PF Minimal pf rules for L2TP/IPSec oubound connection

yurybx

Member


Messages: 24

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
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 7,409
Messages: 29,985

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
 
OP
OP
Y

yurybx

Member


Messages: 24

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.
 

abishai

Aspiring Daemon

Reaction score: 161
Messages: 706

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
 
OP
OP
Y

yurybx

Member


Messages: 24

But even in this way it does not work:
pass in quick proto udp from 195.149.70.70 to $ext_if port 500
 

abishai

Aspiring Daemon

Reaction score: 161
Messages: 706

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.
 
OP
OP
Y

yurybx

Member


Messages: 24

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.
 

abishai

Aspiring Daemon

Reaction score: 161
Messages: 706

If we are discussing client, and client is a initiator (say, roadwarrior setup), inbound rules on client are not required at all.
 
Top