# example pf.conf for any use. caution, this ruleset is based on one # which actually was working at some point, however it has been "sanitized" # and otherwise modified to reflect newer features in the OpenBSD pf facility. # untested in this form. # # --- MACROS --- # # external uplink. note that since this IP address is "hard coded" into the # rules here, if the cable company gives me a new IP addy this will have to # be changed by hand before things work again. ext_if = "we1" ext_ip = "24.213.45.249" # internal protected network ipn_if = "we0" ipn_ip = "172.26.59.1" ip_net = "172.26.59.0/24" # private service network ("DMZ") psn_if = "we2" psn_ip = "172.26.58.1" ps_net = "172.26.58.0/24" psn_OK = "172.26.58.19" # a "trusted" host in the DMZ # my entire internal network f301net = "172.26.58.0/23" # 4 external addresses i consider to be trusted and secure extern_allow = "141.219.152.222/31 141.219.152.226/31" snappy_ip = "172.26.59.42" cobble_ip = "172.26.59.41" psn_http_host = "172.26.58.19" # strange looking port number no one will ever think to scan too closely. screwy_http = "12345" screwy_https = "22345" screwy_ssh_2 = "13245" screwy_ssh_3 = "12435" charterDHCP = "10.64.88.1" charterDNS = " \ 24.213.60.84 \ 24.213.60.68 \ " charter_allow = " \ 10.64.88.1 \ 24.213.60.68 \ 24.213.60.84 \ " all_SERVICES = " \ 10.64.88.1 \ 24.213.60.68 \ 24.213.60.84 \ 141.219.152.253 \ 141.219.152.254 \ " non_routable = "10.0.0.0/8 172.16.0.0/12 192.168.0.0/16" cast_addresses = "255.255.255.255 224.0.0.0/3" web_ports = "80 443 8888" screwy_ssh_ports = "13245 12435" psn_web_server = "172.26.58.19" web_hosts_allow = " \ 172.26.59.0/24 \ 141.219.152.223 \ " intern_allow_to = " \ 172.26.59.41 \ 172.26.59.42 \ " # # --- OPTIONS --- # # packets droped on the floor result in port scanners calling the # ports "filtered" (e.g. nmap). a policy of "return" sends an RST # back to originating TCP connections, or an ICMP UNREACHABLE back # to originating UDP connections; this results in a port scan listing # the port as "closed" e.g. nothing LISTENing on that port. set block-policy drop # # --- TRAFFIC NORMALIZATION --- # # reassembly of fragmented packets, overlaping packets, etc. scrub in on $ext_if all # # --- QUEUEING --- # # queueing (QoS "traffic hsaping") rules would go here. # # --- TRANSLATION --- # # provide for ftp-proxy rdr on $ipn_if proto tcp from $ip_net to ! $ip_net port 21 -> 127.0.0.1 port 8081 rdr on $psn_if proto tcp from $ps_net to ! $ps_net port 21 -> 127.0.0.1 port 8081 # provide external access to http, https rdr on $ext_if proto tcp from { $extern_allow } to $ext_ip port $screwy_http -> $psn_http_host port 80 rdr on $ext_if proto tcp from { $extern_allow } to $ext_ip port $screwy_https -> $psn_http_host port 443 # screwy rdrs for ssh rdr on $ext_if proto tcp from { $extern_allow } to $ext_ip port $screwy_ssh_2 -> $snappy_ip port 22 rdr on $ext_if proto tcp from { $extern_allow } to $ext_ip port $screwy_ssh_3 -> $cobble_ip port 22 # the NAT nat on $ext_if from $f301net to any -> ($ext_if) # # --- FILTERING --- # # note on "direction": "in" means going IN from the network toward the kernel; # "out" means going from the kernel OUT to the network. # # LOOPBACK interface # antispoof for lo0 pass in quick on lo0 pass out quick on lo0 # # EXTERNAL interface: $ext_if and $ext_ip # antispoof for $ext_if inet # default block on external interface block out log on $ext_if all block in log on $ext_if all block in log on $ext_if from { $non_routable } to any block in quick on $ext_if from any to { $cast_addresses } block out log quick on $ext_if from any to { $cast_addresses } # check for odious "fingerprinting" scans block in log quick on $ext_if proto tcp from any to any flags SF/SF block in log quick on $ext_if proto tcp from any to any flags /SFRA block in log quick on $ext_if proto tcp from any to any flags FUP/FUP # filter external noise (don't log useless information) block in quick on $ext_if proto igmp from any to any block in quick on $ext_if proto { tcp udp } from any port 67 to any port 68 block in quick on $ext_if proto tcp from any to any port 445 block in quick on $ext_if proto tcp from any to any port 1433 # this is a separate set of rules for the FW host itself pass in on $ext_if inet from { $charter_allow } to $ext_ip pass out quick on $ext_if inet proto tcp from $ext_ip to any keep state pass out quick on $ext_if inet proto udp from $ext_ip to any keep state # ICMP pass out on $ext_if inet proto icmp all icmp-type 8 code 0 keep state pass in on $ext_if inet proto icmp all icmp-type 8 code 0 keep state # maintain dhcp and dns services pass in on $ext_if inet from { $all_SERVICES } to $f301net # allow normal user traffic out and keep state on it pass out on $ext_if proto tcp from $f301net to any keep state pass out on $ext_if proto udp from $f301net to any keep state # allow in to psn web server pass in on $ext_if proto tcp from { $web_hosts_allow } \ to $psn_web_server port { $web_ports } keep state # allow SSH in for selected external hosts pass in on $ext_if proto tcp from { $extern_allow } \ to $ip_net port ssh keep state # # INTERNAL PROTECTED interface: $ipn_if, $ipn_ip and $ip_net # antispoof for $ipn_if inet # default block-and-log is overridden by rules below it block in log on $ipn_if block out log on $ipn_if # let the GW itself go through pass out quick on $ipn_if from $ipn_ip to $ip_net # ICMP pass out on $ipn_if inet proto icmp all icmp-type 8 code 0 keep state pass in on $ipn_if inet proto icmp all icmp-type 8 code 0 keep state # allow normal user traffic out and keep state on it pass in on $ipn_if proto tcp from $ip_net to any keep state pass in on $ipn_if proto udp from $ip_net to any keep state # allow selected external SSH connections pass out on $ipn_if proto tcp from { $extern_allow } \ to { $intern_allow_to } port ssh keep state # allow traffic from DMZ bastion host in ps_net pass out on $ipn_if proto tcp from { $psn_OK } to $ip_net keep state #pass out on $ipn_if proto udp from { $psn_OK } to $ip_net keep state # # PRIVATE SERVICE interface (DMZ): $psn_if, $psn_ip and $ps_net # antispoof for $psn_if inet block in log on $psn_if block out log on $psn_if # let the GW itself through pass out quick on $psn_if from $psn_ip to $ps_net # ICMP pass out on $psn_if inet proto icmp all icmp-type 8 code 0 keep state pass in on $psn_if inet proto icmp all icmp-type 8 code 0 keep state # HTTP/HTTPS # filter http and https for server(s) inside the DMZ; # only allow from IPN until ready for secure external access. block out log on $psn_if proto tcp from any to any port { $web_ports } pass out quick on $psn_if proto tcp from { $web_hosts_allow } \ to $psn_web_server port { $web_ports } keep state # connections to ipn originating from psn # allow normal user traffic out and keep state on it pass in quick on $psn_if proto tcp from { $psn_OK } to $ip_net keep state pass in quick on $psn_if proto udp from { $psn_OK } to $ip_net keep state # connections to psn originating from ipn pass out quick on $psn_if proto tcp from $ip_net to any keep state pass out quick on $psn_if proto udp from $ip_net to any keep state # # --- EOF ---