Web service di Linux ARM memerlukan kontrol keamanan yang sama ketatnya dengan server x86: permukaan serangan tetap ditentukan oleh port yang terbuka, hak akses proses, autentikasi, secret, dependensi, dan cara aplikasi menangani input. Perbedaan ARM lebih sering muncul pada pilihan perangkat, ketersediaan paket, driver, kapasitas sumber daya, dan dukungan arsitektur—bukan pada prinsip dasar security engineering.
Perkembangan Linux 7.1 dalam ekosistem Asahi Linux dapat menjadi konteks yang relevan bagi pengembang yang menjalankan service pada perangkat Apple Silicon. Namun, dukungan kernel atau hardware tidak otomatis mengamankan aplikasi. Hardening web service di Linux ARM tetap harus dimulai dari threat model, least privilege, autentikasi yang benar, pengelolaan secret, pembatasan resource, dan observabilitas.
1. Mulai dari threat model
Sebelum mengubah konfigurasi, tentukan apa yang ingin dilindungi dan siapa lawannya. Untuk web service yang berjalan pada perangkat ARM di jaringan rumah, kantor, cloud, atau lab, threat model minimal biasanya mencakup:
- Penyerang dari internet: melakukan credential stuffing, brute force, eksploitasi endpoint, pemindaian port, dan penyalahgunaan upload.
- Klien yang sudah terautentikasi: mencoba mengakses resource milik pengguna lain, mengirim payload berukuran besar, atau menyalahgunakan fitur mahal seperti pencarian dan ekspor.
- Proses atau dependensi yang disusupi: berusaha membaca environment, file konfigurasi, socket, atau credential dari host.
- Pengguna lokal dengan akses terbatas: mencoba membaca file service, log, temporary file, atau memanfaatkan permission yang terlalu longgar.
- Kegagalan operasional: secret masuk ke repository, backup, log, crash dump, atau command history.
Tentukan juga batas kepercayaan. Reverse proxy, web service, database, object storage, dan secret manager sebaiknya diperlakukan sebagai komponen berbeda. Jangan menganggap header dari proxy aman sebelum koneksi proxy ke aplikasi dibatasi dan konfigurasi trusted proxy ditetapkan secara eksplisit.
Kontrol yang perlu diprioritaskan
- Expose hanya port dan interface yang diperlukan.
- Jalankan proses dengan user non-root dan filesystem yang terbatas.
- Gunakan autentikasi dengan password hashing yang sesuai dan session cookie yang aman.
- Simpan secret di luar source code dan cegah kebocoran melalui log.
- Validasi input, batasi ukuran dan tipe upload, serta beri rate limit pada endpoint mahal.
- Uji kontrol tersebut di staging sebelum mengandalkan konfigurasi produksi.
2. Hardening host, SSH, dan systemd
SSH: kurangi permukaan akses administratif
Gunakan akun administrator biasa dengan sudo, bukan login langsung sebagai root. Autentikasi berbasis kunci lebih mudah dikontrol dan diaudit daripada password, tetapi private key tetap harus dilindungi dengan passphrase dan permission yang benar.
# /etc/ssh/sshd_config.d/hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AllowGroups webadmin
X11Forwarding no
AllowAgentForwarding no
Nama opsi dapat berbeda berdasarkan implementasi SSH yang digunakan, sehingga validasikan konfigurasi sebelum reload. Contoh pemeriksaan yang umum:
sudo sshd -t
sudo systemctl reload sshd
sudo ss -lntup
Jangan menonaktifkan password authentication sebelum memastikan akses key-based berfungsi melalui sesi SSH kedua. Batasi SSH dengan firewall, VPN, bastion host, atau allowlist jaringan bila kebutuhan operasional memungkinkan. Jika menggunakan AllowUsers atau AllowGroups, pastikan akun pemulihan dan prosedur break-glass tetap tersedia.
Jalankan service sebagai user khusus
Buat user sistem tanpa shell login untuk web service. Pisahkan direktori aplikasi, data yang dapat ditulis, dan file secret. Hindari memberikan akses tulis ke seluruh direktori aplikasi karena kompromi aplikasi dapat berubah menjadi modifikasi kode atau persistence.
[Unit]
Description=Example web service
After=network-online.target
Wants=network-online.target
[Service]
User=webapp
Group=webapp
WorkingDirectory=/opt/example-app
ExecStart=/opt/example-app/bin/server
Restart=on-failure
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/example-app /var/log/example-app
UMask=027
[Install]
WantedBy=multi-user.target
Opsi sandboxing systemd dapat memecahkan aplikasi yang membutuhkan akses tertentu. Terapkan bertahap di staging, lalu periksa journalctl -u nama-service dan audit log ketika service gagal membaca file atau membuka socket. Tambahkan hanya path dan capability yang memang diperlukan; jangan langsung menghapus semua pembatasan karena aplikasi belum siap.
Jika service harus memakai network family tertentu atau capability Linux tertentu, batasi secara eksplisit setelah dependensinya diketahui. Selain itu, gunakan firewall host, bind aplikasi ke loopback jika hanya reverse proxy yang boleh mengaksesnya, dan pastikan database tidak listen pada interface publik tanpa alasan yang kuat.
3. Autentikasi aplikasi dan session cookie
Password dan login
Simpan password dengan password-hashing algorithm yang dirancang untuk password, bukan SHA-256 biasa. Gunakan library resmi framework atau runtime, atur parameter berdasarkan dokumentasi dan kapasitas server, serta sediakan mekanisme rehash ketika parameter diperbarui. Jangan pernah menyimpan atau mencatat password plaintext.
Endpoint login perlu membedakan kebutuhan keamanan dan pengalaman pengguna. Terapkan rate limit berdasarkan kombinasi IP, identitas akun, dan hasil autentikasi; hanya berdasarkan IP sering tidak cukup karena penyerang dapat berganti alamat atau berbagi NAT. Berikan respons yang tidak mengungkap apakah email atau username terdaftar, misalnya pesan umum seperti “kredensial tidak valid”.
Untuk aplikasi yang memiliki akun bernilai tinggi, pertimbangkan MFA, notifikasi login, recovery flow yang diaudit, dan invalidasi session setelah perubahan password atau perubahan faktor autentikasi.
Session cookie yang aman
Session ID harus acak, tidak bermakna, dan disimpan di server atau session store yang terlindungi. Jangan menaruh password, access token jangka panjang, atau data sensitif langsung di cookie. Setelah login berhasil, lakukan session ID rotation untuk mencegah session fixation.
Set-Cookie: __Host-session=<random-session-id>; Path=/; Secure; HttpOnly; SameSite=Lax
Securememastikan cookie hanya dikirim melalui HTTPS.HttpOnlymengurangi risiko pembacaan cookie oleh JavaScript ketika terjadi XSS.SameSite=Laxsering menjadi pilihan seimbang untuk aplikasi web biasa; kebutuhan cross-site yang sah mungkin memerlukan desain berbeda.- Prefix
__Host-membantu mencegah penggunaan atributDomaindan mewajibkanPath=/pada browser yang mendukungnya.
Cookie bukan pengganti perlindungan CSRF. Untuk request yang mengubah state, gunakan token CSRF atau pola perlindungan yang sesuai arsitektur, periksa origin bila relevan, dan jangan mengandalkan SameSite sebagai satu-satunya kontrol.
4. Secret: environment, file, dan secret manager
Secret seperti session signing key, database password, API key, dan private credential tidak boleh berada di source code, image container, repository, atau pesan error. Environment variable dapat menjadi pilihan praktis untuk deployment sederhana, tetapi bukan tempat yang otomatis aman: secret masih dapat terbaca oleh proses dengan hak tertentu, muncul pada diagnostic dump, atau ikut terbawa ke tooling operasional.
Jika menggunakan file environment, simpan di luar repository, batasi permission, dan pastikan hanya user service yang dapat membacanya.
# contoh permission, sesuaikan path dan user deployment
sudo chown root:webapp /etc/example-app/app.env
sudo chmod 0640 /etc/example-app/app.env
Dalam unit systemd, gunakan mekanisme environment file hanya jika model ancaman dan permission host memadai:
[Service]
EnvironmentFile=/etc/example-app/app.env
Untuk produksi dengan kebutuhan rotasi, audit, dan pemisahan akses yang lebih kuat, gunakan secret manager atau mekanisme injection dari platform deployment. Aplikasi sebaiknya membaca secret saat startup, gagal secara aman jika secret wajib tidak tersedia, dan mendukung rotasi tanpa mencetak nilai lama maupun baru ke log. Hindari menampilkan seluruh environment ketika menangani error atau menjalankan endpoint diagnostik.
5. Validasi input, upload, dan pencegahan abuse
Validasi input di server
Validasi di browser hanya meningkatkan UX; batas keamanan harus ditegakkan di server. Gunakan allowlist untuk enum, panjang string, rentang angka, format tanggal, dan ukuran request. Normalisasi input sebelum validasi jika format memungkinkan beberapa representasi. Gunakan parameterized query atau query builder untuk database, dan lakukan output encoding sesuai konteks HTML, URL, JavaScript, atau SQL.
// Pseudocode portable
userId = parseInteger(request.path("id"))
if userId is invalid or userId < 1:
return 400
payload = parseJson(request.body, maxBytes=64 * 1024)
validateSchema(payload, {
"name": {"type": "string", "maxLength": 100},
"status": {"enum": ["active", "disabled"]}
})
record = database.query("SELECT ... WHERE id = ?", [userId])
Validasi juga harus mencakup otorisasi objek. User yang berhasil login belum tentu boleh membaca id apa pun. Terapkan pemeriksaan ownership atau policy pada setiap resource, bukan hanya pada halaman daftar.
Batasi upload secara berlapis
- Tetapkan batas ukuran request pada reverse proxy dan aplikasi.
- Allowlist tipe file dan validasi berdasarkan isi atau signature, bukan hanya ekstensi dan MIME dari client.
- Gunakan nama file yang dibuat server; jangan memakai nama asli sebagai path.
- Simpan file di luar document root dan nonaktifkan eksekusi dari direktori upload.
- Gunakan direktori sementara dengan quota atau ruang disk yang dipantau.
- Scan file bila risiko dan infrastruktur memungkinkan, tetapi jangan menganggap scanner sebagai satu-satunya kontrol.
- Tolak arsip berbahaya, termasuk archive bomb atau rasio kompresi yang dapat menghabiskan resource.
Perhatikan bahwa validasi gambar, PDF, dan arsip memanggil parser kompleks. Jalankan pemrosesan berat di worker terisolasi dengan timeout, batas memory, dan antrean terbatas. Jangan memproses upload secara sinkron pada request yang dapat dibuka tanpa batas.
Rate limit dan abuse control
Rate limit harus diterapkan pada operasi, bukan hanya seluruh API. Login, reset password, pengiriman email, pencarian kompleks, export, pembuatan resource, dan upload biasanya membutuhkan limit berbeda. Selain jumlah request, batasi concurrency, ukuran body, durasi request, kedalaman pagination, serta biaya query.
Gunakan reverse proxy untuk batas kasar dan aplikasi untuk aturan yang memerlukan identitas akun. Tambahkan quota harian atau mingguan untuk operasi mahal, cooldown setelah kegagalan berulang, dan circuit breaker ketika dependency eksternal bermasalah. CAPTCHA atau challenge tambahan dapat menjadi lapisan kedua, bukan pengganti rate limit.
Di perangkat ARM dengan CPU, storage, atau thermal budget terbatas, abuse terhadap CPU dan disk dapat menyebabkan denial of service meskipun bandwidth kecil. Pantau load, memory pressure, file descriptor, ruang disk, panjang antrean, dan waktu respons dependency.
6. Logging tanpa membocorkan secret
Log yang berguna harus membantu menjawab siapa melakukan apa, kapan, dari mana, dan bagaimana hasilnya—tanpa menyimpan password, token, cookie, authorization header, secret, atau payload sensitif. Gunakan request ID untuk menghubungkan log reverse proxy, aplikasi, dan worker.
{
"event": "auth_failure",
"request_id": "generated-id",
"route": "/login",
"method": "POST",
"actor": null,
"client_ip": "redacted-or-policy-based",
"reason": "invalid_credentials",
"status": 401,
"duration_ms": 42
}
Redaksi IP dan identifier harus mengikuti kebutuhan keamanan serta kebijakan privasi. Hindari logging body request secara default. Jika perlu debugging sementara, gunakan allowlist field, masking, retention pendek, dan persetujuan operasional yang jelas. Lindungi log dari modifikasi, batasi aksesnya, dan siapkan alert untuk pola seperti lonjakan login gagal, banyak akun dari satu sumber, upload berulang, atau response 5xx.
7. Checklist verifikasi sebelum produksi
- Exposure: hanya port yang diperlukan terbuka; aplikasi internal bind ke interface privat atau loopback.
- SSH: root login dan password login dinonaktifkan setelah key-based access teruji; akses dibatasi ke user atau group yang benar.
- Process: service berjalan sebagai user non-root, memiliki filesystem write path minimal, dan tidak memiliki capability yang tidak diperlukan.
- TLS dan cookie: HTTPS diterapkan, cookie memakai
Secure,HttpOnly, dan kebijakanSameSiteyang sesuai. - Auth: password di-hash, session dirotasi setelah login, CSRF dilindungi, dan otorisasi objek diuji.
- Secret: tidak ada secret di Git, image, log, backup yang tidak terlindungi, atau error response; permission secret diverifikasi.
- Input: schema validation, parameterized query, output encoding, dan batas body diterapkan di server.
- Upload: ukuran, tipe, nama, lokasi penyimpanan, parser, timeout, dan quota diuji dengan file valid maupun berbahaya.
- Abuse: rate limit, concurrency limit, quota, timeout, dan pembatasan dependency diuji pada endpoint mahal.
- Observability: request ID, event keamanan, metrik resource, alert, retention, dan redaction log berjalan sesuai kebijakan.
8. Pengujian staging dan batasan keamanan
Staging harus semirip mungkin dengan produksi dalam hal user service, permission, reverse proxy, systemd sandbox, secret injection, dan limit resource. Uji login gagal berulang, session fixation, akses lintas akun, CSRF, payload JSON besar, path traversal, nama file Unicode, upload file yang disamarkan, archive bomb, slow request, dan antrean worker penuh.
Uji juga failure mode: secret manager tidak tersedia, disk hampir penuh, database lambat, scanner upload mati, clock host berubah, dan service restart saat traffic berlangsung. Pastikan aplikasi gagal tertutup—misalnya menolak startup tanpa secret wajib—bukan berjalan dengan default credential atau key yang sama untuk semua instalasi.
Batasan: hardening host dan rate limit tidak memperbaiki kerentanan logika bisnis, bug pada dependency, atau kompromi endpoint administrator. Lakukan dependency scanning, code review, pengujian otorisasi, backup recovery test, dan penetration test sesuai tingkat risiko.
Linux ARM, termasuk lingkungan yang berkembang seperti Asahi Linux, dapat menjadi platform yang baik untuk web service, tetapi kompatibilitas platform tetap perlu diverifikasi: binary dependency, agent monitoring, image container, akselerasi kriptografi, dan tool security mungkin memiliki dukungan berbeda. Catat asumsi arsitektur dalam deployment, uji pada hardware target, dan jangan menyamakan “service berhasil berjalan” dengan “service sudah aman”.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!