Bismillah,
Ini adalah satu tulisan saya yang sangat penting, karena ini adalah Konfigurasi OpenBSD PF yang saya tulis untuk memaksimalkan keamanan webserver di internet. setiap baris code akan saya beri komentar, Insya ALLAH.
Apa yang akan anda pelajari:
1. Konfigurasi PF pada OpenBSD tingkat lanjut
Apa yang harus anda kuasai sebelumnya:
1. Mampu menginstall OpenBSD.
2. Menguasai PF tingkat Dasar.
# $Id: pf.conf_48,v 1.25 2011/03/07 03:11:19 hasan Exp $
# Edit by Muhammad Muntaza <m.muntaza@gmail.com>
# $OpenBSD: pf.conf,v 1.44 2009/06/10 15:29:34 sobrado Exp $
#
# See pf.conf(5) for syntax and examples; this sample ruleset uses
# require-order to permit mixing of NAT/RDR and filter rules.
# Remember to set net.inet.ip.forwarding=1 and/or net.inet6.ip6.forwarding=1
# in /etc/sysctl.conf if packets are to be forwarded between interfaces.
###macros
ext_if="ste0"
int_if="vr0"
web_if="ste1"
icmp_types="echoreq"
tcp_port="{ 5000 2028 ftp smtp ftp-data pop3 auth nntp ntp domain 995 587 465 }"
udp_port="{ domain }"
ip_web_server="10.0.0.2"
ip_web_safe="{ xxx.xxx.xxx.xx xxx.xxx.xxx.xx xxx.xxx.xxx.xxx }"
ip_allow_ssh="xx.xx.xx.xx"
#ip_public_admin=""
ip_lan_admin="192.168.0.2"
ip_dns_server="{ xxx.xxx.x.xx xxx.xxx.x.xxx }"
localnet="vr0:network"
cvs_ca="xxx.xxx.xx.xx"
###options
set loginterface $ext_if
set skip on lo0
###match rule
match out on $ext_if inet from !$ext_if to any nat-to $ext_if:0
###cbq
altq on $ext_if cbq bandwidth 2Mb queue { std, https, ssh, http }
queue std bandwidth 20% cbq(default)
queue https bandwidth 10% cbq(borrow)
queue ssh bandwidth 25% { ssh_login, ssh_bulk }
queue ssh_login bandwidth 25% priority 4 cbq(borrow ecn)
queue ssh_bulk bandwidth 75% cbq(borrow ecn)
queue http bandwidth 45% priority 3 cbq(borrow red)
######filter rule
block quick inet6 all
table <terlarang> persist file "/etc/terlarang"
block in quick on $ext_if from <terlarang>
table <https> persist file "/etc/https"
antispoof quick for { lo $int_if $web_if }
block all
block log (all) proto tcp all
###ftp proxy
anchor "ftp-proxy/*"
pass in on $int_if inet proto tcp to any port ftp rdr-to 127.0.0.1 port 8021
#pass in on $web_if inet proto tcp to any port ftp rdr-to 127.0.0.1 port 8021
###$ext_if
pass out on $ext_if inet proto tcp to port $tcp_port
pass out on $ext_if inet proto tcp to $cvs_ca port ssh
pass out on $ext_if inet proto tcp to port http
pass out on $ext_if inet proto tcp to <https> port https queue https
pass out on $ext_if inet proto udp from any to $ip_dns_server port $udp_port
pass out on $ext_if inet proto udp from any to port ntp
table <abusive_hosts> persist
block in quick from <abusive_hosts>
pass in log (all) on $ext_if inet proto tcp from any to $ext_if port 80 \
rdr-to $ip_web_server port 80 \
queue http \
flags S/SA synproxy state \
(max-src-conn 100, max-src-conn-rate 15/5, overload <abusive_hosts> flush)
pass in log (all) on $ext_if inet proto tcp from $ip_allow_ssh to $ext_if port 22 \
rdr-to $ip_web_server port 22 \
queue (ssh_bulk, ssh_login) \
flags S/SA synproxy state \
(max-src-conn 100, max-src-conn-rate 15/5, overload <abusive_hosts> flush)
#pass in log (all) on $ext_if inet proto tcp from $ip_public_admin to $ext_if \
# port 22 flags S/SA synproxy state \
# (max-src-conn 100, max-src-conn-rate 15/5, overload <abusive_hosts> flush) \
# queue ssh
#pass out inet proto icmp all
#pass in inet proto icmp all icmp-type $icmp_types keep state
###altq pada $web_if
altq on $web_if cbq bandwidth 100Mb queue { std_dmz, ssh_dmz, http_dmz, http_dmz_to_net }
queue std_dmz bandwidth 89% cbq(default borrow)
queue ssh_dmz bandwidth 500Kb priority 2 cbq(borrow ecn)
queue http_dmz bandwidth 900Kb priority 3 cbq(borrow red)
queue http_dmz_to_net bandwidth 50Kb priority 2 cbq(borrow red)
###$web_if
pass out on $web_if proto tcp from any to $ip_web_server port 80 queue http_dmz
pass out on $web_if proto tcp from $localnet to $ip_web_server port 80
pass out on $web_if proto tcp from { $ip_lan_admin $ip_allow_ssh } \
to $ip_web_server port 22 \
queue ssh_dmz
pass in on $web_if proto tcp from $ip_web_server to $web_if port { 25, ntp }
pass in on $web_if proto udp from $ip_web_server to $web_if port { 53, ntp }
pass in on $web_if proto tcp from $ip_web_server to $ip_web_safe queue http_dmz_to_net
###altq pada $int_if
altq on $int_if cbq bandwidth 100Mb queue { std_int_to_net, int_to_https, ssh_int, http_int }
queue std_int_to_net bandwidth 350Kb cbq(default)
queue int_to_https bandwidth 200Kb cbq(borrow red)
queue ssh_int bandwidth 10%
queue http_int bandwidth 89% cbq(red)
###$int_if
pass in quick on $int_if proto tcp from $localnet to $ext_if port 80 \
rdr-to $ip_web_server port 80 \
queue http_int \
flags S/SA synproxy state \
(max-src-conn 100, max-src-conn-rate 15/5, overload <abusive_hosts> flush)
pass in quick on $int_if proto tcp from $localnet to any port 80 rdr-to lo0 port 3128
pass in on $int_if proto tcp from $localnet to any port $tcp_port
pass in on $int_if proto tcp from $localnet to <https> port https queue int_to_https
pass in on $int_if proto udp from $localnet to any port $udp_port
pass in on $int_if proto tcp from $ip_lan_admin to \
{ $int_if $ip_web_server } port 22 \
queue ssh_int
pass in on $int_if proto tcp from $ip_lan_admin to $cvs_ca port 22
block out on $int_if
keterangan:
konfigurasi pf di atas untuk skema jaringan seperti ini
localnet----------vr0--firewall--ste0-----internet
|
ste1
|
|
|
webserver
PF diatas dirancang sebagai ikhtiar untuk mencegah serangan attacker, walaupun begitu,
kita tidak lupa berdoa kepada Allah, agar webserver kita selamat, dan kita tetap
bertawakkal kepada Allah. Diantara serangan yang, Insya Allah, bisa dicegah adalah:
1. ping boms
icmp dinonaktifkan, sehingga tidak bisa ip luar memping atau ip dari dalam memping keluar.
2. syn attack
penggunaan keyword synproxy state berfungsi untuk mencegah syn attack, sehingga setiap
paket syn yang masuk, tidak langsung dikirim ke webserver, tapi firewall yang melakukan
validasi koneksi, yaitu mengirim syn+ack dan menunggu ack. Bila client telah menuntaskan
validasi koneksi ini, firewall akan meneruskan koneksi ke webserver.
3. http attack
serangan pada http server ini sangat berbahaya, dan merupakan jenis Denial of Service
(DOS). Disini kita membatasi koneksi client dengan keyword
(max-src-conn 100, max-src-conn-rate 15/5, overload flush) yang bermakna
satu ip client hanya bisa melakukan 100 koneksi, dan tiap waktu 5 detik, hanya bisa
15 koneksi. Bila suatu IP client melanggar batasan, akan dimasukkan kedalam table
abusive_hosts yang akan di block imcoming paket dari IP tersebut dan di flush koneksinya
dari table state.
tapi setiap satu jam, saya menjalankan script dengan cron untuk mendelete IP yang telah
berumur 1 jam dari table abusive_hosts, dengan ini bila terjadi ketidaksengajaan
dari user valid, maka dengan menunggu paling lama 2 jam, IP nya bisa melakukan koneksi lagi.
4. reverse telnet
serangan yang sangat terkenal, untuk mencegah serangan ini, maka webserver dirancang
hanya bisa menerima koneksi dari luar dan TIDAK BISA MEMULAI koneksi ke luar, KECUALI
menuju IP yang telah di definisikan dalam macro $ip_web_safe.
PENJELASAN BARIS CONFIGURASI
Saya menggunakan macro untuk setting diatas, sehingga diharapkan akan mudah untuk
di aplikasikan pada firewall OpenBSD dengan tinggal mengganti variable di macro tersebut.
ext_if="ste0"
int_if="vr0"
web_if="ste1"
ini adalah interface yang digunakan pada firewall dengan IP yang digunakan
vr0=192.168.01
ste1=10.0.0.1
ste0=IP_Publik situs
webserver mempunyai IP 10.0.0.2, dan setiap akses ke port 80 ke IP_Publik akan kita redirect ke 10.0.0.2 port 80
LAN dengan IP 192.168.0.0/24 kecuali 192.168.0.1
icmp_types="echoreq"
tcp_port="{ 5000 2028 ftp smtp ftp-data pop3 auth nntp ntp domain 995 587 465 }"
udp_port="{ domain }"
icmp_types ini adalah type icmp yang boleh masuk bila protokol icmp di aktifkan. Saat
ini saya tidak mengaktifkannya (diberi tanda komentar #)
UDP dan TCP port yang boleh keluar masuk secara umum
ip_web_server="10.0.0.2"
ip_web_safe="{ xxx.xxx.xxx.xxx xxx.xxx.xxx.xx xxx.xx.xxx.xxx }"
ip_allow_ssh="xxx.xx.xxx.xxx"
#ip_public_admin=""
ip_lan_admin="192.168.0.2"
ip_dns_server="{ xxx.xxx.x.xx xxx.xxx.x.xxx }"
localnet="vr0:network"
cvs_ca="xxx.xxx.xx.xx"
ini adalah makro IP. IP webserver 10.0.0.2
ip_web_safe adalah IP, yang webserver, bisa memulai koneksi, untuk terhubung kepadanya. selain IP ini,
webserver tidak bisa melakukan koneksi ke internet dan hanya menerima koneksi.
ip_allow_ssh adalah IP publik internet yang bisa ssh ke webserver. Ini harus sangat dibatasi
sehingga tidak semua IP bisa ssh. ssh ini diredirect ke webserver, bukan ke firewall.
ip_public_admin adalah IP publik yang admin bisa gunakan untuk ssh ke firewall,
tapi kita nonaktifkan saja, dan tidak diaktifkan kecuali sangat terpaksa. Sebagai admin,
kita harusnya login dari LAN saja.
ip_lan_admin adalah IP LAN yang bisa ssh ke firewall dan server
set loginterface $ext_if
set skip on lo0
ini adalah option yang digunakan pada pf
loginterface adalah interface yang kita melakukan log pada tiap data yang
keluar masuk disitu
skip on lo0 berarti pf tidak memfilter interface local yaitu lo0
match out on $ext_if inet from !$ext_if to any nat-to $ext_if:0
ini berarti bahwa setiap paket yang berasal dari IP localnet dan IP
webserver, bila ia akan melakukan koneksi keluar, maka IP tersebut
di NAT dengan IP Publik gateway
tanda !$ext_if berarti selain IP publik gateway yaitu IP localnet
dan IP webserver.
tanda 0 pada $ext_if:0, berarti hanya ke IP utama di NAT kan, jangan
ke IP alias pada interface Publik Gateway.
catatan:
sebenarnya disini, tampaknya boleh menambahkan scrub (sanitasi paket)
yaitu dengan cara
match in all scrub (no-df)
atau
match in all scrub (no-df max-mss 1440)
namun saya pribadi tidak menambahkannya
altq on $ext_if cbq bandwidth 2Mb queue { std, https, ssh, http }
queue std bandwidth 20% cbq(default)
queue https bandwidth 10% cbq(borrow)
queue ssh bandwidth 25% { ssh_login, ssh_bulk }
queue ssh_login bandwidth 25% priority 4 cbq(borrow ecn)
queue ssh_bulk bandwidth 75% cbq(borrow ecn)
queue http bandwidth 45% priority 3 cbq(borrow red)
Iya, ini adalah bandwith manajemen, yang mengatur pemakaian bandwith.
disini saya sampaikan bahwa pembatasan bandwith itu adalah saat gateway
kita mengirim paket keluar (out), adapun bila paket telah tiba di interface
gateway, maka pembatasan sudah terlambat… karena paket tersebut telah
memakan bandwith yang menyampaikan ia ke interface kita. Saya, bila masih
ada kesempatan, akan menulis secara spesial masalah bandwith ini. Di sini
saya hanya menjelaskan maksud konfigurasi saja.
konfigurasi diatas bertujuan:
1. bandwith total yang ada di interface $ext_if 2 Mega bit
2. koneksi standar akan dapat 20% dari 2 Mega bit, yaitu 400 Kilo bit
3. untuk koneksi ke port 22 dapat spesial bandwith 25%, yautu 500 Kilo bit
4. untuk koneksi ke port 80 di webserver dapat spesial bandwith 45%,
yaitu 900 Kilo bit