The FreeBSD Gateway - PF
This is an example of FreeBSD Internet Gateway with firewall, port forwarding and transparent proxy.
Install FreeBSD without x-server, games and packages.
Configure network interfaces and turn on ssh.
Enable PF in rc.conf:
pf_enable="YES"
pf_program="/sbin/pfctl"
pf_flags=""
pf_rules="/etc/pf.conf"
pflog_enable="YES"
pflog_logfile="/var/log/pf.log"
plog_program="/sbin/pflogd"
pflog_flags=""
Reboot system:
# shutdown -r now
Check PF:
# pfctl -sa
Configure Caching DNS server.
# ee /etc/namedb/named.conf
...
# Forward external DNS queryes to your provider DNS servers
forwarders {
135.11.0.77;
135.11.127.77;
};
...
query-source address * port 53;
...
Add named into rc.conf:
named_enable="YES"
named_flags="-u bind"
# ee /etc/resolv.conf
domain domain.ru
search domain.ru
nameserver 127.0.0.1
# /etc/rc.d/named restart
Configure proxy server Squid.
# cd /usr/ports/www/squid
# make install clean
# mcedit /usr/local/etc/squid/squid.conf
acl all src all
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
acl localnet src 192.168.0.0/24 # RFC1918 possible internal network
acl Safe_ports port 80 # http
acl CONNECT method CONNECT
acl flv urlpath_regex -i \.flv$
acl mov urlpath_regex -i \.mov$
acl mp3 urlpath_regex -i \.mp3$
acl wav urlpath_regex -i \.wav$
acl ogg urlpath_regex -i \.ogg$
acl asf urlpath_regex -i \.asf$
acl avi urlpath_regex -i \.avi$
acl mpeg urlpath_regex -i \.mpeg$
acl inet_full src "/usr/local/etc/squid/inet_full"
acl deny_domains dstdomain "/usr/local/etc/squid/deny_domains"
acl work_time time MTWHF 10:00-18:00
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access allow inet_full
http_access deny work_time deny_domains
http_access deny avi
http_access deny wav
http_access deny mp3
http_access deny mpeg
http_access deny flv
http_access deny mov
http_access deny ogg
http_access deny asf
http_access allow localnet
http_access deny all
icp_access allow localnet
icp_access deny all
http_port 3128
http_port 3129 transparent
hierarchy_stoplist cgi-bin ?
access_log /squid/logs/access.log squid
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
acl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]
upgrade_http0.9 deny shoutcast
acl apache rep_header Server ^Apache
broken_vary_encoding allow apache
cache_mem 256 MB
cache_dir ufs /squid/cache 51200 64 512
I restricted multimedia content and sites from file deny_domains at work time.
# chown -R squid:squid /squid
# squid -z
# ee /etc/rc.conf
...
squid_enable="YES"
# /usr/local/etc/rc.d/squid start
# ps -waux | grep squid
squid 854 0,0 0,2 7060 2424 ?? Is 18:50 0:00,00 /usr/local/sbin/squid -D
squid 943 0,0 30,5 320404 314888 ?? S 18:50 2:24,12 (squid) -D (squid)
squid 944 0,0 0,1 1376 604 ?? Ss 18:50 0:00,94 (unlinkd) (unlinkd)
squid 945 0,0 0,1 3308 928 ?? Ss 18:50 0:06,90 (pinger) (pinger)
I have a range of external ip adresses, so I need to configure aliases:
# ee /etc/rc.conf
defaultrouter="135.61.11.222"
gateway_enable="YES"
hostname="bsd"
ifconfig_em0="inet 192.168.0.1 netmask 255.255.254.0"
ifconfig_em1="inet 135.61.11.223 netmask 255.255.255.240"
ifconfig_em1_alias0="inet 135.61.11.224 netmask 255.255.255.240"
ifconfig_em1_alias1="inet 135.61.11.225 netmask 255.255.255.240"
ifconfig_em1_alias2="inet 135.61.11.226 netmask 255.255.255.240"
.....
Write PF configuration file:
# ee /etc/pf.conf
# pf.conf
# Written By Alexander Lipovetskiy at 20.03.2009
# http://ithouse.spb.ru/
#################################################################
#################################################################
# Options
#################################################################
# Interfaces
ext_if = "em1"
int_if = "em0"
# IP
extnet = "135.61.11.222/28"
lannet = "192.168.0.0/24"
ext_ip = "135.61.24.223/32"
ext_ip_bserv = "135.61.11.225/32"
ext_ip_963 = "135.61.11.226/32"
ext_ip_pbx = "135.61.11.227/32"
bsd = "192.168.0.1/32"
mail = "192.168.0.100/32"
dc = "192.168.0.2/32"
pbx = "192.168.0.3/32"
serv1 = "192.168.0.4/32"
serv2 = "192.168.0.5/32"
terminal = "192.168.0.6/32"
root = "192.168.0.10/32"
serv3 = "192.168.0.7/32"
friends = "{ XXX, XXX }"
private_nets= "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"
# Ports
client_ports = "{ 21, 22, 25, 110, 123, 80, 443, 3128, 3129, 3389,8080, >=49151 }"
admin_ports = "{ 5190, 33330:33340 }"
pbx_udp = "{ 2727, 4520, 4569, 5036, 5060, 10000:20000 }"
pbx_tcp = "{ 5060 }"
#------------------------------
# Normalization
#------------------------------
set block-policy drop
set state-policy floating
set loginterface $ext_if
set limit { frags 100000, states 100000 }
set optimization normal
set skip on lo0
scrub in all
#------------------------------
# NAT & RDR
#------------------------------
# BiNAT for Asterisk
binat on $ext_if inet from $pbx to any -> $ext_ip_pbx
# NAT for local net
nat on $ext_if inet from $lannet to any -> $ext_ip
# Transparent proxy forwarding
rdr on $int_if proto tcp from $lannet to any port www -> 127.0.0.1 port 3129
# Asterisk port forwarding
rdr on $ext_if from any to $ext_ip_pbx -> $pbx
# Web serve port forwarding
rdr on $ext_if proto tcp from any to $ext_ip_bserv port www -> $bserv
# Mail server port forwarding - smtp
rdr on $ext_if proto tcp from any to $ext_ip port smtp -> $mail
# Mail server port forwarding - pop3
rdr on $ext_if proto tcp from $friends to $ext_ip port pop3 -> $mail
# Mail server port forwarding - webamil
rdr on $ext_if proto tcp from any to $ext_ip port https -> $mail
# Windows RDP forwarding
rdr on $ext_if proto tcp from any to $ext_ip port rdp -> $terminal
# SSH
rdr on $ext_if proto tcp from any to $ext_ip port 33330 -> $mail port 22
rdr on $ext_if proto tcp from any to $ext_ip port 33331 -> $pbx port 22
rdr on $ext_if proto tcp from any to $ext_ip port 33332 -> $dc port 22
rdr on $ext_if proto tcp from any to $ext_ip port 33333 -> $serv1 port 22
rdr on $ext_if proto tcp from any to $ext_ip port 33334 -> $serv2 port 22
rdr on $ext_if proto tcp from any to $ext_ip port 33335 -> $pdc port 22
#------------------------------
# Filtration rules
#------------------------------
# Spoofing protection
antispoof quick for { lo0, $int_if, $ext_if }
# Block all
block log all
# Block privete ip
block drop in quick on $ext_if from $private_nets to any
# Allow icmp types
pass inet proto icmp icmp-type echoreq
# Allow DNS from local net
pass in on $int_if proto udp from $lannet to $bsd port domain
# Allow NTP from local net
pass in on $int_if proto udp from $lannet to $bsd port ntp
# It's for temporary test
#pass in on $int_if from $lannet to any
# Allow Asterisk output
pass in on $int_if from $pbx to any
# Allow Mail server output
pass in on $int_if proto tcp from $mail to any port smtp
# Allow Admin output
pass in on $int_if proto tcp from $root to any port $admin_ports
# Allow user output
pass in on $int_if proto tcp from $lannet to any port $client_ports
# Full output access for our gateway
pass out on $ext_if proto tcp from any to any
pass out on $ext_if proto udp from any to any keep state
pass out on $int_if proto tcp from any to any
pass out on $int_if proto udp from any to any keep state
#------------------------------
# Icoming #
# Allow incoming ssh
pass in log on $ext_if proto tcp from any to $ext_ip port 33339 flags S/SA synproxy state
pass in log on $ext_if proto tcp from any to $mail port 22 flags S/SA synproxy state
pass in log on $ext_if proto tcp from any to $pbx port 22 flags S/SA synproxy state
pass in log on $ext_if proto tcp from any to $dc port 22 flags S/SA synproxy state
pass in log on $ext_if proto tcp from any to $serv1 port 22 flags S/SA synproxy state
pass in log on $ext_if proto tcp from any to $serv2 port 22 flags S/SA synproxy state
# # Allow incoming smtp
pass in on $ext_if proto tcp from any to $mail port smtp flags S/SA synproxy state
# Allow incoming https
pass in on $ext_if proto tcp from any to $mail port https flags S/SA synproxy state
# Allow incoming http
pass in on $ext_if proto tcp from any to $ext_ip port www flags S/SA synproxy state
# Allow incoming ftp
pass in on $ext_if proto tcp from any to $ext_ip port ftp flags S/SA synproxy state
# Allow incoming pop3
pass in on $ext_if proto tcp from $friends to $mail port pop3 flags S/SA synproxy state
# Allow incoming rdp
pass in log on $ext_if proto tcp from $friends to $terminal port rdp flags S/SA synproxy state
# Allow incoming Asterisk services
pass in on $ext_if proto tcp from any to $pbx port $pbx_tcp flags S/SA synproxy state
pass in on $ext_if proto udp from any to $pbx port $pbx_udp keep state
Check rules before load it:
# pfctl -nf /etc/pf.conf
Load rules if all is ok:
# pfctl -f /etc/pf.conf
# pfctl -sn
# pfctl -sr
# pfctl -si
# pfctl -sa
