Skip to main content
  1. Posts/

Geoblocking Using nftables

·6 mins·
nftables linux nftables
Table of Contents

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
File /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
#

  1. ct state established,related accept
  2. iif lo accept
  3. ICMP / ICMPv6
  4. Allow service (SSH, HTTP, dll)
  5. GeoIP / country block
  6. 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."

Related

Geoblocking Using IPTables and IPset
·5 mins
iptables iptables linux
Cara Menampilkan Timestamp di History Linux
·1 min
linux linux
Mengubah Tanggal Modifikasi File di Linux
·1 min
linux linux
Create Simple Systemd Service in Linux
·2 mins
linux linux
How to Copy Text in Tmux to System Clipboard
·3 mins
tmux linux tmux
Install GSocket di Linux
·5 mins
gsocket linux gsocket