Dasar firewalld untuk VPS Rocky atau AlmaLinux
Buka SSH, izinkan port web, tutup port, dan pertahankan aturan setelah reboot dengan firewalld. Pahami zone serta jebakan opsi --permanent.
Apa itu firewalld dan mengapa Rocky serta AlmaLinux menyertakannya
firewalld adalah pengelola firewall yang terpasang secara default pada Rocky Linux, AlmaLinux, dan rebuild lain dari Red Hat Enterprise Linux (RHEL). Kedua distribusi tersebut mewarisi default itu, bukan memilihnya sendiri. Hal ini lebih mudah dipahami setelah Anda mengetahui bagaimana Rocky dan AlmaLinux membangun ulang pekerjaan Red Hat setelah CentOS mengubah arah. firewalld tidak memeriksa paket secara langsung. firewalld menyimpan konfigurasi lalu mengubah konfigurasi tersebut menjadi aturan nftables. Satu perintah, firewall-cmd, dapat mengubah konfigurasi itu saat server tetap online. Tidak ada hal dalam panduan ini yang berbeda di antara kedua distribusi tersebut, karena hal yang benar-benar membedakan Rocky dari AlmaLinux adalah komitmen kompatibilitas dan jenis CPU yang masih didukung, bukan firewall.
Jika Anda sudah mengetahui cara kerja ufw pada Ubuntu VPS, Anda sudah memahami fungsinya. firewalld menambahkan dua konsep yang tidak dimiliki ufw. Yang pertama adalah zone, yaitu kebijakan bernama yang menjadi tempat pengelompokan paket. Yang kedua adalah pemisahan antara aturan aktif dan aturan tersimpan. Pemisahan ini menggunakan flag --permanent dan merupakan sumber kebingungan terbesar dalam tool ini.
Semua hal di bawah ini adalah perintah yang Anda jalankan pada server sendiri. Uji setiap perubahan dari mesin kedua, karena aturan yang terlihat benar pada server tetap dapat salah jika dilihat dari internet.
Buka SSH sebelum melakukan hal lain
Sebagian besar instalasi Rocky dan AlmaLinux sudah memiliki firewalld dan menjalankannya. Konfigurasi yang disertakan mengizinkan SSH. Beberapa image cloud minimal menghapusnya. Periksa kondisinya, jangan berasumsi.
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --statefirewall-cmd --state menampilkan running. Jika service berhenti, setiap pemanggilan firewall-cmd lainnya menjawab FirewallD is not running dan keluar dengan kode nonzero. Ini hal pertama yang harus diperiksa ketika sebuah perintah tampaknya tidak melakukan apa pun.
Sekarang lihat aturan yang saat ini diizinkan.
sudo firewall-cmd --list-allOutput sebenarnya memiliki beberapa baris tambahan. Berikut baris yang penting:
public (active)
target: default
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
rich rules:ssh pada baris services: adalah alasan sesi Anda masih berfungsi. Jika aturan tersebut tidak ada, tambahkan sebelum melakukan hal lain, karena menjalankan firewall tanpa aturan SSH akan mengakhiri sesi dan membuat Anda tidak dapat masuk kembali.
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadtarget: default berarti paket yang tidak cocok dengan aturan apa pun ditolak dengan balasan ICMP (internet control message protocol) host-prohibited, sehingga client yang mengakses port tertutup langsung melihat No route to host. Mengatur target ke DROP membuat server tidak memberikan respons, sehingga pemindai kemudian menunggu hingga timeout.
sudo firewall-cmd --permanent --zone=public --set-target=DROP
sudo firewall-cmd --reloadPahami dampaknya sebelum menjalankannya: DROP juga menghentikan server agar tidak menjawab ping, sehingga monitoring Anda sendiri juga berhenti menerima respons.
Mengapa aturan saya hilang? Flag --permanent
firewalld menyimpan dua konfigurasi sekaligus. Konfigurasi runtime adalah konfigurasi yang diterapkan kernel saat ini. Konfigurasi permanen berada di /etc/firewalld/zones/public.xml dan digunakan kembali setelah reload atau reboot.
Perintah tanpa --permanent hanya mengubah konfigurasi runtime. Perubahan langsung berlaku, tetapi hilang saat reload atau boot berikutnya. Perintah dengan --permanent menulis perubahan ke file, tetapi tidak mengubah konfigurasi yang sedang berjalan. Karena itu, port tetap tertutup sampai Anda melakukan reload. Tidak satu pun perilaku ini merupakan bug. Keduanya sering membingungkan karena perintah mencetak success dalam kedua kondisi tersebut.
Selalu tulis keduanya.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reloadAnda dapat membaca kedua konfigurasi tersebut. Ini adalah cara tercepat untuk mengetahui kesalahan yang terjadi.
sudo firewall-cmd --list-services
sudo firewall-cmd --permanent --list-servicesPerintah pertama menampilkan kumpulan aturan aktif. Perintah kedua menampilkan kumpulan aturan tersimpan. Jika kumpulan aturan aktif memuat sebuah service yang tidak ada dalam kumpulan aturan tersimpan, aturan tersebut akan hilang saat reload berikutnya. Jika kumpulan aturan tersimpan memuat aturan yang tidak ada dalam kumpulan aturan aktif, Anda lupa melakukan reload. sudo firewall-cmd --runtime-to-permanent menyalin seluruh konfigurasi aktif ke file tersimpan. Ini berguna setelah sesi percobaan.
--reload mempertahankan status pelacakan koneksi, sehingga sesi SSH Anda tetap berjalan. --complete-reload juga memuat ulang modul kernel dan menghapus status tersebut. Biasanya, tindakan ini mengakhiri semua koneksi yang terbuka, termasuk koneksi Anda. Gunakan reload biasa.
Tersedia mekanisme pengaman bawaan. Aturan runtime dapat kedaluwarsa secara otomatis.
sudo firewall-cmd --add-service=http --timeout=5mAturan tersebut menghapus dirinya sendiri setelah lima menit. Aturan ini tidak dapat digabungkan dengan --permanent. Itulah tujuannya: aturan ini digunakan untuk menguji perubahan yang belum Anda yakini. Mekanisme pengaman yang lebih lama tetap lebih baik. Biarkan sesi SSH kedua tetap terbuka saat mengubah aturan, dan jangan tutup sesi tersebut sampai login baru membuktikan bahwa aturan baru berfungsi.
Zona, dan mengapa hanya zona default yang penting pada VPS
Zona adalah kumpulan izin bernama yang memiliki tingkat kepercayaan. firewalld memasukkan setiap paket masuk ke tepat satu zona. firewalld terlebih dahulu mencocokkan alamat sumber paket dengan daftar sources: setiap zona. Jika tidak ada yang cocok, firewalld menggunakan zona tempat interface masuk terikat. Jika interface tidak terikat ke zona mana pun, paket masuk ke zona default.
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zonesPada VPS dengan satu interface jaringan, jawaban pertama hampir selalu public, dan itulah satu-satunya zona yang akan Anda gunakan. firewall-cmd tanpa argumen --zone= bekerja pada zona default. Karena itu, semua perintah singkat dalam panduan ini dapat dijalankan tanpa menyebutkan zona.
Berikut kegagalan yang dapat membuang waktu sepanjang sore. Jika interface terikat ke zona lain, aturan Anda masuk ke public, sedangkan trafik ditangani di tempat lain. Akibatnya, aturan yang Anda tambahkan tidak berpengaruh dan tidak ada peringatan. --get-active-zones menampilkan binding tersebut:
public
interfaces: eth0Jika interface muncul di bawah nama zona yang berbeda, tulis aturan Anda di zona tersebut menggunakan --zone=, atau pindahkan interface itu.
sudo firewall-cmd --permanent --zone=public --change-interface=eth0
sudo firewall-cmd --reloadNetworkManager mengelola interface pada Rocky dan AlmaLinux, serta menerapkan kembali zona saat koneksi aktif. Tetapkan zona di sana juga agar reboot tidak membatalkan perubahan Anda. Ambil nama koneksi dari perintah pertama karena nama tersebut jarang sama dengan nama device.
sudo nmcli connection show
sudo nmcli connection modify "System eth0" connection.zone publicPencocokan sumber memiliki prioritas atas pencocokan interface. Dengan demikian, satu alamat dapat memperoleh kebijakan yang berbeda. Zona bawaan trusted menerima semua hal.
sudo firewall-cmd --permanent --zone=trusted --add-source=203.0.113.10/32
sudo firewall-cmd --reloadBerhati-hatilah dengan zona tersebut. Zona ini membuka semua port pada server untuk alamat itu, termasuk database yang Anda anggap privat. Gunakan rich rule jika Anda hanya ingin membuka satu port, bukan memberikan akses kepada satu host.
Apa itu service firewalld?
Service adalah kumpulan port bernama yang disediakan sebagai file XML. --add-service=https membuka 443/tcp karena /usr/lib/firewalld/services/https.xml menentukan arti https.
sudo firewall-cmd --get-services
sudo firewall-cmd --info-service=https--info-service menampilkan port yang berada di balik nama tersebut:
https
ports: 443/tcpGunakan nama jika tersedia. Nama tersebut lebih mudah dipahami dalam --list-all enam bulan kemudian, dan paket seperti Cockpit memasang file service-nya sendiri. Gunakan --add-port untuk apa pun yang tidak memiliki definisi.
Hal yang perlu diperhatikan: service ssh berarti 22/tcp dan tidak ada yang lain. Jika Anda memindahkan SSH ke port lain saat memperkuat akses SSH ke server, --add-service=ssh tidak membuka port yang benar-benar Anda gunakan.
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reloadPada rebuild RHEL, ada pengunci kedua pada port tersebut. SELinux (security-enhanced Linux) memberi label pada nomor port, dan sshd tidak diizinkan melakukan bind ke port di luar labelnya. Akibatnya, service tersebut gagal start dan log menampilkan error: Bind to port 2222 on 0.0.0.0 failed: Permission denied. Beri label pada port terlebih dahulu.
sudo dnf install -y policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp 2222Bagaimana cara melihat apa yang sedang terbuka?
sudo firewall-cmd --list-all
sudo firewall-cmd --list-rich-rules
sudo nft list table inet firewalld | head -n 40Dua perintah pertama melaporkan apa yang diyakini firewalld. Perintah ketiga membaca aturan yang sebenarnya tersimpan di kernel, dalam tabel yang dikelola firewalld. Hasilnya seharusnya sama.
Tidak satu pun dari pemeriksaan tersebut menjadi bukti. Uji dari mesin lain:
nc -zv 203.0.113.20 443Jangan jalankan pengujian dari server itu sendiri. firewalld menerima semua koneksi yang tiba melalui antarmuka loopback, sehingga curl http://localhost:8080 berhasil apa pun aturan Anda. Pengujian tersebut menunjukkan bahwa service aktif. Pengujian tersebut tidak memberi informasi apa pun tentang firewall.
Izinkan port web
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-servicesPerintah terakhir sekarang seharusnya menampilkan http https bersama entri yang sudah ada sebelumnya. Jika situs masih tidak merespons, firewall mungkin bukan penyebabnya. Sebuah rule mengizinkan paket. Namun, proses tetap harus listening untuk menerima paket tersebut.
sudo ss -tlnpSocket yang ditampilkan sebagai 0.0.0.0:443 atau *:443 menerima koneksi dari alamat mana pun. Socket yang ditampilkan sebagai 127.0.0.1:443 hanya merespons pada loopback, dan tidak ada firewall rule yang dapat membuatnya dapat diakses dari luar. Port dan socket listening di Linux menjelaskan perbedaan tersebut secara lebih rinci.
Bagaimana cara menutup port?
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reloadAturan --permanent juga berlaku di sini, dan dampaknya lebih besar dalam arah ini. Hapus sebuah service hanya dari runtime, lalu port terlihat tertutup. Namun, reload atau reboot berikutnya akan membukanya kembali dari file tersimpan. Ini adalah celah yang tidak akan Anda sadari karena pemeriksaan yang dijalankan berhasil.
Menghapus sesuatu yang sebelumnya tidak ada akan menampilkan Warning: NOT_ENABLED: http dan tetap keluar dengan kode 0. Menambahkan hal yang sama dua kali akan menampilkan Warning: ALREADY_ENABLED: http. Keduanya aman. Nama yang salah eja berbeda: Error: INVALID_SERVICE berarti firewalld tidak memiliki definisi dengan nama tersebut dan tidak ada perubahan yang dilakukan sama sekali.
Jika --list-all Anda menampilkan cockpit dan Anda tidak menggunakan konsol web Cockpit pada port 9090, hapus service tersebut. Setiap port yang terbuka adalah service yang harus terus Anda tambal, dan untuk service yang dipertahankan, dnf-automatic dapat memasang pembaruan keamanan sesuai jadwal sehingga tugas tersebut tidak bergantung pada ingatan Anda. Memasang patch tidak sama dengan menjalankannya, dan needs-restarting menampilkan service yang masih menggunakan library lama setelah pembaruan tersebut terpasang.
Batasi port ke satu alamat sumber
Rich rule adalah bentuk lengkap yang digunakan ketika nama service biasa tidak dapat menyatakan kebutuhan Anda. Membatasi SSH ke satu alamat kantor memerlukan dua perintah, dan perintah kedua sering dilupakan.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept'
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reloadZone adalah sekumpulan izin, bukan daftar bernomor yang berhenti pada kecocokan pertama. Rich rule menambahkan izin accept untuk satu alamat. Rich rule tersebut tidak menolak alamat mana pun. Selama ssh masih berada pada baris services:, seluruh Internet tetap dapat mengakses port 22 dan rich rule tidak mengubah apa pun yang dapat diukur. Hapus entri yang terlalu luas, atau aturan yang lebih spesifik itu hanya menjadi hiasan.
Untuk port yang tidak memiliki nama service, tentukan nomor port secara langsung.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" port port="5432" protocol="tcp" accept'Untuk menolak jaringan yang menghasilkan banyak trafik sekaligus menyimpan catatannya, letakkan elemen log sebelum action. Urutan ini diperlukan oleh bahasa rich rule.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" log prefix="fw-drop " level="info" limit value="3/m" drop'
sudo firewall-cmd --reload
sudo journalctl -k -g fw-dropNilai limit mencegah banjir paket memenuhi journal. Sebelum membatasi SSH ke satu alamat, pastikan alamat tersebut stabil. Koneksi rumah dengan alamat IP yang berubah dapat mengunci Anda di luar server saat alamat itu berubah. Karena itu, pastikan akses console dari provider sudah diuji dan berfungsi.
perintah ufw dan padanannya dalam firewall-cmd
Tugasnya sama, tetapi alatnya berbeda. Setiap baris --permanent memerlukan sudo firewall-cmd --reload setelahnya. Hal ini tidak dapat ditunjukkan oleh daftar seperti ini.
sudo ufw enablemenjadisudo systemctl enable --now firewalldsudo ufw disablemenjadisudo systemctl disable --now firewalldsudo ufw status verbosemenjadisudo firewall-cmd --list-allsudo ufw allow OpenSSHmenjadisudo firewall-cmd --permanent --add-service=sshsudo ufw allow 443/tcpmenjadisudo firewall-cmd --permanent --add-port=443/tcpsudo ufw delete allow 443/tcpmenjadisudo firewall-cmd --permanent --remove-port=443/tcpsudo ufw allow from 203.0.113.10 to any port 22menjadi rich rule yang ditunjukkan di atassudo ufw reloadmenjadisudo firewall-cmd --reloadsudo ufw default deny incomingsudah merupakan perilaku zonapublic, sedangkan--set-target=DROPadalah versi diamnyasudo ufw logging onmenjadisudo firewall-cmd --set-log-denied=all
Ada satu perbedaan yang perlu dijelaskan secara langsung. ufw mempertahankan daftar bernomor, dan Anda dapat menyisipkan rule pada posisi 1. firewalld tidak memiliki nomor rule, sehingga perintah "letakkan rule ini di urutan pertama" tidak memiliki arti di sini. Jika dua entri firewalld tampak saling bertentangan, aturan accept yang lebih luas akan berlaku karena tidak ada aturan dalam kumpulan tersebut yang menolak. Anda harus menghapus entri yang lebih luas itu sendiri.
Mengapa container Docker saya dapat diakses ketika firewall tampak tertutup?
Karena port container yang dipublikasikan tidak pernah melewati bagian firewall yang dikendalikan oleh zone Anda. docker run -d -p 8080:80 nginx memberi tahu Docker untuk menulis aturan NAT (network address translation) dan forwarding sendiri. Paket yang tiba pada 8080 ditulis ulang dan diteruskan ke container, sehingga paket tersebut diteruskan, bukan dikirim ke host. Baris services: dan ports: pada zone Anda mengatur paket yang dikirim ke host. Aturan Docker mengatur jalur forward, dan aturan tersebut mengizinkan paket.
Akibatnya, server dapat berada dalam kondisi sudo firewall-cmd --list-all tidak menampilkan port 8080, tetapi nc -zv 203.0.113.20 8080 dari mesin lain tetap dapat terhubung. Periksa aturan yang dipasang Docker:
sudo iptables -t nat -L DOCKER -nSolusinya ada pada flag publish. Bind port ke loopback, lalu tempatkan reverse proxy di depannya.
docker run -d -p 127.0.0.1:8080:80 nginxContainer kini merespons curl http://127.0.0.1:8080 pada server, tetapi tidak merespons koneksi dari luar. Pengguna Ubuntu menghadapi masalah yang sama, seperti dijelaskan dalam mengapa container Docker memublikasikan port langsung melewati ufw. Podman rootful, yang disertakan Rocky dan AlmaLinux dalam repositori dasar, memublikasikan port dengan pendekatan NAT yang sama. Karena itu, lakukan pengujian dari mesin lain, bukan hanya mengandalkan daftar zone. Kesamaan ini juga menjadi alasan menginstal Docker Engine pada distribusi ini memerlukan beberapa langkah yang tidak disebutkan dalam panduan Ubuntu, dimulai karena Podman sudah menguasai perintah docker.
Membuatnya bertahan setelah reboot dan error yang akan Anda temui
sudo systemctl is-enabled firewalld
sudo systemctl status firewalldenabled dan active (running) adalah konfigurasi yang Anda inginkan. Firewall yang berjalan tetapi belum diaktifkan hanya melindungi server sampai reboot pertama. Pemeriksaan ini harus ada dalam daftar yang Anda lakukan selama sepuluh menit pertama pada VPS baru, bersama kunci SSH dan update.
Perintah nftables langsung dan firewalld tidak dapat digunakan bersamaan. firewalld memiliki tabel bernama inet firewalld. sudo nft flush ruleset menghapus tabel tersebut, sehingga server terbuka terhadap semua trafik. Namun, firewall-cmd --list-all tetap menampilkan konfigurasi yang Anda inginkan karena firewalld melaporkan konfigurasi yang diyakininya, bukan konfigurasi yang tersimpan di kernel. sudo firewall-cmd --reload memasang ulang aturan tersebut. Tulis aturan menggunakan firewall-cmd agar aturan tetap ada setelah reload.
Dua pengelola firewall pada satu server. Memasang ufw atau iptables-services bersamaan dengan firewalld membuat dua program menulis aturan tanpa saling mengetahui. Program yang berlaku bergantung pada service yang dijalankan terakhir. Pilih satu. Pada Rocky dan AlmaLinux, firewalld adalah pengelola yang didukung oleh distribusi.
Firewall provider di depan server. Banyak panel VPS memiliki firewall jaringan terpisah. Jika --list-all menunjukkan bahwa sebuah port terbuka tetapi koneksi dari luar tetap gagal, periksa panel tersebut sebelum mengubah apa pun pada server. Hal sebaliknya juga berlaku: aturan panel yang terbuka tidak berpengaruh jika firewalld menolak paket tersebut.
Menjalankan firewall-cmd tanpa sudo. Setiap perubahan memerlukan root. Tanpa root, permintaan ditolak melalui pemeriksaan otorisasi dan tidak ada yang diubah. Sekilas, kondisi ini tampak seperti perintah diabaikan.
Enam perintah mencakup sebagian besar kebutuhan sehari-hari: --list-all untuk membaca status, --permanent --add-service atau --add-port untuk membuka sesuatu, --permanent --remove-service untuk menutupnya, --reload untuk menerapkan file yang disimpan, dan --runtime-to-permanent setelah serangkaian eksperimen. Zonanya adalah public, flag-nya adalah --permanent, dan satu-satunya pemeriksaan yang benar-benar dapat diandalkan berasal dari mesin lain.
FAQ
Mengapa aturan firewalld saya hilang setelah reboot?
Aturan tersebut hanya masuk ke konfigurasi runtime. sudo firewall-cmd --add-service=http langsung menerapkannya dan aturan itu dibuang saat reload atau boot berikutnya, karena konfigurasi tersimpan di /etc/firewalld/zones/public.xml tidak pernah diubah. Tambahkan --permanent, lalu jalankan sudo firewall-cmd --reload. Untuk menyimpan aturan yang sudah Anda tambahkan secara manual, jalankan sudo firewall-cmd --runtime-to-permanent. Perintah ini menyalin kumpulan aturan aktif ke file tersimpan.
Mengapa tidak ada perubahan setelah saya menambahkan aturan dengan --permanent?
Karena --permanent menulis file, tetapi tidak mengubah firewall yang sedang berjalan. Port tetap tertutup sampai sudo firewall-cmd --reload memuat konfigurasi tersimpan ke kernel. Bandingkan sudo firewall-cmd --list-services dengan sudo firewall-cmd --permanent --list-services. Jika daftar tersimpan memiliki entri yang tidak ada dalam daftar aktif, berarti reload belum dilakukan.
Sebaiknya saya menggunakan --add-service atau --add-port?
Gunakan --add-service jika tersedia nama untuk layanan yang Anda jalankan. Opsi ini menyatakan tujuan aturan, dan sudo firewall-cmd --info-service=https menampilkan port yang dicakup nama tersebut secara tepat. Gunakan --add-port jika tidak ada definisi untuk layanan Anda, atau jika layanan tersebut listen pada port nonstandar. Service ssh hanya berarti 22/tcp. Jadi, jika SSH dipindahkan ke 2222, Anda memerlukan --add-port=2222/tcp serta label SELinux untuk port tersebut.
Mengapa container Docker saya dapat diakses ketika firewalld menunjukkan port tersebut tertutup?
Port yang dipublikasikan ditulis ulang oleh aturan NAT milik Docker sendiri dan diteruskan ke container. Karena itu, paket tidak pernah dikirimkan ke host, sedangkan daftar service dan port suatu zone hanya mencakup paket yang dikirimkan ke host. Container tetap dapat merespons dari Internet, sementara --list-all tidak menampilkan apa pun. Publikasikan port ke loopback dengan docker run -d -p 127.0.0.1:8080:80 nginx, lalu tempatkan reverse proxy di depannya.
Dapatkah saya menginstal ufw di Rocky Linux sebagai pengganti firewalld?
Dua firewall manager pada satu server menulis aturan tanpa saling mengetahui, dan kumpulan aturan yang bertahan bergantung pada service yang terakhir dijalankan. firewalld adalah tool yang didukung di Rocky Linux dan AlmaLinux. Tool ini sudah terinstal dan menggunakan backend nftables yang sama dengan backend yang akan digunakan ufw. Pelajari zone default dan flag --permanent satu kali, dan Anda akan memahami seluruh tool ini.