Server yang tersambung ke internet mulai menerima paket asing dalam hitungan menit — pemindaian port, percobaan koneksi, dan traffic sampah yang tidak pernah kita minta. Firewall adalah kebijakan yang memutuskan nasib setiap paket itu: diteruskan ke proses, atau dibuang. Di Linux, kebijakan itu dijalankan kerangka netfilter di dalam kernel — program yang kita pakai sehari-hari hanya alat tulis untuk mengisinya. Chapter ini membangun konsepnya bertingkat: chain tempat paket diadili, table yang mengelompokkan aturan, kebijakan bawaan, dan perbedaan stateless versus stateful. Dengan konsep ini kokoh, chapter berikutnya tentang ufw dan firewalld akan terasa sebagai alat ketik, bukan mantra hafalan.
Kebijakan di Dalam Kernel: netfilter #
Netfilter menyediakan titik pemeriksaan (hook) di jalur paket kernel: setiap paket yang masuk, keluar, atau lewat wajib melewati salah satu hook itu, dan di titik itulah aturan kita bisa memutuskan nasibnya. Karena hook berada di dalam kernel, firewall berlaku untuk semua proses tanpa kecuali — tidak ada aplikasi yang bisa memintas. Alat baris perintah seperti iptables, nft, ufw, dan firewalld tidak memfilter paket sendiri; alat-alat itu hanya menuliskan aturan ke struktur data yang dibaca hook.
Tiga Chain Utama: INPUT, OUTPUT, FORWARD #
Aturan-aturan kita disusun berkelompok dalam chain — nama untuk daftar aturan yang dilewati paket dengan posisi tertentu. Tiga chain yang paling sering kita sentuh pada mesin tunggal:
| Chain | Paket seperti apa yang diadili | Contoh nyata |
|---|---|---|
| INPUT | menuju proses di mesin kita sendiri | koneksi SSH masuk ke sshd |
| OUTPUT | keluar dari proses di mesin kita | query DNS yang dikirim resolver |
| FORWARD | hanya lewat, diteruskan ke interface lain | paket client yang melewati gateway |
Peta alurnya ringkas — setiap paket selalu masuk ke salah satu dari tiga jalur ini, tidak ada jalur keempat:
paket dari jaringan ──► [ INPUT ] ──► proses lokal di mesin ini
proses lokal ──► [ OUTPUT ] ──► kembali ke jaringan
paket transit ──► [ FORWARD ] ──► interface jaringan berikutnyaSebuah paket hanya melewati satu dari ketiga chain itu: paket SSH masuk diadili di INPUT, jawabannya diadili di OUTPUT, dan paket yang dirutekan melewati mesin diadili di FORWARD. Server biasa hampir seluruh aturannya di INPUT; FORWARD justru penting pada mesin yang berbagi koneksi.
Kebijakan Bawaan: ACCEPT atau DROP #
Setiap chain punya keputusan cadangan bernama policy — keputusan yang dijatuhkan bila tidak ada satu pun aturan yang cocok dengan paket. Dua filosofi mengisinya. Kebijakan ACCEPT berarti semua diterima kecuali yang disebut ditolak: nyaman bagi desktop, tapi satu celah yang lupa kita tutup langsung terbuka. Kebijakan DROP membalik logikanya menjadi default-deny: semua dibuang kecuali yang eksplisit dizinkan — satu pintu besi yang hanya terbuka untuk daftar yang kita tulis sendiri. Simulasi kecil memperlihatkan cara kerja daftar izin itu:
printf 'ACCEPT tcp 22\nACCEPT tcp 80\n' > aturan-packet-filter
printf 'tcp 22\ntcp 443\nudp 53\n' | while read -r proto port; do
if grep -q "^ACCEPT $proto $port$" aturan-packet-filter; then
printf 'paket %s/%s: ACCEPT\n' "$proto" "$port"
else
printf 'paket %s/%s: DROP\n' "$proto" "$port"
fi
doneOutput yang Dihasilkan:
paket tcp/22: ACCEPT
paket tcp/443: DROP
paket udp/53: DROPMari kita bedah simulasi di atas:
- Baris 1 (
printf ... > aturan-packet-filter): menulis daftar izin: hanya SSH di 22 dan HTTP di 80. Daftar ini tidak memuat aturan tolak sama sekali — penolakan adalah keadaan bawaan. - Baris 2 (
printf ... | while read -r proto port): mengirim tiga “paket” ke simulasi, satu per baris, lalu membacanya satu per satu sebagai pasangan protokol dan port. - Baris 3 (
grep -q "^ACCEPT $proto $port$" ...): memeriksa apakah paket tercantum di daftar izin. Opsi-qmembuatgrepdiam — hanya kode keluarnya yang dipakaiif. - Baris 4 dan 6 (
printf 'paket ... ACCEPT/DROP'): keputusan dicetak. Paket SSH (22) dan HTTP (80) lolos, sedangkan HTTPS (443) dan DNS (53) dibuang — bukan karena ada aturan menolaknya, tetapi karena tidak ada aturan yang menerimanya.
Pada firewall sungguhan, wujud kebijakan bawaan itu terbaca langsung dari tampilan aturan. Berikut contoh tampilan iptables -L -n pada server dengan kebijakan default-deny — perhatikan tanda kurung di tiap judul chain:
Chain INPUT (policy DROP)
target prot opt in out source destination
ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy DROP)
target prot opt in out source destination
Chain OUTPUT (policy ACCEPT)
target prot opt in out source destinationDi contoh itu INPUT hanya meloloskan loopback, SSH, dan HTTP, sementara OUTPUT dibiarkan menerima — server perlu bebas menghubungi dunia, dan balasannya diurus oleh konsep berikutnya.
Stateless dan Stateful: Firewall yang Mengingat #
Firewall paling sederhana mengadili setiap paket sendiri-sendiri: dari mana, ke port mana, protokol apa — lalu putuskan. Model ini disebut stateless, dan masalahnya praktis: bila kita mengizinkan koneksi keluar ke web server jauh, balasannya datang sebagai paket masuk yang harus diterima — padahal INPUT kita default-deny.
Jawaban Linux adalah connection tracking (conntrack): kernel mencatat setiap koneksi yang pernah lewat beserta statusnya, dan aturan bisa bertanya pada catatan itu. Dua status yang paling penting: ESTABLISHED untuk paket milik koneksi yang sudah tercatat sah, dan NEW untuk paket pembuka koneksi. Dengan satu aturan “terima paket ESTABLISHED” pada INPUT, balasan dari koneksi yang kita mulai sendiri lolos otomatis — tanpa membuka pintu bagi koneksi yang memulai sendiri dari luar. Inilah yang membuat kebijakan default-deny bisa hidup damai dengan aktivitas keluar yang bebas; firewall modern, termasuk kedua alat pada chapter berikutnya, stateful secara bawaan.
Table filter, nat, dan mangle #
Sebelum sampai ke chain, paket melewati table — kelompok besar aturan menurut tugasnya. Table filter adalah rumah aturan izin-tolak yang kita bahas sejauh ini. Table nat menangani penulisan ulang alamat, seperti masquerade saat Linux kita berbagi koneksi internet ke client di belakangnya. Table mangle memodifikasi sisi teknis paket, misalnya menandai paket (mark) agar dibedakan oleh traffic shaper. Sehari-hari kita hampir selalu bekerja di filter; dua lainnya hadir saat kita membangun router atau mengatur kualitas layanan.
Alamat yang Didengarkan Menentukan Pintu #
Sebelum firewall bicara, aplikasi sudah menentukan sesuatu yang lebih mendasar: di alamat mana ia mendengarkan. Aplikasi yang mengikat 127.0.0.1 hanya terjangkau dari dalam mesin, sedangkan 0.0.0.0 mendengarkan di semua interface. Kita buktikan keduanya berdampingan:
python3 -m http.server 8792 --bind 127.0.0.1 >/dev/null 2>&1 &
lokal=$!
python3 -m http.server 8793 --bind 0.0.0.0 >/dev/null 2>&1 &
terbuka=$!
for i in 1 2 3 4 5; do
curl -s -o /dev/null 127.0.0.1:8792/ && curl -s -o /dev/null 127.0.0.1:8793/ && break
sleep 0.2
done
ss -tln '( sport = :8792 or sport = :8793 )'
kill "$lokal" "$terbuka"
sleep 0.2Output yang Dihasilkan:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 5 127.0.0.1:8792 0.0.0.0:*
LISTEN 0 5 0.0.0.0:8793 0.0.0.0:* Mari kita bedah blok di atas:
- Baris 1 dan 3: dua server HTTP identik dijalankan di background — hanya
--bindyang berbeda. PID keduanya disimpan agar bisa dimatikan bersih. - Baris 5-8 (
for i in ...): menunggu kedua server siap dengan mencoba mengambil halamannya berulang kali sampaibreak. - Baris 9 (
ss -tln '( sport = :8792 or sport = :8793 )'): mendaftar socket yang mendengarkan, difilter langsung olehsspada dua port itu agar keluarannya pasti dua baris. Bedanya di kolom alamat:127.0.0.1:8792hanya dijangkau dari dalam mesin, sedangkan0.0.0.0:8793menunggu koneksi dari interface mana pun — paket dari luar hanya untuk yang kedua, dan hanya dia yang bergantung pada aturan INPUT. - Baris 10-11: kedua server dimatikan, lalu jeda sebentar memastikan port benar-benar lepas.
Pilihan alamat mendengarkan adalah lapisan pertama, firewall lapisan kedua. Anatomi interface dan alamatnya dibahas pada Chapter Network Interfaces .
Membaca Paket yang Ditolak #
Keputusan DROP membuang paket secara diam-diam — penyerang tidak menerima kabar bahwa paketnya ditolak, dan itu memang nilai keamanannya. Untuk kita sendiri, netfilter menyediakan target LOG: paket yang cocok dicatat dulu ke log kernel (terbaca lewat dmesg atau journalctl -k) sebelum aturan berikutnya memutuskan nasibnya. Praktik yang sehat memasang LOG tepat sebelum DROP dengan pembatasan laju seperti -m limit --limit 5/min, agar banjir paket tidak ikut membanjiri log. Barisnya memuat waktu, interface, alamat asal, dan port tujuan — bahan untuk menimbang ulang daftar izin.
Kini seluruh kosakata sudah ada: chain sebagai ruang sidang, policy sebagai putusan cadangan, table sebagai pembagian tugas, dan connection tracking sebagai ingatan. Yang tersisa adalah memilih alat tulisnya — Chapter berikutnya memperkenalkan dua yang paling populer: ufw di keluarga Ubuntu dan Debian, firewalld di keluarga Red Hat.
Referensi lanjut: situs netfilter untuk dokumentasi arsitektur, iptables(8) untuk referensi alat klasiknya, serta wiki Arch Linux tentang iptables untuk contoh aturan dan pola umum.