PF pf firewall basic understanding

Hi,

It seems I'm still struggling to fully grasp the concept behind pf filtering rules. I got the following setup:

A router/gateway which has five active interfaces, one (tun0) facing the WAN, the others (igb1, lagg0.64, lagg0.128, lagg.192) facing the LAN. What I want to achieve is to limit the traffic between the different networks, for instance I would like to restrict ICMP, like in the following table:

fromtostate
192.168.101.64/26192.168.101.192/26PASS
192.168.101.192/26192.168.101.192/26PASS
192.168.101.0/26192.168.101.192/26BLOCK

If I do so, I successfully can't reach any of the devices in the 192.168.101.192/26 network from 192.168.101.0/26 except for the router interface 192.168.101.193/26 which is still responding to ICMP echo-request, but I don't understand why. :( I hope someone can point out my mistake here.
  • router/gateway using freebsd 13.0-RELEASE-p5
    • interfaces:
      • tun0 - WAN interface
      • igb1 - 192.168.101.1/26 desc W
      • lagg0.64 192.168.101.65/26 vlan desc O
      • lagg0.128 192.168.101.129/26 vlan desc S
      • lagg0.192 192.168.101.193/26 vlan desc M
Code:
# /usr/local/etc/pf.conf
#
#-----------------------------------------------------------------------------
#
# Options
#
#-----------------------------------------------------------------------------

#
# iface: WAN
ifWan = "tun0"

#
# iface: VLAN
ifW = "igb1"
ifO = "lagg0.64"
ifS = "lagg0.128"
ifM = "lagg0.192"

# Variable declaration
include "/usr/local/etc/pf.conf.d/var/vlanWAN.conf"

# disable packet filtering on loopback interface
set skip on { lo }

#-----------------------------------------------------------------------------
#
# Normalization
#
#-----------------------------------------------------------------------------

# enable normalization of all incoming packets on all interfaces
scrub in all fragment reassemble max-mss 1440

#-----------------------------------------------------------------------------
#
# Queueing
#
#-----------------------------------------------------------------------------

#
# nothing here
#

#-----------------------------------------------------------------------------
#
# Translation (NAT)
#
#
#-----------------------------------------------------------------------------

include "/usr/local/etc/pf.conf.d/nat/vlanM.conf"
include "/usr/local/etc/pf.conf.d/nat/vlanS.conf"
include "/usr/local/etc/pf.conf.d/nat/vlanW.conf"
include "/usr/local/etc/pf.conf.d/nat/vlanO.conf"

#-----------------------------------------------------------------------------
#
# Filtering
#
#-----------------------------------------------------------------------------

# antispoof support
antispoof quick for { lo $ifWan $ifW $ifO $ifS $ifM }

# 1st rule
block all

#-----------------------------------------------------------------------------
#
# Inbound
#
#-----------------------------------------------------------------------------

# VLan: WAN (Internet)
include "/usr/local/etc/pf.conf.d/inbound/vlanWAN.conf"

# VLan: M
include "/usr/local/etc/pf.conf.d/inbound/vlanM.conf"

# VLan: S
include "/usr/local/etc/pf.conf.d/inbound/vlanS.conf"

# VLan: W
include "/usr/local/etc/pf.conf.d/inbound/vlanW.conf"

# VLan: O
include "/usr/local/etc/pf.conf.d/inbound/vlanO.conf"

#-----------------------------------------------------------------------------
#
# Outbound
#
#-----------------------------------------------------------------------------

# VLan: WAN (Internet)
include "/usr/local/etc/pf.conf.d/outbound/vlanWAN.conf"

# VLan: M
include "/usr/local/etc/pf.conf.d/outbound/vlanM.conf"

# VLan: S
include "/usr/local/etc/pf.conf.d/outbound/vlanS.conf"

# VLan: W
include "/usr/local/etc/pf.conf.d/outbound/vlanW.conf"

# VLan: O
include "/usr/local/etc/pf.conf.d/outbound/vlanO.conf"

Code:
#
# /etc/pf.conf.d/inbound/vlanW.conf
#
# interface var: $ifW

# ICMP: echoreq, unreach
pass in on $ifW inet proto icmp icmp-type { echoreq, unreach }

Code:
#
# /etc/pf.conf.d/outbound/vlanM.conf
#
# interface var: $ifM
#                       $ifW

# ICMP: echoreq, unreach
pass out on $ifM inet proto icmp from { $ifM:network $ifO:network } icmp-type { echoreq, unreach }
 
192.168.101.192/26 to 192.168.101.192/26 is on the same network, traffic never passes through your firewall because these hosts can directly talk to each other. You can't firewall that. I assume one of them is a typo and 192.168.101.128/26 is meant there.

I successfully can't reach any of the devices in the 192.168.101.192/26 network from 192.168.101.0/26 except for the router interface 192.168.101.193/26 which is still responding to ICMP echo-request, but I don't understand why.
I suspect, because you've cut everything up into smaller files, you have some overlapping rules. Keep in mind that unless you used the quick keyword rules continue to be processed after a specific rule has been 'hit'. So one rule might be blocking the traffic but a followup rule may be allowing it again.
 
SirDice, Thanks for your answer and sorry for my confusing posting. ?

192.168.101.192/26 to 192.168.101.192/26, allows me to request ICMP-echo from the router/gateway directly to the network 192.168.101.192/26. If I change that like below I'm not able to reach that network segment from the router anymore, but I'm still able to reach 192.168.101.193/26 from 192.168.101.4/26, which is what I don't understand. :-(

OLD:
Code:
#
# /etc/pf.conf.d/outbound/vlanM.conf
#
# interface var: $ifM
#                       $ifW

# ICMP: echoreq, unreach
pass out on $ifM inet proto icmp from { $ifM:network $ifO:network } icmp-type { echoreq, unreach }

NEW:
Code:
#
# /etc/pf.conf.d/outbound/vlanM.conf
#
# interface var: $ifM
#                       $ifW

# ICMP: echoreq, unreach
pass out on $ifM inet proto icmp from { $ifO:network } icmp-type { echoreq, unreach }
 
192.168.101.192/26 to 192.168.101.192/26, allows me to request ICMP-echo from the router/gateway directly to the network 192.168.101.192/26.
Code:
pass in on $ifM proto icmp from $ifM:network to ($ifM) icmp-type  { echoreq } # ping from network to gateway
pass out on $ifM proto icmp from ($ifM) to $ifM:network icmp-type  { echoreq }  # ping from gateway to network

For traffic passing through the gateway things get a little bit more complicated because you have to allow the traffic coming in on one interface and out another.
Code:
# From $ifM:network to $ifS:network
pass in on $ifM proto icmp from $ifM:network to $ifS:network icmp-type echoreq
pass out on $ifS proto icmp from $ifM:network to $ifS:network icmp-type echoreq

# From $ifS:network to $ifM:network 
pass in on $ifS proto icmp from $ifS:network to $ifM:network icmp-type echoreq
pass out on $ifM proto icmp from $ifS:network to $ifM:network icmp-type echoreq
Just took $ifM and $ifS as an example.
 
One idea that I find helpful in study of firewalls is that there's a certain logic to rule precedence when parsing the .conf files. A couple pitfalls from another thread:
 
Code:
pass in on $ifM proto icmp from $ifM:network to ($ifM) icmp-type  { echoreq } # ping from network to gateway
pass out on $ifM proto icmp from ($ifM) to $ifM:network icmp-type  { echoreq }  # ping from gateway to network

For traffic passing through the gateway things get a little bit more complicated because you have to allow the traffic coming in on one interface and out another.
Code:
# From $ifM:network to $ifS:network
pass in on $ifM proto icmp from $ifM:network to $ifS:network icmp-type echoreq
pass out on $ifS proto icmp from $ifM:network to $ifS:network icmp-type echoreq

# From $ifS:network to $ifM:network
pass in on $ifS proto icmp from $ifS:network to $ifM:network icmp-type echoreq
pass out on $ifM proto icmp from $ifS:network to $ifM:network icmp-type echoreq
Just took $ifM and $ifS as an example.
SirDice thank you for your example, but unfortunately it seems there is something fundamental wrong with my understanding.

I boiled down the ICMP rules to the following statement (ifW = igb1):
$ pfctl -vf /usr/local/etc/pf.conf | grep icmp
No ALTQ support in kernel
ALTQ related functions disabled
pass in on igb1 inet proto icmp all icmp-type echoreq keep state
$
Like mentioned the router gateway has the following interfaces:
intervar_varinterfaceip addrnetwork
ifWantun0publicpublic
ifWigb1192.168.101.1192.168.101.0/26
IfOlagg0.64192.168.101.65192.168.101.64/26
IfSlagg0.128192.168.101.129192.168.101.128/26
IfMlagg0.192192.168.101.193192.168.101.192/26

My laptop got the ip 192.168.101.4, so from my understanding I would expect the following behavoir based on the single ICMP rule above:
srcdststate
192.168.101.4192.168.101.1pass
192.168.101.4192.168.101.65blocked
192.168.101.4192.168.101.129blocked
192.168.101.4192.168.101.193blocked

In reality:
srcdststate
192.168.101.4192.168.101.1pass (expected)
192.168.101.4192.168.101.65pass (not expected)
192.168.101.4192.168.101.129pass (not expected)
192.168.101.4192.168.101.193pass (not expected)

All other devices in the actual networks are not reachable, but each of the routers interfaces in each single network is still reachable, and I don't understand why.

I hope this makes it a bit easier to understand. I already read a ton of material using Google and also read "The Book of PF" a few times, but I just don't get it?! o_O

astyle: Thank you for the thread I'm going to work through all these information.:)
 
One thing to note, the default rule of PF is to pass traffic. So if you don't have a block rule everything is going to be allowed.
 
Code:
$ pfctl -sr
scrub in all max-mss 1440 fragment reassemble
block drop in quick on ! lo inet6 all
block drop in quick on ! tun0 inet from x.x.x.x to any
block drop in quick inet from x.x.x.x to any
block drop in quick on ! igb1 inet from 192.168.101.0/26 to any
block drop in quick inet from 192.168.101.1 to any
block drop in quick on ! lagg0.64 inet from 192.168.101.64/26 to any
block drop in quick inet from 192.168.101.65 to any
block drop in quick on ! lagg0.128 inet from 192.168.101.128/26 to any
block drop in quick inet from 192.168.101.129 to any
block drop in quick on ! lagg0.192 inet from 192.168.101.192/26 to any
block drop in quick inet from 192.168.101.193 to any
block drop in quick inet6 all
block drop in quick on tun0 inet6 from fe80::220:b7ff:fee0:3db to any
block drop all
block drop in quick on tun0 inet from <__automatic_953c3c08_0> to any
pass in on lagg0.192 inet proto tcp all flags S/SA keep state
pass in on lagg0.192 inet proto udp all keep state
pass in on igb1 inet proto icmp all icmp-type echoreq keep state
pass in on igb1 inet proto udp from any to any port 33433 >< 33626 keep state
pass in on igb1 inet proto tcp from any to 192.168.101.1 port = ssh flags S/SA keep state (source-track rule, max-src-conn 15, max-src-conn-rate 3/1, overload <bruteforce> flush global, src.track 1)
pass in on igb1 inet proto udp from any to any port 3477 >< 3498 keep state
pass in on igb1 inet proto udp from any to any port 16383 >< 16388 keep state
pass in on igb1 inet proto udp from any to any port 16392 >< 16403 keep state
pass in on igb1 inet proto udp from any to any port = domain keep state
pass in on igb1 inet proto udp from any to any port = bootps keep state
pass in on igb1 inet proto udp from any to any port = http keep state
pass in on igb1 inet proto udp from any to any port = ntp keep state
pass in on igb1 inet proto udp from any to any port = imap keep state
pass in on igb1 inet proto udp from any to any port = https keep state
pass in on igb1 inet proto udp from any to any port = submission keep state
pass in on igb1 inet proto udp from any to any port = imaps keep state
pass in on igb1 inet proto tcp from any to 192.168.101.1 port = 3000 flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = 5223 flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = domain flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = bootps flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = http flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = ntp flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = imap flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = https flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = submission flags S/SA keep state
pass in on igb1 inet proto tcp from any to any port = imaps flags S/SA keep state
pass in on lagg0.64 inet proto tcp all flags S/SA keep state
pass in on lagg0.64 inet proto udp all keep state
block return out quick on tun0 inet from any to <__automatic_953c3c08_1>
pass out on lagg0.192 inet proto tcp from 192.168.101.193 to 192.168.101.192/26 flags S/SA keep state
pass out on lagg0.192 inet proto tcp from 192.168.101.64/26 to 192.168.101.192/26 flags S/SA keep state
pass out on igb1 inet proto tcp from 192.168.101.1 to 192.168.101.0/26 flags S/SA keep state
pass out on igb1 inet proto tcp from 192.168.101.64/26 to 192.168.101.0/26 flags S/SA keep state
pass out on tun0 inet proto tcp all flags S/SA keep state
pass out on lagg0.64 inet proto tcp from 192.168.101.65 to 192.168.101.64/26 flags S/SA keep state
pass out on lagg0.192 inet proto udp from 192.168.101.193 to 192.168.101.192/26 keep state
pass out on lagg0.192 inet proto udp from 192.168.101.64/26 to 192.168.101.192/26 keep state
pass out on igb1 inet proto udp from 192.168.101.1 to 192.168.101.0/26 keep state
pass out on igb1 inet proto udp from 192.168.101.64/26 to 192.168.101.0/26 keep state
pass out on tun0 inet proto udp all keep state
pass out on lagg0.64 inet proto udp from 192.168.101.65 to 192.168.101.64/26 keep state
$

Code:
$ ifconfig
igb0: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:db
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
igb1: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:dc
    inet 192.168.101.1 netmask 0xffffffc0 broadcast 192.168.101.63
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
igb2: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:dd
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
igb3: flags=8863<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:dd
    hwaddr 00:20:b7:e0:03:de
    media: Ethernet autoselect (1000baseT <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
igb4: flags=8822<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:df
    media: Ethernet autoselect
    status: no carrier
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
igb5: flags=8822<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:e0
    media: Ethernet autoselect
    status: no carrier
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
    inet6 ::1 prefixlen 128
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x7
    inet 127.0.0.1 netmask 0xff000000
    groups: lo
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1492
    options=80000<LINKSTATE>
    inet6 fe80::220:b7ff:fee0:3db%tun0 prefixlen 64 scopeid 0x8
    inet x.x.x.x --> x.x.x.x netmask 0xffffffff
    groups: tun
    nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
    Opened by PID 65795
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:dd
    laggproto lacp lagghash l2,l3,l4
    laggport: igb2 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
    laggport: igb3 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
    groups: lagg
    media: Ethernet autoselect
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lagg0.64: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1496
    options=4600703<RXCSUM,TXCSUM,TSO4,TSO6,LRO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:dd
    inet 192.168.101.65 netmask 0xffffffc0 broadcast 192.168.101.127
    groups: vlan
    vlan: 64 vlanproto: 802.1q vlanpcp: 0 parent interface: lagg0
    media: Ethernet autoselect
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lagg0.128: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1496
    options=4600703<RXCSUM,TXCSUM,TSO4,TSO6,LRO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:dd
    inet 192.168.101.129 netmask 0xffffffc0 broadcast 192.168.101.191
    groups: vlan
    vlan: 128 vlanproto: 802.1q vlanpcp: 0 parent interface: lagg0
    media: Ethernet autoselect
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lagg0.192: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1496
    options=4600703<RXCSUM,TXCSUM,TSO4,TSO6,LRO,RXCSUM_IPV6,TXCSUM_IPV6,NOMAP>
    ether 00:20:b7:e0:03:dd
    inet 192.168.101.193 netmask 0xffffffc0 broadcast 192.168.101.255
    groups: vlan
    vlan: 192 vlanproto: 802.1q vlanpcp: 0 parent interface: lagg0
    media: Ethernet autoselect
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
pflog0: flags=141<UP,RUNNING,PROMISC> metric 0 mtu 33160
    groups: pflog
$

Code:
$ netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default               x.x.x.x      UGS        tun0
x.x.x.x                link#8             UH         tun0
x.x.x.x                link#8             UHS         lo0
127.0.0.1           link#7             UH          lo0
192.168.101.0/26   link#2             U          igb1
192.168.101.1      link#2             UHS         lo0
192.168.101.64/26  link#10            U      lagg0.64
192.168.101.65     link#10            UHS         lo0
192.168.101.128/26 link#11            U      lagg0.12
192.168.101.129    link#11            UHS         lo0
192.168.101.192/26 link#12            U      lagg0.19
192.168.101.193    link#12            UHS         lo0
$
 
Sometimes, it helps to have a quick-and-dirty diagram on paper for your setup. It then quickly becomes obvious how the data flows, and where the errors in your config are. That's advice from my college class on computer networks. :cool:
 
This rule:
Code:
pass in on igb1 inet proto icmp all icmp-type echoreq keep state
That allows the traffic. And the reason you can ping the other other gateway addresses (192.168.101.65, 192.168.101.129, 192.168.101.193) is because these addresses are attached to the host, that traffic never passed out of any of the interfaces, so it never gets blocked by any rule. Packets with that destination address have already arrived at their destination and don't need to be routed out of an interface.
 
Sometimes, it helps to have a quick-and-dirty diagram on paper for your setup. It then quickly becomes obvious how the data flows, and where the errors in your config are. That's advice from my college class on computer networks. :cool:
I got that one right here only on paper, but I can add that as well. :)
 
When you ping from 192.168.101.4 -> 192.168.101.65 the dynamic state rule is created via " pass in on igb1 inet proto icmp all icmp-type echoreq keep state" which allow the returning traffic to pass out on igb1.

Edit: SirDice just respond faster than me :)
 
Try pinging some other addresses (not bound to the gateway host) in those 192.168.101.64/26, 192.168.101.128/26 or 192.168.101.192/26 ranges. And you'll see those packets have to travel out of their respective interfaces to arrive at their destination. Firewall rules only apply to packets going into or out of an interface.
 
You can show the dynamic state table using pfctl -ss or/and you can observe the actual packet using tcpdump on pflog interface to get better understanding which rules is matched.
 
This rule:
Code:
pass in on igb1 inet proto icmp all icmp-type echoreq keep state
That allows the traffic. And the reason you can ping the other other gateway addresses (192.168.101.65, 192.168.101.129, 192.168.101.193) is because these addresses are attached to the host, that traffic never passed out of any of the interfaces, so it never gets blocked by any rule. Packets with that destination address have already arrived at their destination and don't need to be routed out of an interface.

Ok, so just to get that right, ip addresses are primary attached to the host and not attached to the host interface, so does that mean in conclusion that all services bound to each separate address are also available through all other addresses as soon as the host is reached ?

Example:
addressportservices
192.168.101.1123ntp
192.168.101.65123ntp
192.168.101.129123ntp
192.168.101.193123ntp

The following rule would not only give access to 192.168.101.1:123, but as well access to 192.168.101.65:123, 192.168.101.129:123, 192.168.101.193:123, but no access beyond that host.
pass in on $ifW inet proto { tcp udp } to port ntp

where instead the following rule should limit the access to 192.168.101.1:123, and all other addresses become unavailable, right ?
pass in on $ifW inet proto {tcp udp } to 192.168.101.1 port ntp

In regards to the ICMP echo-reply, if I don't want that kind of behavior, I need to filter ICMP echo-reply at the interface it is passing to 192.168.101.4, so I thought of the following rule to block all ICMP from 192.168.101.65 (to keep it simple)
block out on $ifW inet proto icmp from 192.168.101.65
but I still get an ICMP echo-reply. ? o_O

I monitor the traffic using:
$ tcpdump -i igb1 icmp and host 192.168.101.4
I also tried pfctl -ss and it seems even after ping has been canceled the icmp state is for another 10 seconds in the table, is that correct ?

Sorry for so many questions and thank you for all your help!?
 
Ok, so just to get that right, ip addresses are primary attached to the host and not attached to the host interface, so does that mean in conclusion that all services bound to each separate address are also available through all other addresses as soon as the host is reached ?
Yes, that sounds about right.
The following rule would not only give access to 192.168.101.1:123, but as well access to 192.168.101.65:123, 192.168.101.129:123, 192.168.101.193:123, but no access beyond that host.
Yes.
In regards to the ICMP echo-reply, if I don't want that kind of behavior, I need to filter ICMP echo-reply at the interface it is passing to 192.168.101.4, so I thought of the following rule to block all ICMP from 192.168.101.65 (to keep it simple)
No, packet is already on the host at that point. You need to block it coming in.
Code:
block in on $ifW proto icmp to 192.168.101.65
 
Ok, so just to get that right, ip addresses are primary attached to the host and not attached to the host interface, so does that mean in conclusion that all services bound to each separate address are also available through all other addresses as soon as the host is reached ?
If your host has 2 NICs, it would be quite possible for it to have 2 IP addresses. Even a consumer-grade router would have 2 IP addresses: an Internet-legal one, and an internal one, like 192.168.1.1.
--
an IP address gets bound to an interface on the host. In case of a router, one IP address (192.168.1.1) can be bound to several interfaces (ethernet plugs) - this is a case of "One or more".
--
If SSH is only listening on 192.168.101.3, port 22, it would not accept connections on 192.168.101.4, port 22.

Maybe SirDice can correct me - but OP's statement that I'm quoting does not appear to be correct, as far as I can tell. ?
 
an IP address gets bound to an interface on the host.
Yes, but the IP address is always routed to lo0:
Code:
192.168.101.1      link#2             UHS         lo0
192.168.101.65     link#10            UHS         lo0
192.168.101.129    link#11            UHS         lo0
192.168.101.193    link#12            UHS         lo0

I always imagine myself to be a network packet. The only thing a router (gateway_enable) cares about is the destination IP address. So packet gets sent to 192.168.101.1 and walks in on $ifW. Runs into a firewall rule, pass in on igb1 inet proto icmp all icmp-type echoreq. Good, allowed in. Then looks at routing table where to go next, sees 192.168.101.65 is right here. Hey, service with that IP. And the response is allowed back due to the state.
 
Yes, but the IP address is always routed to lo0:
Code:
192.168.101.1      link#2             UHS         lo0
192.168.101.65     link#10            UHS         lo0
192.168.101.129    link#11            UHS         lo0
192.168.101.193    link#12            UHS         lo0

I always imagine myself to be a network packet. The only thing a router (gateway_enable) cares about is the destination IP address. So packet gets sent to 192.168.101.1 and walks in on $ifW. Runs into a firewall rule, pass in on igb1 inet proto icmp all icmp-type echoreq. Good, allowed in. Then looks at routing table where to go next, sees 192.168.101.65 is right here. Hey, service with that IP. And the response is allowed back due to the state.
Off the top of my head, routing to lo0 isn't making much sense. Which command produced the routing table? netstat -r?
 
Back
Top