Hi folks, if it is allowed to ask a question about packet filter here?
Please take a look at the attached pf.conf file. Problem is that incoming traffic from a host in (internal:network) to an external host port is passed in rule 86 (thats one of the debproxy lines) pass $log0 quick proto tcp from (internal:network) to $debproxy port $debproxy_port but then its blocked for outgoing in the default rule 0. # tcpdump -envi pflog0 host 172.19.96.126 tcpdump: WARNING: snaplen raised from 116 to 160 tcpdump: listening on pflog0, link-type PFLOG 13:19:46.286235 rule 86/(match) [uid 0, pid 10501] pass in on em1: 10.150.1.32.37024 > 172.19.96.126.3142: S [tcp sum ok] 1742174933:1742174933(0) win 64240 <mss 1460,sackOK,timestamp 2504651158 0,nop,wscale 7> (DF) (ttl 64, id 58124, len 60) 13:19:46.286263 rule 0/(match) [uid 0, pid 10501] block out on em0: 10.150.1.32.37024 > 172.19.96.126.3142: S [tcp sum ok] 1742174933:1742174933(0) win 64240 <mss 1460,sackOK,timestamp 1896845108 0,nop,wscale 7> (DF) (ttl 63, id 47021, len 60, bad ip cksum 3f68! -> 6bc7) ^C 294 packets received by filter 0 packets dropped by kernel Rule 86 explicitly says "pass quick", not "pass in quick". The tcpdump line shows that the outgoing packet is still filtered using the IP address bound to (internal:network) as for the incoming packet. How comes that this rule 86 is not applied for the outgoing packet? The workaround is to add a tag in rule 86 and to add a line pass out quick tagged ALLOWED But thats ugly. Every insightful comment is highly appreciated Harri
# # gate6a/b firewall configuration # # to watch pf at work use 'tcpdump -nettt -i pflog0' # to check the rule numbers use 'pfctl -gsr | grep ^@' # to check built in tables use something like # # pfctl -a _pf -s Tables # pfctl -a _pf -t self -T show # pfctl -a _pf -t internal:network -T show # # The groups are assigned in /etc/hostname.$ifname. There are also a # few predefined groups, depending on the interface type, see ifconfig(8). # Here is a list, as used in this pf config file # # egress: the interface with the default gateway # external: the interface to access the internet # public: public IP address range to access the containers # internal: local IP address range to access the nodes # switches: local IP address range to access the switches and idracs # dblan: local IP address range to access the databases # # external, public, internal, switches and dblan are mutually exclusive # # special groups: # # carpdev: interface running carp protocol # pfsyncdev: interface running pfsync protocol # carp: interface *is* a carp interface # # Please keep this list up to date. # ========================================================================== # macros for logging # ========================================================================== # we surely need some policy for logging. How about this: log0 = "log (to pflog0)" # "regular" traffic (passed or blocked)" log1 = "log (to pflog1)" # traffic to or from public network log2 = "log (to pflog2)" # unused log3 = "log (to pflog3)" # exclusively for spamlogd (unused) logd = "log (to pflog0)" # verbose # logd = "" # ========================================================================== # runtime options # ========================================================================== set block-policy return # default: drop set fingerprints "/etc/pf.os" # /etc/pf.os set limit states 100000 # default: 100000 set limit tables 1000 # default: 1000 set limit table-entries 200000 # default: 200000 set limit frags 65536 # default: platform dependent set limit src-nodes 10000 # default: unknown set loginterface egress # default: none set optimization normal # default: normal set reassemble yes # default: yes set ruleset-optimization basic # default: basic set skip on { lo } # set state-defaults ... # set state-policy if-bound # default: floating set syncookies never # default: never set timeout udp.first 240 # default: 60 set timeout udp.single 120 # defualt: 30 set timeout udp.multiple 240 # default: 60 # ========================================================================== # IP addresses and ports # ========================================================================== ssh_port = "{ ssh 1023 }" http_port = "{ http https }" smtp_host = "{ 10.150.1.1 }" smtp_port = "{ smtp }" debproxy = "{ 172.19.96.126 10.150.1.32 }" debproxy_port = 3142 dns_host = "any" ntp_host = "any" oracle_port = "{ 1521 }" zabbix_agent = 10050 # Zabbix Agent port zabbix_trapper = 10051 # Zabbix Server port # ========================================================================== # tables # ========================================================================== table <unroutable> const persist { 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 2001:DB8::/32 } table <aixigo> const persist { not shown here } table <aixigo_lan> const persist { 172.19.96.0/20 } table <zabbix_server> const persist { not shown here } table <zabbix_proxy> const persist { not shown here } # ========================================================================== # default # ========================================================================== block $logd all block return-rst quick proto tcp all flags /S block return-rst quick proto tcp all flags A/A block in $logd quick from no-route to any block in $logd quick from urpf-failed to any block in $logd quick from any to 255.255.255.255 block in $logd quick from 255.255.255.255/32 to any # # disabled temporarily: # block in $logd quick on external from <unroutable> to any # block out $logd quick on external from any to <unroutable> # antispoof_if = "{ lo external public internal switches dblan pfsyncdev }" antispoof quick for $antispoof_if # public network traffic is logged on pflog1 by default block $log1 from (public:network) block $log0 to (public:network) # ========================================================================== # normalisation # ========================================================================== # no-df: clear the don't fragment bit, needed for NFS # random-id: replace the IP identification field by a random value, recommended for no-df # reassemble tcp: Statefully normalises TCP connections (TTL, timestamp, PAWS) match in all scrub (random-id reassemble tcp) # ========================================================================== # nat and rdr for IPv4 # ========================================================================== match out on external inet from (internal:network) to any nat-to (carp0:0) match out on external inet from (switches:network) to any nat-to (carp0:0) match out on external inet from (dblan:network) to any nat-to (carp0:0) # ========================================================================== # carp and pfsync # ========================================================================== pass quick on carpdev proto carp pass quick on pfsyncdev proto pfsync # ========================================================================== # ICMP and ICMP6 traffic # ========================================================================== icmp_types_ext = "{ echoreq unreach }" icmp6_types_ext = "{ echoreq unreach timex paramprob neighbrsol neighbradv }" pass in quick inet proto icmp icmp-type $icmp_types_ext pass in quick on ! external inet proto icmp pass out quick inet proto icmp pass in quick inet6 proto icmp6 icmp6-type $icmp6_types_ext pass in quick on ! external inet6 proto icmp6 pass out quick inet6 proto icmp6 # ========================================================================== # traceroute # ========================================================================== pass quick proto udp from (internal:network) to any port 33433 >< 33626 # ========================================================================== # access to and from this host ("self" rules) # # Please note that destination NAT (e.g. port forwarding) is processed # first, i.e. if there is some NAT involved for an incoming package, then we # see the new destination address here, which is usually not included in # (self). The rules for this case can be found in the subnets section below. # # OTOH, source NAT (aka "NAT") is done first, too. In this case, outgoing # traffic *is* mapped to an address in (self). So we cannot blindly block # all outgoing traffic coming from (self), only the traffic that is not # natted. # # better use IPv6 instead of NAT # ========================================================================== pass in $log0 quick proto tcp from <aixigo> to (self) port { 1023 ssh } pass in $log0 quick proto tcp from <aixigo_lan> to (self) port { 1023 ssh } pass in $log0 quick proto tcp from (internal:network) to (self) port { 1023 ssh } pass out $logd quick proto udp from (self) to $ntp_host port ntp pass out $log0 quick proto { tcp udp } from (self) to any port $http_port pass out $log0 quick proto { tcp udp } from (self) to $dns_host port domain pass in $logd quick proto tcp from <zabbix_proxy> to (self) port $zabbix_agent pass out $logd quick proto tcp from (self) to <zabbix_proxy> port $zabbix_trapper block in $log0 quick from any to (self) # ========================================================================== # access between local subnets and the rest of the world # ========================================================================== pass $log0 quick proto { tcp udp } from (internal:network) to $dns_host port domain pass $log0 quick proto { tcp udp } from (internal:network) to $ntp_host port ntp pass $log0 quick proto tcp from (internal:network) to $smtp_host port $smtp_port pass $log0 quick proto { tcp udp } from (internal:network) to any port $http_port pass $log0 quick proto tcp from (internal:network) to (switches:network) port $ssh_port pass $log0 quick proto tcp from (internal:network) to (switches:network) port $http_port pass $log0 quick proto tcp from (internal:network) to (dblan:network) port $ssh_port pass $log0 quick proto tcp from (internal:network) to (dblan:network) port $http_port pass $log0 quick proto tcp from (internal:network) to $debproxy port $debproxy_port pass $log1 quick proto { tcp udp } from (public:network) to $dns_host port domain pass $log1 quick proto { tcp udp } from (public:network) to $ntp_host port ntp pass $log1 quick proto tcp from (public:network) to $smtp_host port $smtp_port pass $log0 quick proto tcp from (public:network) to $debproxy port $debproxy_port pass $log0 quick proto { tcp udp } from (switches:network) to $dns_host port domain pass $log0 quick proto { tcp udp } from (switches:network) to $ntp_host port ntp pass $log0 quick proto tcp from (switches:network) to $smtp_host port $smtp_port pass $log0 quick proto { tcp udp } from (dblan:network) to $dns_host port domain pass $log0 quick proto { tcp udp } from (dblan:network) to $ntp_host port ntp pass $log0 quick proto tcp from (dblan:network) to $smtp_host port $smtp_port pass $log0 quick proto tcp from (dblan:network) to $debproxy port $debproxy_port pass $log0 quick proto tcp from <aixigo_lan> to (internal:network) port $ssh_port pass $log0 quick proto tcp from <aixigo_lan> to (internal:network) port $http_port pass $log1 quick proto tcp from <aixigo> to (public:network) port $ssh_port pass $log1 quick proto tcp from <aixigo> to (public:network) port $http_port pass $log0 quick proto tcp from <aixigo_lan> to (switches:network) port $ssh_port pass $log0 quick proto tcp from <aixigo_lan> to (switches:network) port $http_port pass $log0 quick proto tcp from <aixigo_lan> to (dblan:network) port $ssh_port pass $log0 quick proto tcp from <aixigo_lan> to (dblan:network) port $http_port pass $log0 quick proto tcp from <zabbix_proxy> to (internal:network) port $zabbix_agent pass $log1 quick proto tcp from <zabbix_proxy> to (public:network) port $zabbix_agent pass $log0 quick proto tcp from <zabbix_proxy> to (switches:network) port $zabbix_agent pass $log0 quick proto tcp from <zabbix_proxy> to (dblan:network) port $zabbix_agent pass $log0 quick proto tcp from (switches:network) to <zabbix_proxy> port $zabbix_trapper pass $log1 quick proto tcp from (public:network) to <zabbix_proxy> port $zabbix_trapper pass $log0 quick proto tcp from (switches:network) to <zabbix_proxy> port $zabbix_trapper pass $log0 quick proto tcp from (dblan:network) to <zabbix_proxy> port $zabbix_trapper pass $log0 quick proto tcp from <zabbix_server> to <zabbix_proxy> port $zabbix_agent pass $log0 quick proto tcp from <zabbix_proxy> to <zabbix_server> port $zabbix_trapper # ========================================================================== # worldwide access to local services # ========================================================================== # NAT has already been applied, see above.