I had this gateway with NAT working fine until I added another for
load balancing using carp. So now I've been slowly discovering the ins
and outs of carp in PF rules. Namely that packets seem to be going in
and out of the physical interfaces, but in on the carp interfaces at
the same time. Only a detail I've noted with tcpdump.

vic0 is management only, works fine.
vic1 is pfsync only, set skip
vic2 is external public ipv4 address, seen here below as XX.XX.XX.59.
vic3 is the first internal network 10.221.181.0/24
vic4 is the second internal network 10.221.182.0/24
carp0 is vic2 on both machines, there is no IP-information on the
physical carpdev's, only on the carps.
carp1 is vic3
carp2 is vic4

There are no pfsync update errors in syslog, I can see carp traffic
pass between the carpdevs using proto carp.

Both loadbalancers are identical in configuration and I use git,
public ssh keys and bash scripts to update the configuration on the
git-server, update it on both loadbalancers and then run pfctl -vf
/etc/pf.conf on both.

Here is output of pfctl -vvsr, please excuse the mail formatting. I'm
hoping this will shed light on my ruleset.

@0 block drop on vic0 all
  [ Evaluations: 353       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@1 pass in quick on vic0 inet proto tcp from any to 10.220.100.0/24
port = 1022 flags S/SA keep state label "PassInMGMTSSH"
  [ Evaluations: 347       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@2 pass in quick on vic0 inet proto tcp from any to 10.220.100.0/24
port = ssh flags S/SA keep state label "PassInMGMTSSH"  [ Evaluations:
0         Packets: 0         Bytes: 0           States: 0     ]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@3 pass out quick on vic0 inet proto tcp from 10.220.100.0/24 to any
port = 1022 flags S/SA keep state label "PassOutMGMTSSH"
  [ Evaluations: 16        Packets: 136       Bytes: 19978       States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 1     ]
@4 pass out quick on vic0 inet proto tcp from 10.220.100.0/24 to any
port = ssh flags S/SA keep state label "PassOutMGMTSSH"
  [ Evaluations: 15        Packets: 1020      Bytes: 441024      States: 4
]
  [ Inserted: uid 0 pid 3940 State Creations: 30    ]
@5 pass on vic0 proto udp from any to any port = domain keep state
label "PassMGMTDNS"
  [ Evaluations: 331       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@6 pass on vic0 inet proto icmp all icmp-type echorep keep state label
"PassMGMTICMP"
  [ Evaluations: 331       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@7 pass on vic0 inet proto icmp all icmp-type echoreq keep state label
"PassMGMTICMP"
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@8 pass on vic0 inet proto icmp all icmp-type unreach keep state label
"PassMGMTICMP"
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@9 pass quick on vic2 proto carp all keep state label "CUST-PassCarp"
  [ Evaluations: 337       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@10 pass quick on vic3 proto carp all keep state label "CUST-PassCarp"
  [ Evaluations: 332       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@11 pass quick on vic4 proto carp all keep state label "CUST-PassCarp"
  [ Evaluations: 331       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@12 block drop log all
  [ Evaluations: 337       Packets: 335       Bytes: 36237       States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@13 pass log inet proto icmp from any to XX.XX.XX.59 icmp-type echoreq
keep state label "CUST-PingOutPhys"
  [ Evaluations: 337       Packets: 1722      Bytes: 144648      States: 1
]
  [ Inserted: uid 0 pid 3940 State Creations: 1     ]
@14 pass log inet proto icmp from any to XX.XX.XX.59 icmp-type echorep
keep state label "CUST-PingOutPhys"
  [ Evaluations: 1         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@15 pass log inet proto icmp from any to XX.XX.XX.59 icmp-type unreach
keep state label "CUST-PingOutPhys"
  [ Evaluations: 1         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@16 pass log inet proto icmp from any to 10.221.181.10 icmp-type
echoreq keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 884       Bytes: 74256       States: 1
]
  [ Inserted: uid 0 pid 3940 State Creations: 2     ]
@17 pass log inet proto icmp from any to 10.221.182.10 icmp-type
echoreq keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@18 pass log inet proto icmp from any to 10.221.181.10 icmp-type
echorep keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@19 pass log inet proto icmp from any to 10.221.182.10 icmp-type
echorep keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@20 pass log inet proto icmp from any to 10.221.181.10 icmp-type
unreach keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@21 pass log inet proto icmp from any to 10.221.182.10 icmp-type
unreach keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@22 pass log inet proto icmp from 10.221.181.10 to any icmp-type
echoreq keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@23 pass log inet proto icmp from 10.221.182.10 to any icmp-type
echoreq keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@24 pass log inet proto icmp from 10.221.181.10 to any icmp-type
echorep keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@25 pass log inet proto icmp from 10.221.182.10 to any icmp-type
echorep keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@26 pass log inet proto icmp from 10.221.181.10 to any icmp-type
unreach keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@27 pass log inet proto icmp from 10.221.182.10 to any icmp-type
unreach keep state label "CUST-PingInternalGW"
  [ Evaluations: 2         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@28 match out log on vic2 from ! (egress:2) to any label
"CUST-MatchOutNAT" nat-to (egress:2) round-robin
  [ Evaluations: 337       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@29 pass out log inet proto tcp from XX.XX.XX.59 to any port = www
flags S/SA keep state label "CUST-PassOutPorts"
  [ Evaluations: 332       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@30 pass out log inet proto tcp from XX.XX.XX.59 to any port = https
flags S/SA keep state label "CUST-PassOutPorts"
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@31 pass out log inet proto tcp from XX.XX.XX.59 to any port = smtp
flags S/SA keep state label "CUST-PassOutPorts"
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@32 pass out log inet proto tcp from XX.XX.XX.59 to any port = ssh
flags S/SA keep state label "CUST-PassOutPorts"
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@33 pass out log inet proto tcp from XX.XX.XX.59 to any port = 1022
flags S/SA keep state label "CUST-PassOutPorts"
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@34 pass in log on vic3 inet proto tcp from 10.221.181.0/24 to any
flags S/SA keep state
  [ Evaluations: 337       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@35 pass in log on vic3 inet proto tcp from 10.221.182.0/24 to any
flags S/SA keep state
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@36 pass in log on vic4 inet proto tcp from 10.221.181.0/24 to any
flags S/SA keep state
  [ Evaluations: 336       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@37 pass in log on vic4 inet proto tcp from 10.221.182.0/24 to any
flags S/SA keep state
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@38 pass out log on vic2 inet proto tcp from 10.221.181.0/24 to any
flags S/SA keep state
  [ Evaluations: 336       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@39 pass out log on vic2 inet proto tcp from 10.221.182.0/24 to any
flags S/SA keep state
  [ Evaluations: 0         Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@40 anchor "ftp-proxy/*" all
  [ Evaluations: 337       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]
@41 pass in log on vic3 inet proto tcp from any to any port = ftp
flags S/SA keep state label "CUST-PassInRDRFTP" rdr-to 127.0.0.1 port
8021
  [ Evaluations: 337       Packets: 0         Bytes: 0           States: 0
]
  [ Inserted: uid 0 pid 3940 State Creations: 0     ]

My real issue is with connections going out from the LAN to remote
destinations on the internet.

>From a LAN server I do nc -vv 212.211.132.250 80 # (this is
security.debian.org) and get the following on pflog0.

Oct 17 07:47:30.793687 rule 34/(match) pass in on vic3:
10.221.181.21.45667 > 212.211.132.250.80: S 3729652686:3729652686(0)
win 5840 <mss 1460,sackOK,timestamp 85822017 0,nop,wscale 7> (DF)
Oct 17 07:47:30.793786 rule 28/(match) match out on vic2:
XX.XX.XX.59.57433 > 212.211.132.250.80: S 3729652686:3729652686(0) win
5840 <mss 1460,sackOK,timestamp 85822017 0,nop,wscale 7> (DF)
Oct 17 07:47:30.793800 rule 29/(match) pass out on vic2:
XX.XX.XX.59.57433 > 212.211.132.250.80: S 3729652686:3729652686(0) win
5840 <mss 1460,sackOK,timestamp 85822017 0,nop,wscale 7> (DF)

So this tells me that NAT is being done, and it is even sending
packets out on the external carpdev (vic2) to the remote destination.
But nothing comes back and the connection times out. I am not a
networking guy but TCP is a streaming protocol, I know that much, am I
to allow packets coming back through that stream? Or even packets
coming back to establish the stream?

Even removing 'tcp' from that tcpdump command doesn't give me any new
clues as to what is happening to the rest of the stream. If I do nc
-vv 212.211.132.250 80 from the shell on the gateway it works fine.
Strangely enough the same command from lb02 does not work, it triggers
rule 29 in tcpdump of pflog0 on both systems but on lb02 no connection
is established.

lb01 $
carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 01:00:5e:00:01:01
        description: Customer External Public Loadbalancer
        priority: 0
        carp: carpdev vic2 advbase 1 balancing ip
                state MASTER vhid 1 advskew 0
                state MASTER vhid 2 advskew 100
        groups: carp egress
        status: master
        inet6 fe80::200:5eff:fe00:101%carp0 prefixlen 64 scopeid 0x8
        inet XX.XX.XX.59 netmask 0xffffff00 broadcast XX.XX.XX.255
vic2: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST>
mtu 1500
        lladdr 00:50:56:8e:00:63
        description: Customer External
        priority: 0
        media: Ethernet autoselect
        status: active
        inet6 fe80::250:56ff:fe8e:63%vic2 prefixlen 64 scopeid 0x3

lb02 $
carp0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 01:00:5e:00:01:01
        description: Customer External Public Loadbalancer
        priority: 0
        carp: carpdev vic2 advbase 1 balancing ip
                state MASTER vhid 1 advskew 100
                state MASTER vhid 2 advskew 0
        groups: carp egress
        status: master
        inet6 fe80::200:5eff:fe00:102%carp0 prefixlen 64 scopeid 0x8
Connection to 10.220.100.53 closed.
        inet XX.XX.XX.59 netmask 0xffffff00 broadcast XX.XX.XX.255
vic2: flags=8b43<UP,BROADCAST,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST>
mtu 1500
        lladdr 00:50:56:8e:00:5e
        description: Customer External
        priority: 0
        media: Ethernet autoselect
        status: active
Connection to 10.220.100.53 closed.
        inet6 fe80::250:56ff:fe8e:5e%vic2 prefixlen 64 scopeid 0x3

Now there is actually another issue here that is of lower priority,
the fact that I can ping the external IP of the gateway without issue
but I can't have my LAN servers ping their gateways, meaning the
IP-addresses of carp1 and carp2. In that case I can see packets going
in on the physical interface behind carp1, but no reply comes back.

Oct 17 07:45:48.710962 rule 16/(match) pass in on vic3: 10.221.181.21
> 10.221.181.10: icmp: echo request (DF)

This is strange to me as the rule to allow ICMP on the external
interface is nearly identical to the ones to allow on the internal
interfaces.

--


Med vdnliga hdlsningar / With kind regards

Stefan Midjich

Reply via email to