nftables adalah framework firewall modern yang dirancang untuk menggantikan iptables, ip6tables, arptables, dan ebtables pada banyak distribusi Linux terbaru. nftables menawarkan sintaks yang lebih konsisten, performa lebih baik, serta dukungan fitur yang lebih luas, termasuk kemampuan memanfaatkan set data berukuran besar, seperti daftar alamat IP berdasarkan negara (GeoIP).
Blokir Berdasarkan Negara (Country Blocking) #
Instalasi nftables #
sudo apt-get install nftables # Ubuntu / Debian
sudo yum install nftables # CentOS / RHEL
Konfigurasi Dasar nftables #
Buat tabel filter pada family inet (berlaku untuk IPv4 dan IPv6):
nft add table inet filter
Buat chain input dengan hook ke paket masuk:
nft add chain inet filter input '{ type filter hook input priority 0; }'
Membuat Set IP Berdasarkan Negara (IPv4) #
Buat set baru untuk menyimpan daftar IP IPv4 yang akan diblokir:
nft add set inet filter country_block_v4 '{ type ipv4_addr; flags interval; auto-merge; comment "Blocked IPv4 Countries"; }'
Tambahkan rule untuk memblokir paket dari IP yang terdapat dalam set tersebut, sekaligus mencatat log:
nft add rule inet filter input ip saddr @country_block_v4 log prefix "GEOBLOCK-IPv4-DROP: " drop
Mengunduh Daftar IP Berdasarkan Negara #
Unduh daftar IP sesuai negara yang ingin diblokir. Beberapa sumber yang umum digunakan antara lain:
Umumnya, daftar IP tersebut tersedia dalam format CIDR (x.x.x.x/yy) dan dapat langsung diimpor ke dalam set nftables.
Menambahkan IP ke Set nftables #
Tambahkan alamat IP atau subnet ke dalam set country_block_v4:
nft add element inet filter country_block_v4 { 192.168.1.100 }
nft add element inet filter country_block_v4 { 203.0.113.45 }
Contoh menambahkan satu subnet CIDR:
nft add element inet filter country_block_v4 { 203.0.113.0/24 }
Melihat Konfigurasi nftables #
Untuk menampilkan daftar tabel yang ada:
nft list tables
Untuk menampilkan semua chain:
nft list chains
Untuk menampilkan rule pada chain input di tabel filter:
nft list chain inet filter input
Untuk menampilkan seluruh konfigurasi nftables secara lengkap:
nft list ruleset
Persist Konfigurasi nftables (Agar Aktif Setelah Reboot) #
Secara default, rule nftables yang ditambahkan lewat command line tidak otomatis tersimpan setelah reboot. Untuk membuatnya persisten, lakukan langkah berikut.
Simpan Konfigurasi ke File #
Simpan seluruh ruleset nftables ke file konfigurasi:
sudo nft list ruleset > /etc/nftables.conf
/etc/nftables.conf adalah lokasi default yang digunakan oleh service nftables.
Aktifkan dan Jalankan Service nftables #
Aktifkan service agar dijalankan otomatis saat boot:
sudo systemctl enable nftables
sudo systemctl start nftables
Untuk memastikan service berjalan dengan benar:
sudo systemctl status nftables
Memuat Ulang Konfigurasi (Reload) #
Jika ada perubahan pada /etc/nftables.conf, muat ulang konfigurasi dengan:
sudo nft -f /etc/nftables.conf
Optimasi Rule agar Lebih Aman #
Agar firewall lebih aman dan efisien, rule sebaiknya disusun dengan urutan yang benar.
Izinkan Koneksi yang Sudah Ada (Established / Related) #
Rule ini harus berada di awal chain input agar koneksi yang sah tidak terputus:
nft add rule inet filter input ct state established,related accept
Izinkan Loopback Interface #
Loopback wajib diizinkan untuk komunikasi lokal:
nft add rule inet filter input iif lo accept
(Opsional) Izinkan Port / Service Tertentu #
Contoh mengizinkan SSH dan HTTP/HTTPS:
nft add rule inet filter input tcp dport { 22, 80, 443 } accept
Default Policy Drop (Best Practice) #
Tambahkan rule terakhir untuk menolak semua trafik lain:
nft add rule inet filter input counter drop
Contoh Urutan Rule yang Direkomendasikan #
ct state established,related acceptiif lo accept- ICMP / ICMPv6
- Allow service (SSH, HTTP, dll)
- GeoIP / country block
- Drop default
Urutan ini memastikan:
- koneksi aktif tetap berjalan,
- layanan penting tetap bisa diakses,
- trafik dari negara terblokir dihentikan,
- dan semua trafik lain ditolak secara aman.
Contoh Script Bash Otomatis #
Script berikut digunakan untuk mengunduh daftar IP negara tertentu dan memasukannya ke set.
#!/bin/bash
set -e
set -o pipefail
# --- Konfigurasi ---
# Daftar kode negara yang akan diblokir (huruf kecil).
# Contoh: ("cn" "ru" "us")
COUNTRIES_TO_BLOCK=("cn")
# --- Konfigurasi nftables ---
TABLE="inet filter"
CHAIN="input"
SET4="country_block_v4"
SET6="country_block_v6"
# --- Fungsi untuk menyiapkan nftables secara idempoten ---
setup_nftables() {
echo "Menyiapkan tabel dan set di nftables..."
# Pastikan tabel ada
nft list table $TABLE &>/dev/null || nft add table $TABLE
# Pastikan chain ada
nft list chain $TABLE $CHAIN &>/dev/null || nft add chain $TABLE $CHAIN '{ type filter hook input priority 0; }'
# Hapus set jika sudah ada untuk menghindari error dan memulai dari keadaan bersih
nft delete set $TABLE $SET4 2>/dev/null || true
nft delete set $TABLE $SET6 2>/dev/null || true
# Buat set baru untuk IPv4 dan IPv6
nft add set $TABLE $SET4 '{ type ipv4_addr; flags interval; auto-merge; comment "Blocked IPv4 Countries"; }'
nft add set $TABLE $SET6 '{ type ipv6_addr; flags interval; auto-merge; comment "Blocked IPv6 Countries"; }'
# Hapus aturan lama yang mungkin ada untuk menghindari duplikasi
rule_numbers=$(nft -a list chain "$TABLE" "$CHAIN" \
| grep -E "$SET4|$SET6" \
| awk '{for(i=1;i<=NF;i++){if($i=="handle"){print $(i+1)}}}')
if [ -n "$rule_numbers" ]; then
for rule_number in $rule_numbers; do
nft delete rule "$TABLE" "$CHAIN" handle "$rule_number"
done
fi
# Tambahkan aturan pemblokiran dengan logging
# Log akan muncul di dmesg atau /var/log/kern.log
nft add rule $TABLE $CHAIN ct state established,related accept comment "$SET4"
nft add rule $TABLE $CHAIN iif lo accept comment "$SET4"
nft add rule $TABLE $CHAIN ip saddr @$SET4 log prefix \"GEOBLOCK-IPv4-DROP: \" drop
nft add rule $TABLE $CHAIN ip6 saddr @$SET6 log prefix \"GEOBLOCK-IPv6-DROP: \" drop
echo "Struktur nftables siap."
}
# --- Fungsi untuk mengunduh dan memuat IP ---
process_country_ips() {
local country_code=$1
local url_v4="https://raw.githubusercontent.com/ipverse/country-ip-blocks/master/country/${country_code}/ipv4-aggregated.txt"
local url_v6="https://raw.githubusercontent.com/ipverse/country-ip-blocks/master/country/${country_code}/ipv6-aggregated.txt"
echo "Memproses negara: ${country_code^^}..."
# Proses IPv4
echo " -> Mengunduh dan memuat daftar IPv4..."
if ips=$(curl -s -f -L "$url_v4" \
| grep -v "^#" \
| cut -d',' -f1 \
| tail -n +2 \
| tr '\n' ',' \
| sed 's/,$//'); then
if [ -n "$ips" ]; then
nft add element "$TABLE" "$SET4" { $ips }
echo " -> IPv4 untuk ${country_code^^} berhasil dimuat."
else
echo " -> PERINGATAN: Tidak ada IP valid untuk ${country_code^^}."
fi
else
echo " -> PERINGATAN: Gagal mengunduh atau memproses IPv4 untuk ${country_code^^}"
fi
# Proses IPv6
echo " -> Mengunduh dan memuat daftar IPv6..."
if ips=$(curl -s -f -L "$url_v6" \
| grep -v "^#" \
| cut -d',' -f1 \
| tail -n +2 \
| tr '\n' ',' \
| sed 's/,$//'); then
if [ -n "$ips" ]; then
nft add element "$TABLE" "$SET6" { $ips }
echo " -> IPv6 untuk ${country_code^^} berhasil dimuat."
else
echo " -> PERINGATAN: Tidak ada IP valid untuk ${country_code^^}."
fi
else
echo " -> PERINGATAN: Gagal mengunduh atau memproses IPv6 untuk ${country_code^^}"
fi
}
# --- Eksekusi Utama ---
# 1. Menyiapkan struktur nftables
setup_nftables
# 2. Loop melalui semua negara yang akan diblokir
for COUNTRY in "${COUNTRIES_TO_BLOCK[@]}"; do
process_country_ips "$COUNTRY"
done
echo -e "\nPembaruan daftar IP blokir selesai."
echo "Total IPv4 yang ditambahkan: $(nft list set $TABLE $SET4 | wc -l)"
echo "Total IPv6 yang ditambahkan: $(nft list set $TABLE $SET6 | wc -l)"
echo "Aturan pemblokiran telah diterapkan dan di-log."