Langkah 0: Persiapan Dan Prasyarat :
Sebelum memulai, pastikan dua hal ini terpenuhi.
1.Pastikan Anda memiliki layanan UDP proxy yang sudah berjalan. Anda perlu mengetahui nama layanan systemd-nya. Nama yang umum adalah udp-custom.service, udp-proxy.service, atau xray.service. Untuk panduan ini, kita akan menggunakan udp-custom.service sebagai contoh. Ganti dengan nama layanan Anda yang sebenarnya.
Cari nama layanan Anda:
systemctl list-units --type=service | grep -i udp
2.Instal conntrack. Alat ini wajib untuk memutus koneksi UDP secara paksa.
# Untuk Debian/Ubuntu
sudo apt update && sudo apt install conntrack -y
Langkah 1: Membuat Skrip Penjaga Utama
Ini adalah otak dari sistem. Skrip ini akan memantau log, mengelola status, dan mengeksekusi aturan firewall.
1.Buat file skrip di lokasi yang standar:
sudo nano /opt/udp-proxy/bin/enforcer_service.sh
2.Copy-paste seluruh kode di bawah ini. Jangan ubah apa pun kecuali yang ada di bagian "KONFIGURASI".
#!/bin/bash
# =================================================================
# --- CEK FILE BENDERA (PANEL KONTROL) ---
# Skrip akan berhenti jika file bendera ini tidak ada.
# =================================================================
FLAG_FILE="/opt/udp-proxy/log/enforcer.enabled"
if [ ! -f "$FLAG_FILE" ]; then
echo "[$(date)] File bendera '$FLAG_FILE' tidak ditemukan. Penjaga tidak aktif. Keluar."
exit 0
fi
# =================================================================
# --- KONFIGURASI PENJAGA (UBAH BAGIAN INI SAJA) ---
# =================================================================
PROTECTED_PORT=36712 # Port UDP yang dilindungi
STATE_FILE="/opt/udp-proxy/log/enforcer_state.log"
IPTABLES_CHAIN="UDP_ENFORCER"
MEMORY_MINUTES=10 # Berapa lama mengingat sesi yang tidak aktif
TIMEOUT_MINUTES=15 # Sesi dianggap hangus setelah X menit tidak ada aktivitas
GRACE_PERIOD_SECONDS=120 # Waktu tunggu sebelum IP lama ditendang (120 detik = 2 menit)
# Nama layanan UDP proxy Anda (DITEMUKAN DI LANGKAH 0)
UDP_SERVICE_NAME="udp-custom.service"
# =================================================================
# --- PASTIKAN DIREKTORI YANG DIPERLUKAN ADA ---
mkdir -p "$(dirname "$STATE_FILE")"
touch "$STATE_FILE"
# =================================================================
# --- FUNGSI PEMBERSIH (OTOMATIS LUPA & EKSEKUSI TIMER) ---
# =================================================================
function cleanup() {
echo "[$(date)] =====> MEMULAI PEMBERSIHAN DAN EKSEKUSI TIMER <====="
local current_time=$(date +%s)
local timeout_seconds=$((TIMEOUT_MINUTES * 60))
local temp_state_file=$(mktemp)
while IFS=':' read -r user ip last_seen violation_time; do
if [[ -z "$user" || -z "$ip" || -z "$last_seen" ]]; then continue; fi
local elapsed=$((current_time - last_seen))
if [ "$elapsed" -lt "$timeout_seconds" ]; then
if [[ -n "$violation_time" ]]; then
local violation_elapsed=$((current_time - violation_time))
if [ "$violation_elapsed" -ge "$GRACE_PERIOD_SECONDS" ]; then
echo "[$(date)] >>> EKSEKUSI: Timer habis. Memutus & memblokir IP '$ip' (user: '$user')..."
sudo conntrack -D -s "$ip" -p udp 2>/dev/null
if ! sudo iptables -C "$IPTABLES_CHAIN" -s "$ip" -j DROP &> /dev/null; then
sudo iptables -A "$IPTABLES_CHAIN" -s "$ip" -j DROP -m comment --comment "Kicked $USER on $(date +%F-%T)"
echo "[$(date)] >>> IP '$ip' telah diblokir."
fi
continue
else
echo "[$(date)] [DEBUG] Timer untuk IP '$ip' user '$user' belum habis. Menunggu..."
echo "${user}:${ip}:${last_seen}:${violation_time}" >> "$temp_state_file"
fi
else
echo "[$(date)] [DEBUG] Sesi normal untuk user '$user' dari IP '$ip'."
echo "${user}:${ip}:${last_seen}:" >> "$temp_state_file"
fi
else
echo "[$(date)] Sesi untuk user '$user' dari IP '$ip' kadaluarsa. Membuka blokir..."
local rule_num=$(sudo iptables -L "$IPTABLES_CHAIN" --line-numbers -n | grep "$ip" | awk '{print $1}' | head -n 1)
if [ -n "$rule_num" ]; then
sudo iptables -D "$IPTABLES_CHAIN" "$rule_num"
fi
fi
done < "$STATE_FILE"
mv "$temp_state_file" "$STATE_FILE"
echo "[$(date)] =====> PEMBERSIHAN SELESAI <====="
}
# =================================================================
# --- INISIALISASI PENJAGA ---
# =================================================================
# Buat chain jika belum ada
if ! sudo iptables -L "$IPTABLES_CHAIN" &> /dev/null; then
echo "[$(date)] Membuat chain iptables: $IPTABLES_CHAIN"
sudo iptables -N "$IPTABLES_CHAIN"
fi
# --- PASTIKAN POSISI ATURAN BENAR (KRUSIAL) ---
echo "[$(date)] Memastikan aturan iptables berada di posisi teratas..."
sudo iptables -D INPUT -p udp --dport "$PROTECTED_PORT" -j "$IPTABLES_CHAIN" 2>/dev/null
sudo iptables -D FORWARD -p udp --dport "$PROTECTED_PORT" -j "$IPTABLES_CHAIN" 2>/dev/null
sudo iptables -F "$IPTABLES_CHAIN" # Bersihkan aturan lama
sudo iptables -I INPUT 1 -p udp --dport "$PROTECTED_PORT" -j "$IPTABLES_CHAIN"
sudo iptables -I FORWARD 1 -p udp --dport "$PROTECTED_PORT" -j "$IPTABLES_CHAIN"
# Jalankan cleanup di latar belakang
while true; do
cleanup
sleep 300
done &
CLEANUP_PID=$!
trap 'kill $CLEANUP_PID; exit' SIGTERM SIGINT
# Memori awal
echo "[$(date)] Memuat memori awal dari $MEMORY_MINUTES menit terakhir..."
sudo journalctl -u "$UDP_SERVICE_NAME" --since "$MEMORY_MINUTES minutes ago" --no-pager | grep "Client connected" | sort | awk -F'[][]' '
{
for (i=1; i<=NF; i++) {
if ($i ~ /src:/) { split($i, s, ":"); ip = s[2]; }
if ($i ~ /user:/) { split($i, u, ":"); user = u[2]; }
}
if (user && ip) {
print user ":" ip ":" systime() ":" > "'"$STATE_FILE"'"
}
}'
awk -i inplace '!seen[$0]++' "$STATE_FILE"
echo "[$(date)] Memori awal selesai. Penjaga siap bertugas!"
# Loop utama pemantauan
echo "[$(date)] Memantau log layanan: $UDP_SERVICE_NAME"
sudo journalctl -u "$UDP_SERVICE_NAME" -f --no-tail | while read line; do
if [[ "$line" == *"[INFO]"*"[src:"*"[user:"*"Client connected"* ]]; then
IP=$(echo "$line" | awk -F'[][]' '{for(i=1;i<=NF;i++){if($i ~ /src:/){split($i, a, ":"); print a[2]}}}')
USER=$(echo "$line" | awk -F'[][]' '{for(i=1;i<=NF;i++){if($i ~ /user:/){split($i, a, ":"); print a[2]}}}')
if [[ -n "$IP" && -n "$USER" ]]; then
echo "[$(date)] Koneksi baru: User '$USER' dari IP '$IP'"
LAST_ENTRY=$(grep "^${USER}:" "$STATE_FILE" | tail -n 1)
LAST_IP=$(echo "$LAST_ENTRY" | cut -d':' -f2)
if [[ -n "$LAST_IP" && "$LAST_IP" != "$IP" ]]; then
echo "[$(date)] >>> PELANGGARAN: User '$USER' multi-login (IP lama: '$LAST_IP', IP baru: '$IP')."
echo "[$(date)] >>> IP lama '$LAST_IP' akan ditendang dalam $((GRACE_PERIOD_SECONDS / 60)) menit."
OLD_LAST_SEEN=$(echo "$LAST_ENTRY" | cut -d':' -f3)
sed -i "/^${USER}:${LAST_IP}:/d" "$STATE_FILE"
echo "${USER}:${LAST_IP}:${OLD_LAST_SEEN}:$(date +%s)" >> "$STATE_FILE"
fi
echo "${USER}:${IP}:$(date +%s)::" >> "$STATE_FILE"
awk -i inplace '!seen[$0]++' "$STATE_FILE"
fi
elif [[ "$line" == *"[INFO]"*"[src:"*"[user:"*"Client disconnected"* ]]; then
IP=$(echo "$line" | awk -F'[][]' '{for(i=1;i<=NF;i++){if($i ~ /src:/){split($i, a, ":"); print a[2]}}}')
USER=$(echo "$line" | awk -F'[][]' '{for(i=1;i<=NF;i++){if($i ~ /user:/){split($i, a, ":"); print a[2]}}}')
if [[ -n "$IP" && -n "$USER" ]]; then
echo "[$(date)] User '$USER' dari IP '$IP' disconnect. Membersihkan state..."
sed -i "/^${USER}:${IP}:/d" "$STATE_FILE"
fi
fi
done
4.Jadikan skrip dapat dieksekusi:
sudo chmod +x /opt/udp-proxy/bin/enforcer_service.sh
Langkah 2: Membuat Layanan systemd
Ini membuat skrip penjaga berjalan otomatis di latar belakang dan restart jika gagal.
1.Buat file layanan:
sudo nano /etc/systemd/system/udp-enforcer.service
2.Copy-paste konfigurasi berikut:
[Unit]
Description=UDP Multi-Login Enforcer Service
After=network.target udp-custom.service
[Service]
Type=simple
User=root
ExecStart=/opt/udp-proxy/bin/enforcer_service.sh
Restart=always
RestartSec=10s
[Install]
WantedBy=multi-user.target
Penting: Jika nama layanan UDP Anda bukan udp-custom.service, ubah baris After=... sesuai.
3.Simpan dan keluar (Ctrl+X, Y, Enter).
4.Aktifkan layanan untuk berjalan saat boot:
sudo systemctl daemon-reload
sudo systemctl enable udp-enforcer.service
Langkah 3: Membuat Panel Kontrol On/Off
Ini adalah antarmuka sederhana untuk mengontrol penjaga.
1.Buat direktori untuk panel:
sudo mkdir -p /opt/udp-proxy/panel
2.Buat skrip enable.sh:
sudo nano /opt/udp-proxy/panel/enable.sh
Isi dengan:
#!/bin/bash
echo "Mengaktifkan Penjaga UDP..."
# Pastikan direktori log ada
sudo mkdir -p /opt/udp-proxy/log
# Buat file bendera
sudo touch /opt/udp-proxy/log/enforcer.enabled
# Restart layanan untuk menerapkan
sudo systemctl restart udp-enforcer.service
echo "Penjaga UDP telah diaktifkan dan dimulai ulang."
3.Buat skrip disable.sh:
sudo nano /opt/udp-proxy/panel/disable.sh
Isi dengan:
#!/bin/bash
echo "Menonaktifkan Penjaga UDP..."
# Hapus file bendera
sudo rm -f /opt/udp-proxy/log/enforcer.enabled
# Hentikan layanan
sudo systemctl stop udp-enforcer.service
echo "Penjaga UDP telah dinonaktifkan dan dihentikan."
4.Jadikan kedua skrip panel dapat dieksekusi:
sudo chmod +x /opt/udp-proxy/panel/enable.sh
sudo chmod +x /opt/udp-proxy/panel/disable.sh
Langkah 4: Aktivasi Dan Verifikasi Akhir
Sekarang kita akan mengaktifkan semuanya dan memastikan berjalan sempurna.
1.Aktifkan Penjaga menggunakan panel:
sudo /opt/udp-proxy/panel/enable.sh
2.Periksa status layanan. Harus active (running):
sudo systemctl status udp-enforcer.service
Output yang diharapkan:
● udp-enforcer.service - UDP Multi-Login Enforcer Service
Loaded: loaded (/etc/systemd/system/udp-enforcer.service; enabled; vendor preset: enabled)
Active: **active (running)** since ...
3.Periksa log untuk memastikan skrip berjalan:
sudo journalctl -u udp-enforcer.service -f
4.Verifikasi aturan iptables ada di posisi teratas:
sudo iptables -L INPUT -n --line-numbers
Pastikan aturan yang mengarah ke UDP_ENFORCER ada di nomor 1.
Sistem Anda sekarang seharusnya sudah siap dan berjalan dengan benar!
Untuk mempermudah penggunaan script yang telah kita buat di atas,kita akan membuat menu panel sederhana di postingan berikutnya : Membuat Menu Panel Hunter
