Linux – ip xfrm policy port

ipseclinuxlinux-networking

On Linux, ip xfrm policy let's me specify the selector on which I want to enable IPsec. It allows you to restrict IPsec to a particular port, by specifying [ sport PORT ] [ dport PORT ]

I would like to enable IPsec for all but one port. E.g. IPsec for all ports except 873. Is there any way to do that? Is there any way to specify a "not" in the SELECTOR? If not, what is the workaround?

Note that I am referring to manual initialization of the kernel's IPsec, using the ip xfrm command.

Best Answer

Just create passthrough policies for that port that have a higher priority (lower numeric value) than the policies that match all ports. Passthrough policies have action allow but no templates attached.

Without docs, I would have expected that allow simply allows the traffic, not that it bypasses the other policies and skips encrypting it.

That's because the Linux kernel stores the policies in a list ordered by priority and only uses the first matching policy. So if an action allow policy (the default, the only other option is to use action drop to filter traffic) without templates (i.e. without any instructions how to process/encrypt the traffic) has a higher priority than the actual IPsec policies the traffic will just bypass IPsec processing.

For instance, if your existing policies have priority 1000 then add passthrough policies for TCP port 873 like this:

ip xfrm policy add proto tcp sport 873 dport 873 dir out priority 1
ip xfrm policy add proto tcp sport 873 dport 873 dir in priority 1

The priority could be anything, it must just be lower than 1000 so traffic matches these policies first.