PF Minimal pf rules for L2TP/IPSec oubound connection

Good day!
I am trying to optimize the firewall rules, leaving only the necessary permissions. And I ran into a strange situation.
My FreeBSD server establishes the L2TP/IPSec connection to the remote server. And if there is the rules in my pf.conf
pass in on $ext_if proto { esp ah } from 195.149.70.70 to $ext_if pass in on $ext_if proto udp from 195.149.70.70 to $ext_if
then the connection is established normally.
But if the second rule is replaced by
pass in on $ext_if proto udp from 195.149.70.70 to $ext_if port {500 1701}
then the connection can not establish!
With a successful connection, the tcpdump shows the following picture (1.2.3.4 - my IP, 195.149.70.70 - L2TP-server's IP):
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hn1, link-type EN10MB (Ethernet), capture size 65535 bytes
16:42:14.404130 IP 1.2.3.4.500 > 195.149.70.70.500: isakmp: phase 1 I ident
16:42:14.426122 IP 195.149.70.70.500 > 1.2.3.4.500: isakmp: phase 1 R ident
16:42:14.427514 IP 1.2.3.4.500 > 195.149.70.70.500: isakmp: phase 1 I ident
16:42:14.450043 IP 195.149.70.70.500 > 1.2.3.4.500: isakmp: phase 1 R ident
16:42:14.451509 IP 1.2.3.4.500 > 195.149.70.70.500: isakmp: phase 1 I ident[E]
16:42:14.469011 IP 195.149.70.70.500 > 1.2.3.4.500: isakmp: phase 1 R ident[E]
16:42:14.470596 IP 1.2.3.4.500 > 195.149.70.70.500: isakmp: phase 2/others I oakley-quick[E]
16:42:14.489225 IP 195.149.70.70.500 > 1.2.3.4.500: isakmp: phase 2/others R oakley-quick[E]
16:42:14.493802 IP 1.2.3.4.500 > 195.149.70.70.500: isakmp: phase 2/others I oakley-quick[E]
16:42:17.667995 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x1), length 148
16:42:17.685935 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x1), length 164
16:42:17.686510 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x2), length 148
16:42:17.703530 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x2), length 68
16:42:17.703579 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x3), length 84
16:42:17.721570 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x3), length 84
16:42:17.722039 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x4), length 100
16:42:17.722811 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x5), length 84
16:42:17.743385 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x4), length 68
16:42:17.743468 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x5), length 84
16:42:17.743692 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x6), length 84
16:42:17.743713 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x7), length 84
16:42:17.744541 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x6), length 84
16:42:17.745550 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x7), length 68
16:42:17.760977 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x8), length 68
16:42:17.761018 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0x9), length 84
16:42:17.763179 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x8), length 132
16:42:17.793245 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0x9), length 68
16:42:17.798005 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0xa), length 116
16:42:17.799122 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0xa), length 84
16:42:17.817447 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0xb), length 68
16:42:17.817759 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0xc), length 68
16:42:17.817847 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0xb), length 68
16:42:17.818158 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0xc), length 68
16:42:17.835396 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0xd), length 68
16:42:17.835651 IP 1.2.3.4 > 195.149.70.70: ESP(spi=0x572fa15d,seq=0xd), length 68
16:42:17.855546 IP 195.149.70.70 > 1.2.3.4: ESP(spi=0xc4c822e1,seq=0xe), length 68
Thus, I see that only port 500 is used. But this port is not enough for it! How to understand why?
My ipsec.conf:
Code:
config setup
conn vpn-uz
        keyexchange=ikev1
        type=transport
        authby=secret
        ike=aes128-sha1-modp1024
        esp=aes128-sha1
        left=%defaultroute
        leftsubnet=%dynamic[udp]
        right=195.149.70.70
        rightsubnet=195.149.70.70[udp/1701]
        auto=route
 
Code:
pass out quick on $ext_if proto esp from any to any
pass out quick on $ext_if proto ah from any to any
pass out quick on $ext_if proto ipencap from any to any

pass in quick on $ext_if proto esp from any to any
pass in quick on $ext_if proto ah from any to any
pass in quick on $ext_if proto ipencap from any to any
You'll want to limit these to both end points instead of any to any. You'll also need to allow UDP/500 for IKE.

There's a fairly basic set of rules at the bottom of the page: Handbook: 13.7. VPN over IPsec
 
Unfortunately, this does not work. But as soon as I replace line
pass in quick proto udp from any port = 500 to any port = 500
with line
pass in quick proto udp from 195.149.70.70 to $ext_if
, the connection is established successfully.
I'm at a loss.
 
The first rule is wrong. Source port is not guaranteed to be 500. In case of NAT-T it will be random.
Here are my rules
Code:
pass in on $ext inet proto udp from any to $main port { 500, 4500 }        #StrongSwan
pass in on $ext inet proto esp from any to any                    #Allow ESP
 
But even in this way it does not work:
pass in quick proto udp from 195.149.70.70 to $ext_if port 500
 
tcpdump is your friend here. Log dropped packets and check them. esp proto, 500 and 4500 inbound is enough for ipsec to operate. BTW, it is unclear - we are discussing server rules or client rules ? My example for the server.
 
tcpdump is your friend here. Log dropped packets and check them. esp proto, 500 and 4500 inbound is enough for ipsec to operate. BTW, it is unclear - we are discussing server rules or client rules ? My example for the server.
Tcpdump shows ESP and UDP:500 traffic only. It is strange.
My FreeBSD machine is client in this situation, so we are discussing client rules.
Tomorrow I will try adding 4500 port into my rules.
 
If we are discussing client, and client is a initiator (say, roadwarrior setup), inbound rules on client are not required at all.
 
Back
Top