Change local source ports of IPsec tunnels
-
I have a VPN vendor where they will support multiple P1 connections but the requirement is that I change the source port on my side. The context is that each connection on the remote side can only support X amount of throughput, but by adding multiple tunnels to the same remote destination IP, I can get double the bandwidth. Routes are shared between pfSense and the remote with BGP and utilize ECMP.
Is it possible to have multiple P1 connections to the same destination IP and use different local source ports for each connection? If it's not possible in the UI, I'm open to any file-based modifications as a workaround.
For example:
Connection 1 P1 to remote IP uses the standard local 4500 port
Connection 2 P1 to remote IP uses a custom local port of 4501Thanks!
-
@baketopher
I have forwarded a different port (2001) to the NAT-T port, where IPSec is listening on:

However, this requires that the remote site initiates the connection.
If you want to initiate the connection from your site, a different remote IP or port would be required, so you can define an outbound NAT rule to translate the source IP to something else.
I didn't find another way to use different local ports for multiple connections.
-
@baketopher I think you are looking for the “custom ports” settings on VPN -> IPSEC - ADVANCED tab:

@OP: Sorry, this wasn’t intended for you but rather @viragomann
-
@keyser said in Change local source ports of IPsec tunnels:
I think you are looking for the “custom ports” settings on VPN -> IPSEC - ADVANCED tab
But this sets the port globally for IPSec, but I don't see a way to state a specific port for a certain connection, as the OP requested.
-
Circling back to this, I've been researching whether this is possible with pfSense's current strongSwan implementation or whether a code change would be required. Unfortunately, this isn't currently possible. Here's why:
The Core Issue: socket-default vs socket-dynamic
strongSwan has two socket plugins that handle IKE packet transmission:
- socket-default (what pfSense uses): Opens two fixed UDP ports (500 and 4500) at daemon startup. These ports are shared globally by all connections. The local_port setting in swanctl.conf is ignored because the socket layer doesn't support per-connection ports.
- socket-dynamic: Opens sockets dynamically on a per-connection basis, allowing each tunnel to specify its own local_port. However, this plugin is marked as experimental and has significant limitations.
Why socket-dynamic Isn't a Simple Solution
- Cannot use port 500 - The plugin enables UDP encapsulation on all sockets, so standard IKE packets without the non-ESP marker are incorrectly processed as ESP by the kernel. You must use NAT-T ports (4500+) exclusively.
- No coexistence - You cannot load both socket-default and socket-dynamic simultaneously. The socket layer operates at the daemon level, not per-connection. Both plugins would attempt to bind the same ports, and only one would actually receive packets.
- Requires remote NAT-T port - Connections must set remote_port = 4500 (or another NAT-T port), limiting interoperability.
Current Workarounds
- Multiple WAN IPs: Bind each tunnel to a different source IP address via the Phase 1 Interface setting
- Different remote ports: If your VPN vendor can accept connections on different remote ports, pfSense does support per-connection remote_port settings
References
strongSwan FAQ on custom ports: https://docs.strongswan.org/docs/latest/support/faq.html
strongSwan socket-dynamic discussion: https://github.com/strongswan/strongswan/discussions/927
swanctl.conf local_port documentation: https://docs.strongswan.org/docs/5.9/swanctl/swanctlConf.htmlHope this helps anyone else investigating this limitation.