Bab 30 menutup dengan janji eksplisit: lapisan kedua defense in depth kita, yaitu firewall, menjadi fokus penuh bab ini. Sepanjang series ini pun kita sebenarnya sudah berulang kali menjalankan sudo ufw allow tanpa pernah membahas dari mana perintah itu berasal atau ke mana sebenarnya ia pergi di dalam kernel. Port SSH kustom di Bab 3, DNS dan DHCP di Bab 9 dan Bab 10, web server serta database di Bagian IV dan V, sampai Samba dan NFS di Bagian VI, semuanya sudah menumpuk rule ufw allow yang menunggu, tetapi UFW sendiri belum pernah benar-benar kita aktifkan secara resmi. Bab ini menuntaskan aktivasi itu, sekaligus menjawab dua janji tertunda: alasan container Docker di Bab 27 ternyata bisa menembus UFW meski portnya belum diizinkan, dan pembahasan mendalam soal application profile yang sempat kita tunda di Bab 24.
Kita akan mulai dari evolusi arsitektur firewall Linux, dari iptables klasik sampai nftables sebagai penerusnya, agar paham posisi UFW di antara keduanya. Setelah itu kita masuk ke konsep dasar iptables yang masih relevan dibaca di banyak script produksi lawas, mengaktifkan UFW secara resmi lengkap dengan rate limiting dan application profile kustom, mencoba sintaks native nftables beserta cara migrasinya, merangkum seluruh aturan firewall untuk service yang sudah kita pasang sepanjang series ini, dan menutup dengan logging serta monitoring firewall sebagai bekal mendeteksi percobaan intrusi sebelum Bab 32 membahas Fail2ban.
31.1 Evolusi Arsitektur Firewall Linux: dari iptables ke nftables
Sebelum menyentuh perintah apa pun, ada baiknya kita paham dulu peta besarnya: alasan Ubuntu Server 26.04 masih mengenal iptables sekaligus nftables, dan cara keduanya berhubungan dengan UFW yang sudah lama kita pakai diam-diam.
31.1.1 Netfilter, iptables, dan Keterbatasannya
Netfilter adalah framework di dalam kernel Linux yang menyediakan titik-titik hook di sepanjang jalur paket jaringan, mulai dari saat paket baru masuk ke network interface sampai saat ia keluar lagi, tempat modul filtering bisa memeriksa dan memutuskan nasib tiap paket. iptables (bersama saudaranya ip6tables untuk IPv6, arptables, dan ebtables) adalah utility userspace klasik yang berbicara ke Netfilter lewat framework lama bernama x_tables. Selama lebih dari dua dekade, iptables menjadi standar de facto firewall Linux, tetapi arsitekturnya menyimpan keterbatasan nyata: satu utility terpisah untuk tiap protocol family, rule dievaluasi satu per satu secara linear dari atas ke bawah tanpa struktur data pencarian cepat bawaan, dan tidak ada mekanisme reload ruleset yang benar-benar atomic, sehingga mengganti banyak rule sekaligus berisiko meninggalkan celah singkat saat proses berlangsung.
31.1.2 nftables sebagai Penerus dan iptables-nft sebagai Jembatan
nftables masuk ke mainline kernel Linux pada versi 3.13 (2014) sebagai penerus resmi Netfilter, dirancang untuk menutup seluruh keterbatasan di atas: satu utility nft untuk semua protocol family lewat konsep table family (ip, ip6, inet untuk dual-stack sekaligus, arp, bridge, netdev), dukungan native untuk set dan map dengan pencarian O(1) alih-alih linear, reload ruleset yang atomic, dan sintaks deklaratif yang jauh lebih mudah dibaca dibanding rangkaian flag pendek ala iptables.
Transisinya di Ubuntu berjalan bertahap. Sejak Ubuntu 16.04 LTS, package iptables sudah menyertakan compatibility wrapper bernama iptables-nft yang menerjemahkan sintaks iptables lama menjadi rule nftables di balik layar. Sejak Ubuntu 20.10, wrapper inilah yang menjadi backend default: menjalankan perintah iptables di Ubuntu Server 26.04 sebenarnya memanggil iptables-nft, dikelola lewat sistem update-alternatives, sementara backend lama masih tersedia sebagai iptables-legacy untuk kasus kompatibilitas modul kernel tertentu. Kedua backend ini menyimpan ruleset yang sama sekali terpisah, jadi mencampur keduanya di server yang sama hanya akan membingungkan diri sendiri saat troubleshooting.
Fakta ini juga menjelaskan posisi UFW secara lebih presisi. UFW memanggil binary iptables/ip6tables untuk menerapkan setiap rule yang kita tulis, dan karena binary tersebut kini adalah iptables-nft, rule UFW pada akhirnya benar-benar tersimpan sebagai struktur data nftables di kernel. Namun UFW sendiri, sampai penulisan series ini, belum memiliki backend native yang berbicara langsung sintaks nft. Jadi kalau ada yang bilang "UFW menghasilkan rule nftables", maksudnya bukan UFW menulis sintaks nft secara langsung, melainkan UFW tetap menulis rule bergaya iptables yang kemudian diterjemahkan otomatis oleh iptables-nft menjadi entri nftables di kernel.
| Aspek | iptables (x_tables / legacy) | nftables |
|---|---|---|
| Utility per protocol family | Terpisah: iptables, ip6tables, arptables, ebtables | Satu utility nft untuk seluruh family |
| Evaluasi rule | Linear, dibaca satu per satu dari atas ke bawah | Mendukung set/map dengan lookup O(1) |
| Reload ruleset | Tidak atomic secara native | Atomic lewat nft -f |
| Gaya sintaks | Prosedural, banyak flag pendek | Deklaratif, mendekati struktur blok |
Langkah Praktik
- Periksa backend
iptablesyang sedang aktif di server kita.iptables -V - Lihat symlink alternatives yang menentukan pilihan backend tersebut.
sudo update-alternatives --display iptables
Verifikasi dan Troubleshooting
- Output
iptables -Vpada Ubuntu Server 26.04 mengandung keterangan(nf_tables), menandakan backend aktifnya memangiptables-nft, bukaniptables-legacy. - Jika output justru menampilkan
(legacy), server kemungkinan pernah diarahkan manual ke backend lama lewatupdate-alternatives --config iptables, entah oleh instalasi software pihak ketiga yang mensyaratkannya atau kesalahan konfigurasi sebelumnya. Kembalikan ke opsi yang mengarah keiptables-nftkecuali memang ada alasan kuat mempertahankan backend legacy.
31.2 iptables: Konsep Dasar dan Kasus Nyata di Balik Docker
Meski Ubuntu 26.04 sudah memakai nftables di balik layar, sintaks iptables tetap layak dikuasai karena tiga alasan konkret: masih dipakai luas di script automation lawas seperti playbook Ansible atau image vendor lama, menjadi bahasa yang dipakai UFW seperti baru saja kita bahas, dan dipakai langsung oleh Docker untuk memanipulasi firewall tanpa sepengetahuan UFW, kasus nyata yang menjadi fokus bagian ini.
31.2.1 Anatomi Table, Chain, dan Rule
iptables mengorganisasi rule ke dalam table, tiap table berisi kumpulan chain, dan tiap chain berisi daftar rule. Table default bernama filter berisi tiga chain bawaan: INPUT untuk paket yang ditujukan ke host ini sendiri, OUTPUT untuk paket yang keluar dari host ini, dan FORWARD untuk paket yang hanya lewat atau di-routing melalui host ini, chain yang nanti relevan langsung dengan kasus Docker di Bagian 31.2.3. Tiap chain punya default policy (ACCEPT, DROP, atau REJECT) yang berlaku kalau tidak ada rule yang cocok, dan daftar rule di dalamnya dievaluasi berurutan dari atas ke bawah sampai ditemukan rule pertama yang cocok (first-match-wins). Satu rule sendiri terdiri dari kriteria pencocokan, misalnya -p untuk protokol, --dport untuk port tujuan, -s untuk source IP, digabung dengan target lewat flag -j seperti ACCEPT, DROP, REJECT, atau LOG. Table filter bukan satu-satunya table yang dikenal iptables. Table nat, dengan chain PREROUTING dan POSTROUTING, khusus menangani penerjemahan alamat seperti port forwarding, dan justru table inilah yang dipakai Docker untuk mem-publish port container, bukan table filter tempat UFW bekerja, seperti akan kita lihat langsung di Bagian 31.2.3.
31.2.2 Membaca dan Menguji Rule Secara Langsung
Praktik paling aman untuk mulai mengenal iptables adalah membaca dulu ruleset yang sudah berjalan, baru mencoba menambah dan menghapus rule latihan yang tidak mengganggu apa pun.
Langkah Praktik
- Lihat seluruh rule aktif di chain table
filterbeserta counter paket yang sudah cocok dengan tiap rule.sudo iptables -L -n -v --line-numbers - Tambahkan rule latihan, misalnya mengizinkan port 8443/tcp.
sudo iptables -A INPUT -p tcp --dport 8443 -j ACCEPT - Hapus lagi rule latihan tadi. Jalankan ulang perintah pada langkah pertama untuk melihat di baris berapa rule baru ini berada, karena
-Aselalu menambahkan rule di posisi paling akhir chain, lalu hapus berdasarkan nomor tersebut.sudo iptables -D INPUT 5
Verifikasi dan Troubleshooting
- Rule yang ditambahkan lewat
-Ahanya hidup di memori kernel dan hilang setelah reboot berikutnya, berbeda dari rule UFW yang tersimpan permanen di/etc/ufw/user.rulesseperti akan kita bahas di Bagian 31.3.1. Untuk ruleiptablesmentah yang perlu bertahan lewat reboot, packageiptables-persistentmenyediakan servicenetfilter-persistentyang menyimpan ruleset ke/etc/iptables/rules.v4danrules.v6. - Hindari menambahkan rule manual untuk port yang sama yang juga dikelola UFW di server yang sama. Dua mekanisme yang mengatur port identik dari sumber berbeda hanya akan membingungkan diagnosis saat terjadi masalah akses di kemudian hari.
31.2.3 Studi Kasus: DOCKER-USER Chain dan Alasan Container Bisa Menembus UFW
Bagian 27.2.3 sempat memberi peringatan singkat, jika UFW aktif, port stack Docker Compose perlu diizinkan lebih dulu. Kenyataannya sedikit lebih rumit, dan justru di situlah pemahaman iptables tadi berguna. Saat container mem-publish port lewat opsi -p pada docker run atau lewat blok ports: pada docker-compose.yml, Docker Engine membuat rule NAT di chain PREROUTING pada table nat yang mengarahkan paket masuk ke IP internal container, lalu paket tersebut diteruskan lewat chain FORWARD, bukan chain INPUT tempat seluruh rule UFW berada. Docker juga membuat dua chain kustom bernama DOCKER dan DOCKER-USER, lalu menyisipkan jump ke keduanya di posisi paling awal chain FORWARD, sehingga paket menuju container dievaluasi chain-chain milik Docker ini jauh sebelum UFW punya kesempatan bicara. Akibatnya, container yang mem-publish port tetap bisa diakses dari luar meski UFW belum pernah mengizinkan port tersebut, karena secara teknis lalu lintasnya memang tidak pernah lewat jalur yang dijaga UFW.
Docker sendiri secara resmi menyediakan chain DOCKER-USER justru untuk kasus ini. Docker sengaja tidak pernah mengisi chain ini secara otomatis, sehingga aman dipakai Sysadmin untuk menyisipkan rule kontrol akses tambahan, dan rule tersebut tetap bertahan setiap kali Docker daemon di-restart.
Langkah Praktik
- Pastikan dulu chain ini memang ada, artinya Docker Engine sudah pernah berjalan di server ini seperti pada Bab 26 dan Bab 27.
sudo iptables -L DOCKER-USER -n -v - Batasi akses ke seluruh container yang mem-publish port hanya dari subnet tepercaya, misalnya subnet kantor
192.168.1.0/24yang sudah kita pakai konsisten sejak Bab 11. Urutan tiga perintah berikut penting karena-Imenyisipkan rule di posisi teratas, sehingga perintah yang dijalankan paling akhir justru berakhir paling atas. RuleESTABLISHED,RELATEDsengaja dieksekusi paling akhir supaya berakhir di baris pertama, karena chainFORWARDtempatDOCKER-USERberada juga dilewati trafik balik dari koneksi yang diinisiasi container itu sendiri ke internet, misalnya saat container menjalankanapt-get updatedi dalamnya. Tanpa rule ini, blokir di bawahnya ikut memutus akses keluar container, bukan cuma akses masuk yang ingin kita batasi.sudo iptables -I DOCKER-USER -j DROP sudo iptables -I DOCKER-USER -s 192.168.1.0/24 -j ACCEPT sudo iptables -I DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - Verifikasi urutannya benar-benar sesuai rencana.
sudo iptables -L DOCKER-USER -n -v --line-numbers
Verifikasi dan Troubleshooting
- Rule
ACCEPTuntuk trafikESTABLISHED,RELATEDharus berada di baris nomor 1, ruleACCEPTdari subnet tepercaya di baris nomor 2, dan ruleDROPdi baris nomor 3. Jika urutannya berantakan, baik akses masuk dari subnet tepercaya maupun akses keluar container ke internet bisa ikut ter-drop, karena rule pertama yang cocok yang menang. - Rule di
DOCKER-USERini bertahan lewat restart Docker daemon karena memang begitu desainnya, tetapi tidak otomatis bertahan lewat reboot host kecuali dipersistenkan lewatiptables-persistentseperti dibahas di Bagian 31.2.2, atau ditulis ulang lewat automation yang berjalan saat boot. - Catatan jujur soal batasannya: solusi ini bekerja di level
iptables/nftablesmentah, sepenuhnya di luar jangkauan UFW. Sampai penulisan series ini, UFW belum menyediakan cara native mengelola chainDOCKER-USER, sehingga kombinasi Docker dan UFW selalu butuh langkah tambahan manual seperti di atas, bukan sekadar mengandalkanufw allowpada port yang dipublish container.
31.3 UFW: Cara Kerja di Balik Layar dan Kontrol Lanjutan
Setelah memahami iptables mentah, sekarang kita kembali ke UFW, tool yang sebenarnya sudah kita pakai diam-diam sejak Bab 3, tetapi kali ini sampai ke detail cara kerjanya dan fitur-fitur lanjutan yang belum pernah kita sentuh.
31.3.1 UFW sebagai Generator Rule dan Aktivasi Resmi
UFW (Uncomplicated Firewall) adalah frontend berbasis Python yang menyederhanakan sintaks iptables/nftables menjadi perintah singkat, dikembangkan khusus untuk Ubuntu agar konfigurasi firewall sehari-hari tidak perlu menghafal flag iptables satu per satu. Setiap kali kita menjalankan ufw allow atau ufw deny, UFW menulis baris baru ke file rule di /etc/ufw/user.rules (dan user6.rules untuk IPv6), terlepas dari status UFW sendiri sedang aktif atau tidak. Itulah sebabnya seluruh rule yang sudah kita tambahkan sejak Bab 3 tetap tersimpan menunggu, meski kita belum pernah benar-benar menjalankan ufw enable. Begitu diaktifkan, UFW memuat seluruh file rule tersebut lewat iptables-restore, membentuk deretan chain miliknya sendiri seperti ufw-before-input, ufw-user-input, dan ufw-after-input, yang disisipkan ke dalam chain bawaan INPUT/OUTPUT/FORWARD.
Langkah Praktik
- Sebelum mengaktifkan apa pun, lihat dulu seluruh rule yang sudah menumpuk sejak Bab 3. Perintah
ufw statusbiasa sengaja tidak menampilkan apa-apa selain katainactivesaat UFW belum aktif, jadi gunakanshow addedyang tetap membaca rule dari file konfigurasi.sudo ufw show added - Pastikan rule untuk port SSH kustom dari Bagian 3.2.4 benar-benar ada di daftar tersebut sebelum melangkah lebih jauh. Kehilangan akses SSH akibat firewall yang salah konfigurasi adalah salah satu insiden paling umum yang dialami Sysadmin, sekaligus paling mudah dicegah.
- Aktifkan UFW secara resmi.
Perintah ini menampilkan konfirmasisudo ufw enableCommand may disrupt existing ssh connections. Proceed with operation (y|n)?. Ketikyhanya setelah yakin rule SSH sudah ada di langkah sebelumnya. - Verifikasi status lengkap beserta default policy-nya.
sudo ufw status verbose
Verifikasi dan Troubleshooting
- Output
ufw status verboseyang sehat menampilkanStatus: active, diikutiDefault: deny (incoming), allow (outgoing), disabled (routed), lalu daftar rule yang sudah menumpuk sejak bab-bab sebelumnya. - Buktikan sendiri bahwa rule UFW benar-benar terjelma sebagai rule
iptablesnyata di kernel, bukan sekadar konfigurasi di atas kertas.sudo iptables -L ufw-user-input -n -v - Jika sesi SSH ternyata terputus tepat setelah mengaktifkan UFW, jangan panik. Sesi lama yang sudah terhubung biasanya tidak langsung terputus paksa oleh perubahan rule, tetapi sesi baru bisa gagal masuk jika rule SSH ternyata salah port atau salah sintaks. Console akses dari Bagian 3.4 tetap menjadi jalur darurat untuk situasi ini.
31.3.2 Rate Limiting dan Manajemen Rule Bernomor
Rule allow biasa tidak membatasi seberapa sering satu source IP mencoba konek. Attacker yang menjalankan brute force SSH otomatis bisa mencoba ratusan kombinasi username dan password dalam hitungan menit tanpa ada yang menghalangi, sampai Bab 32 nanti memperkenalkan Fail2ban sebagai solusi berbasis deteksi log. Sebagai lini pertama yang jauh lebih ringan, UFW sudah menyediakan mekanisme rate limiting bawaan.
Langkah Praktik
- Terapkan rate limiting ke port SSH kustom kita. Perhatikan bahwa alias siap pakai
ufw limit sshatau profileOpenSSHtetap menunjuk ke port 22 baku, bukan port 2222 hasil kustomisasi kita di Bagian 3.2.4, jadi kita harus menyebut port-nya secara eksplisit.sudo ufw limit 2222/tcp - Lihat seluruh rule beserta nomor urutnya.
sudo ufw status numbered - Hapus satu rule berdasarkan nomornya, ganti angka berikut sesuai nomor yang benar-benar tampil di langkah sebelumnya.
sudo ufw delete 3 - Sisipkan rule baru di posisi tertentu, misalnya memblokir subnet dokumentasi
203.0.113.0/24di posisi paling atas sebelum rule allow lain sempat dievaluasi.sudo ufw insert 1 deny from 203.0.113.0/24 to any port 2222 proto tcp comment 'contoh blokir subnet mencurigakan'
Verifikasi dan Troubleshooting
- Rule
limitUFW bekerja dengan menolak koneksi baru dari satu source IP begitu source tersebut mencoba enam kali koneksi atau lebih dalam rentang 30 detik, angka yang tidak bisa dikustomisasi lewat UFW sendiri. Threshold ini cukup longgar untuk user sah yang sesekali salah ketik password, tapi cukup ketat untuk memperlambat drastis serangan brute force otomatis. - Nomor rule bisa bergeser setiap kali ada rule yang dihapus atau disisipkan. Selalu jalankan
ufw status numberedulang sebelum mengeksekusi perintahdeleteatauinsertberikutnya, jangan mengandalkan nomor dari hasil pengecekan yang sudah beberapa perintah lalu.
31.3.3 Application Profile: Membaca Profile Bawaan dan Menulis Profile Sendiri
Bagian 24.3 sempat menunda pembahasan mendalam soal application profile UFW saat memilih membuka port Samba secara manual. Sekarang saatnya menuntaskan hal tersebut, sekaligus membuat profile sendiri untuk stack Docker Compose dari Bab 27.
Langkah Praktik
- Lihat seluruh profile yang sudah terdaftar di server ini, hasil instalasi berbagai service sepanjang series.
sudo ufw app list - Intip detail profile
Sambayang sengaja kita hindari di Bagian 24.3.
Output menampilkansudo ufw app info SambaPorts: 137,138/udp|139,445/tcp. Inilah alasan teknis Bagian 24.3 memilihufw allow 445/tcpmanual, bukanufw allow Samba: profile bawaan ini tetap membuka port 137, 138, dan 139 untuk NetBIOS, padahal NetBIOS di server kita sudah sengaja dimatikan pada bagian yang sama. Memakai profile bawaan di situ justru membuka kembali port yang sudah tidak dipakai proses apa pun. - Buat profile baru untuk stack Docker Compose dari Bagian 27.2, yang memakai port 8090 untuk situs statis dan 8091 untuk Adminer.
Isi file dengan format berikut.sudo nano /etc/ufw/applications.d/notes-compose[NotesCompose] title=Notes Compose Stack description=Situs statis dan Adminer dari stack Docker Compose Bab 27 ports=8090,8091/tcp - Daftarkan profile baru ke UFW lalu terapkan.
sudo ufw app update NotesCompose sudo ufw allow NotesCompose
Verifikasi dan Troubleshooting
- Konfirmasikan profile baru terbaca dengan benar.
sudo ufw app info NotesCompose - Catatan jujur yang justru penting: rule
allowdi atas mengontrol chainINPUTmilik UFW, sedangkan berdasarkan Bagian 31.2.3, container yang mem-publish port lewatports:pada Compose melewati jalurFORWARDdan chainDOCKER-USER, bukanINPUT. Artinya, untuk stack Compose Bab 27 secara spesifik, container tersebut sebenarnya sudah bisa diakses dari luar sejak awal, terlepas dari ada atau tidaknya ruleallow NotesComposeini. Profile tetap berguna sebagai dokumentasi port yang dipakai dan akan benar-benar berpengaruh jika kelak port yang sama dipakai proses non-container yang listen langsung di host. Untuk kontrol akses yang benar-benar berlaku ke container Compose ber-publish-port, kembali ke pendekatanDOCKER-USERpada Bagian 31.2.3.
31.4 nftables Native: Sintaks Modern dan Migrasi dari iptables
UFW sudah cukup untuk mayoritas kebutuhan sehari-hari sepanjang series ini, tapi ada kalanya Sysadmin butuh kontrol lebih granular yang tidak disediakan UFW, misalnya named set berisi puluhan IP yang sering berubah, atau rule berbasis kondisi yang tak tercakup sintaks UFW. Di titik itulah nftables native, penerus resmi yang sudah kita bahas di Bagian 31.1.2, menjadi pilihan.
Karena UFW dan rule nftables native sama-sama memakai hook Netfilter yang sama persis di kernel, menjalankan keduanya sekaligus sebagai firewall utama berpotensi membingungkan bahkan saling bentrok. Bagian praktik berikut oleh karena itu kita perlakukan sebagai lab tersendiri: nonaktifkan dulu UFW sementara, baru aktifkan lagi setelah selesai bereksperimen, supaya server kita tetap punya satu sumber kebenaran firewall yang jelas.
31.4.1 Instalasi dan Anatomi Ruleset: Table, Chain, Rule
Langkah Praktik
- Nonaktifkan sementara UFW supaya tidak bentrok dengan eksperimen berikut.
sudo ufw disable - Pasang package
nftablesjika belum terpasang. Kernel dan compatibility layer-nya kemungkinan besar sudah aktif lewatiptables-nft, tetapi utilitynftdan systemd unit-nya tetap butuh package eksplisit.sudo apt install nftables - Buat table dan chain
inputdengan default policydrop. Familyinetsengaja dipilih karena otomatis mencakup IPv4 dan IPv6 sekaligus dalam satu rule, berbeda dariiptablesyang mewajibkanip6tablesterpisah untuk IPv6. Angkapriority 0menentukan urutan eksekusi chain ini relatif terhadap chain lain yang mungkin hook di titikinputyang sama, misalnya miliknftables.servicelain atau Docker; nilai lebih kecil dieksekusi lebih dulu, dan 0 adalah nilai konvensional untuk chain filtering utama.sudo nft add table inet filter sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; } - Tambahkan rule dasar: loopback, koneksi yang sudah established atau related, lalu SSH di port kustom kita.
sudo nft add rule inet filter input iif lo accept sudo nft add rule inet filter input ct state established,related accept sudo nft add rule inet filter input tcp dport 2222 accept
Verifikasi dan Troubleshooting
- Lihat ruleset lengkap yang baru dibuat.
sudo nft list ruleset - Urutan rule dalam base chain tetap dievaluasi dari atas ke bawah persis seperti
iptables. Rule loopback dan established/related sengaja diletakkan di atas supaya trafik yang paling sering muncul tidak perlu dicocokkan lawan seluruh rule di bawahnya, optimasi kecil yang terasa nyata di server dengan trafik tinggi.
31.4.2 Ruleset Persisten di /etc/nftables.conf
Rule yang baru kita tambahkan lewat nft add hanya hidup di memori kernel dan hilang setelah reboot, persis seperti iptables mentah di Bagian 31.2.2. nftables punya cara yang lebih rapi: mendefinisikan seluruh ruleset dalam satu file deklaratif di /etc/nftables.conf, yang dimuat otomatis oleh systemd unit nftables.service saat boot.
Langkah Praktik
- Tulis ulang rule di atas sebagai file deklaratif.
Isi filenya sebagai berikut.sudo nano /etc/nftables.conf
Baris#!/usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority 0; policy drop; iif lo accept ct state established,related accept tcp dport 2222 accept ct state invalid drop } }flush rulesetdi awal penting supaya setiap kali file ini dimuat ulang, ruleset lama benar-benar bersih lebih dulu, mencegah rule ganda menumpuk di kernel. Satu baris baru turut ditambahkan di sini,ct state invalid drop, yang tidak ada di rule uji coba sebelumnya: baris ini membuang paket yang oleh connection tracking kernel sudah ditandai tidak valid, misalnya potongan paket TCP yang datang di luar urutan koneksi mana pun. Paket semacam ini nyaris selalu berasal dari percobaan port scanning atau paket rusak di jaringan, bukan trafik sah, sehingga aman dibuang lebih awal sebelum sempat dicocokkan ke rule di bawahnya. - Muat file tersebut, lalu aktifkan sebagai service yang berjalan otomatis saat boot.
sudo nft -f /etc/nftables.conf sudo systemctl enable --now nftables.service
Verifikasi dan Troubleshooting
- Pastikan service berjalan dan ruleset di kernel cocok dengan isi file.
sudo systemctl status nftables.service sudo nft list ruleset - Jika ada kesalahan sintaks,
nft -fmenolak memuat file dan menampilkan baris bermasalah lengkap dengan nomor barisnya, jauh lebih informatif dibanding pesan erroriptableslama yang sering hanya berbunyi singkat tanpa konteks. - Setelah selesai bereksperimen, kembalikan server ke kondisi semula: matikan
nftables.service, bersihkan ruleset-nya, lalu nyalakan lagi UFW sebagai satu-satunya firewall aktif.sudo systemctl disable --now nftables.service sudo nft flush ruleset sudo ufw enable
31.4.3 Migrasi Rule Lama dengan iptables-translate
Skenario yang sering ditemui di lapangan: Sysadmin mewarisi server dengan banyak rule iptables mentah peninggalan orang sebelumnya, dan sedang mempertimbangkan migrasi penuh ke nftables. Menulis ulang seluruh rule secara manual rawan salah dan memakan waktu. Package nftables menyertakan tool iptables-translate yang menerjemahkan satu rule iptables ke sintaks nft setara, tanpa perlu menghafal ulang seluruh pemetaan flag secara manual.
Langkah Praktik
- Terjemahkan satu rule contoh untuk melihat pola konversinya.
Perintah ini mencetak barisiptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPTnftsetara, kurang lebih berbentuknft add rule ip filter INPUT tcp dport 22 ct state new counter accept, siap dijalankan langsung atau ditempel ke file konfigurasi. - Untuk migrasi ruleset penuh yang sudah tersimpan lewat
iptables-save, gunakan varian restore-nya supaya seluruh file diterjemahkan sekaligus.sudo iptables-save > /root/rules-lama.v4 sudo iptables-restore-translate -f /root/rules-lama.v4
Verifikasi dan Troubleshooting
- Hasil terjemahan tetap perlu dibaca ulang manual sebelum dipakai di server production, terutama untuk rule kompleks yang memanfaatkan modul
iptablestanpa padanan langsung dinft. Tool ini mempercepat proses migrasi, bukan menggantikan review manual sepenuhnya.
31.5 Aturan Firewall untuk Service Umum: Konsolidasi Series Ini
Setelah memahami cara kerja di baliknya, bagian ini merangkum seluruh rule firewall yang sudah kita terapkan sejak Bab 3, sengaja disusun sebagai satu referensi ringkas yang bisa dibaca berdiri sendiri tanpa perlu membuka ulang tiap bab satu per satu.
31.5.1 Rekap Port yang Sudah Kita Buka Sejak Bab 3
| Bab | Service | Port / Protokol | Rule UFW |
|---|---|---|---|
| 3 | SSH (port kustom) | 2222/tcp | ufw allow 2222/tcp |
| 9 | DNS (BIND9) | 53 (tcp & udp) | ufw allow 53 |
| 10 | DHCP | 67/udp | ufw allow 67/udp |
| 11 | NTP (chrony) | 123/udp, dibatasi subnet | ufw allow from 192.168.1.0/24 to any port 123 proto udp |
| 12 | HTTP (Nginx) | 80/tcp | ufw allow 80/tcp |
| 13 | HTTP & HTTPS (Apache) | 80, 443/tcp lewat profile | ufw allow 'Apache Full' |
| 17 | HTTPS (Let's Encrypt) | 443/tcp | ufw allow 443/tcp |
| 18 | PostgreSQL | 5432/tcp, dibatasi subnet | ufw allow from 192.168.1.0/24 to any port 5432 proto tcp |
| 19 | MySQL | 3306/tcp, dibatasi subnet | ufw allow from 192.168.1.0/24 to any port 3306 proto tcp |
| 24 | Samba | 445/tcp, manual bukan profile | ufw allow 445/tcp |
| 25 | NFS | 2049/tcp, dibatasi subnet | ufw allow from 192.168.1.0/24 to any port 2049 proto tcp |
Ada pola yang layak diperhatikan dari tabel di atas. Service yang memang perlu diakses publik luas, seperti HTTP, HTTPS, dan DNS, dibuka tanpa batasan source. Service yang sifatnya internal, seperti database dan file sharing, selalu dibatasi ke subnet tepercaya 192.168.1.0/24, bukan Anywhere. Ini bukan kebetulan, melainkan penerapan konsisten prinsip least privilege yang sudah kita singgung di Bab 30 dan akan kita perdalam lagi di Bab 34.
31.5.2 Prinsip Default Deny Incoming dan Urutan Rule yang Aman
Default policy UFW yang kita verifikasi di Bagian 31.3.1, yaitu deny incoming, berarti server kita otomatis menolak seluruh trafik masuk yang tidak eksplisit diizinkan. Ini adalah filosofi whitelist: menutup semua akses lebih dulu, baru membuka satu per satu sesuai kebutuhan, jauh lebih aman dibanding filosofi blacklist yang membuka semua akses lalu menutup satu per satu yang bermasalah setelah insiden terjadi. UFW menerapkan prinsip ini secara otomatis tanpa kita perlu mengatur urutan rule secara manual, karena UFW secara internal selalu menempatkan rule allow yang lebih spesifik sebelum kembali ke default deny yang umum. Di iptables maupun nftables mentah, tanggung jawab urutan ini sepenuhnya ada di tangan kita sendiri, persis seperti yang kita alami langsung di Bagian 31.2.3 saat rule ACCEPT harus sengaja disisipkan di atas rule DROP agar berfungsi benar.
Verifikasi dan Troubleshooting
- Konfirmasikan default policy yang sedang berlaku.
sudo ufw status verbose - Catatan lapangan: jangan pernah mengubah default outgoing ke
denytanpa persiapan matang. Proses sepertiapt update, sinkronisasi NTP, atau notifikasi outbound lain akan ikut terblokir, dan gejalanya sering tidak langsung, misalnya package gagal ter-update atau jam server perlahan meleset, sehingga penyebabnya baru terlihat setelah cukup lama.
31.6 Logging dan Monitoring Firewall
Rule yang benar tanpa visibility tetap berisiko. Log firewall adalah salah satu sumber data paling murni untuk melihat siapa saja yang mengetuk pintu server kita, termasuk percobaan dari Attacker yang gagal karena sudah ditolak oleh rule yang sudah kita susun sepanjang bab ini.
31.6.1 Level Logging UFW dan Cara Membacanya
UFW mendukung lima level logging: off, low, medium, high, dan full, dengan low sebagai default begitu UFW diaktifkan. Level low mencatat paket yang diblokir karena tidak cocok rule mana pun beserta paket yang cocok rule yang memang ditandai untuk di-log, sudah cukup untuk kebutuhan monitoring harian tanpa membebani disk.
Langkah Praktik
- Pastikan logging aktif di level
low. Level ini sebenarnya sudah default sejak UFW diaktifkan di Bagian 31.3.1, tapi menjalankannya secara eksplisit tetap baik untuk dokumentasi konfigurasi.sudo ufw logging low - Pantau log secara real-time.
sudo tail -f /var/log/ufw.log
Verifikasi dan Troubleshooting
- Cari entri trafik yang ditolak lewat kata kunci
[UFW BLOCK].sudo grep 'UFW BLOCK' /var/log/ufw.log | tail -20 - Jika
/var/log/ufw.logtidak ditemukan meskirsyslogterpasang normal, log tetap bisa ditelusuri lewat journald.sudo journalctl -k | grep UFW - Level
mediumke atas menghasilkan volume log jauh lebih besar karena ikut mencatat seluruh trafik yang diizinkan, bukan cuma yang ditolak. Pertimbangkan level ini hanya untuk sesi troubleshooting sementara, bukan default permanen, karena berisiko memenuhi disk dengan cepat di server yang sibuk.
31.6.2 Logging Native di nftables dengan Statement log
Jika memilih jalur nftables native seperti pada Bagian 31.4, logging tidak otomatis berjalan global seperti UFW. Setiap rule yang ingin dicatat harus ditambahkan statement log secara eksplisit.
Langkah Praktik
- Tambahkan logging ke rule SSH pada ruleset
nftableslatihan di Bagian 31.4.1.sudo nft add rule inet filter input tcp dport 2222 log prefix "SSH-ATTEMPT " accept
Verifikasi dan Troubleshooting
- Pantau entri log yang baru ditambahkan lewat journald.
Cari baris yang diawali prefixsudo journalctl -k -fSSH-ATTEMPTsetiap kali ada percobaan koneksi baru ke port tersebut. - Statement
logdiletakkan sebelum action final sepertiacceptataudrop, dan tetap meneruskan paket ke action tersebut, bukan menggantikannya. Statement ini bisa dipasang di ruleacceptmaupundroptergantung trafik mana yang ingin dipantau. - Untuk kebutuhan analisis lanjutan yang memisahkan log ke consumer userspace terpisah seperti
ulogd, tambahkan parametergrouppada statementlog. Detail konfigurasiulogdsendiri berada di luar cakupan series ini.
31.6.3 Studi Kasus: Mengenali Pola Port Scanning dari Log
Di lapangan, deretan entri UFW BLOCK dengan source IP yang sama menyasar banyak port berurutan dalam hitungan detik hampir selalu ciri khas port scanner otomatis seperti nmap, bukan sekadar user yang salah ketik alamat.
Langkah Praktik
- Hitung source IP yang paling sering muncul di log blokir sepanjang jam berjalan.
sudo grep 'UFW BLOCK' /var/log/ufw.log | grep "$(date '+%b %e %H')" | grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn | head -10
Verifikasi dan Troubleshooting
- Satu source IP dengan ratusan percobaan blokir ke banyak port berbeda dalam waktu singkat layak dipertimbangkan untuk diblokir permanen secara manual sebagai langkah darurat.
sudo ufw insert 1 deny from alamat_ip_scanner comment 'scanner terdeteksi manual' - Pendekatan grep manual ini bersifat reaktif dan tidak scalable untuk server yang menerima ribuan percobaan koneksi tiap hari. Bab 32 berikutnya mengotomasi persis proses deteksi-dan-blokir ini lewat Fail2ban, sehingga kita tidak perlu lagi grep log secara manual setiap hari.
Sampai di sini kita sudah menuntaskan lapisan kedua defense in depth dari Bagian 30.1.2: memahami evolusi iptables ke nftables, membaca rule iptables mentah secara langsung sampai paham alasan Docker bisa menembus UFW, mengaktifkan UFW secara resmi lengkap dengan rate limiting dan application profile kustom, mencoba sintaks nftables native beserta cara migrasi rule lama, merangkum seluruh port service yang sudah kita buka sejak Bab 3, hingga logging dan monitoring sebagai bekal deteksi dini. Firewall yang rapi tetap punya satu titik buta: ia hanya bisa menolak apa yang sudah eksplisit kita larang, tapi tidak bisa mengenali pola serangan berulang secara otomatis atau memblokir IP mencurigakan tanpa campur tangan manual seperti yang baru saja kita lakukan sendiri di Bagian 31.6.3. Bab 32 menutup titik buta itu lewat Fail2ban, lapisan ketiga pada peta defense in depth kita, yang mengotomasi deteksi pola dari log dan pemblokiran IP secara real-time tanpa perlu kita pantau log secara manual setiap hari.

