nm-l2tp / NetworkManager-l2tp

L2TP and L2TP/IPsec support for NetworkManager
GNU General Public License v2.0
486 stars 83 forks source link

UDP port 500 is open needlessly #193

Closed patrakov closed 1 year ago

patrakov commented 1 year ago

Context: a website that I don't want to disclose checks for VPN related ports and denies access if they find an open port. I have worked around this using a local firewall, but still, I have an opinion that if a firewall is needed (not as a second line of defense), then something else is wrong.

I have a SwissVPN account. They give out a public IP, so, with other VPN types (PPtP, SSTP), this anti-VPN feature is not a problem: my public IP is not the same as the VPN server IP, so the check doesn't trigger. But it is a problem with Network-Manager-l2tp, because UDP port 500 is open and responds to packets from outside, that arrive via the VPN.

There is no reason to keep port 500 open to the entire world. We should somehow force StrongSwan to do a connect() so that it ignores all packets addressed to port 500 and not coming from the VPN server.

dkosovic commented 1 year ago

For the custom ipsec.conf file that gets generated, it is currently using left=%defaultroute :

according to https://wiki.strongswan.org/projects/strongswan/wiki/connsection :

Prior to 5.0.0, specifying %any for the local endpoint was not supported for IKEv1 connections, instead the keyword %defaultroute could be used, causing the value to be filled in automatically with the local address of the default-route interface (as determined at IPsec startup time and during configuration update).

From the above, it's not clear what left=%defaultroute does with strongswan >= 5.0.0, but from what you describe, not only is it listening on the local IP address, but also on the IP address assigned by the VPN server.

I need to look at it more.

dkosovic commented 1 year ago

Running ss and netstat both confirm strongwan's charon daemon is listening on 0.0.0.0, i.e. all interfaces for UDP port 500:

$ sudo ss -tunlp | grep :500
udp   UNCONN 0      0                       0.0.0.0:500        0.0.0.0:*    users:(("charon",pid=12238,fd=12))                                                                             
udp   UNCONN 0      0                             *:500              *:*    users:(("charon",pid=12238,fd=10))                                                                             

$ sudo netstat -tunlp | grep :500
udp        0      0 0.0.0.0:500             0.0.0.0:*                           12238/charon        
udp6       0      0 :::500                  :::*                                12238/charon        

I tried setting left=192.168.0.74 (i.e. my local IP address) in the custom ipsec.conf file that gets generated, but made no difference with strongwan's charon daemon still listening on 0.0.0.0 port 500.

I think you need to modify /etc/strongswan.conf and set interfaces_ignore to the interface you don't want listening on port 500, or set interfaces_use to the interfaces you do want to listening on port 500. I don't think it is possible to do it with the custom ipsec.conf file that gets generated.

Switching to libreswan seems to do the right thing, when the VPN connection is up I see :

$ sudo netstat -tunlp | grep :500
udp        0      0 127.0.0.1:500           0.0.0.0:*                           14389/pluto         
udp        0      0 192.168.0.74:500        0.0.0.0:*                           14389/pluto         
udp        0      0 192.168.0.159:500       0.0.0.0:*                           14389/pluto
udp6       0      0 2001:8003:786c:cf00:500 :::*                                14389/pluto         
udp6       0      0 2001:8003:786c:cf00:500 :::*                                14389/pluto         
udp6       0      0 2001:8003:786c:cf00:500 :::*                                14389/pluto         
udp6       0      0 2001:8003:786c:cf00:500 :::*                                14389/pluto         
udp6       0      0 ::1:500                 :::*                                14389/pluto

Where 192.168.0.74 is my local Ethernet and 192.168.0.159 my local WiFi. So only local interfaces are being listened on.

dkosovic commented 1 year ago

Most Linux distros include both strongswan and libreswan, on Ubuntu to switch to libreswan, just issue:

sudo apt install libreswan
patrakov commented 1 year ago

Well, for Arch Linux, it is in AUR. I will give it a try in a virtual machine later this week.

patrakov commented 1 year ago

Another data point is that for IKEv2 tunnels (unfortunately not supported by SwissVPN) the StrongSwan NetworkManager plugin ends up with no interface listening on port 500 at all.

dkosovic commented 1 year ago

NetworkManager-strongswan uses a daemon called charon-nm which runs independently of the regular daemons charon-systemd or charon and to avoid conflicts, it doesn't use ports 500/udp and 4500/udp.

charon-nm also uses a completely different configuration interface.

dkosovic commented 1 year ago

I'll close this issue as there isn't much I can do with how strongswan listens on multiple interfaces for UDP port 500 with the custom ipsec.conf file that gets generated. At least strongswan provides mechanism to modify the behavior with /etc/strongswan.conf.