VPN where local private address collide

Terje Elde terje at elde.net
Sun Aug 18 11:51:44 UTC 2013

On 18. aug. 2013, at 12.20, Frank Leonhardt wrote:
> I'm not sure that TLS would cause more problems than any other packets, but as you point out, the exercise is bound to be full of pooh traps as yet undiscovered. FTP should be interesting, for a start. But for most things, why would swapping an IP address in the packet header cause any kind of problem as long as it was done consistently?

I was cutting corners and trying to keep the reply short (was on cellphone at the time), and I think the word headers might have lead to some crosstalk.

For TCP/IP itself, just consistently swapping the IP would solve the problem.  That'd fix a lot, and things like like ssh and http should work fine with that.

If we look at other things though, like SIP, it's not that easy.  I'm using SIP as an example just because it illustrates the point nicely, and I know it well.

For SIP, you'd have the IP in multiple places:

TCP/IP - the connection to the server.
SIP - The application protocol
RTP - Payload in the application protocol, carrying media-metadata

Now, you'd get the connection to the server (TCP/IP), but for registering against the SIP-server, the client would include it's IP in the SIP-layer as well, in a http-like header.  It'd tell the server where it would want to be contacted for things like incoming calls.  Initially this would point to the clients perspective of the IP, and not to the IP it were to carry after NAT.  That is, the client would be able to register, but for incoming calls the server would try to contact the IP in the wrong place.

For placing calls, you'd also have information about where media-streams should go in RTP, both IP and port numbers.  This would also carry wrong information if you're merely changing the IP/port in TCP/IP-layers.

Both of these can be resolved wither in the router/firewall/NAT-box, or worked around on the server, but it's not pretty by a long shot, and it's completely avoidable if you can avoid the NAT.

> There are lots of corporate networks on 10.x.x.x, and I'm told this kind of caper is used to sort them out when they collide. Paying for a Cisco VPN could easily work out cheaper than reconfiguring a large corporate LAN, but I don't have the budget for either.

This kind of thing *can* be used to sort out colliding subnets, but that doesn't mean it *should* be used to resolve the issue(s).

You mentioned that a Cisco-guy said this would work, and explained details of how to do it.

I'm thinking that the same Cisco-guy could also give details on how to drop a rack full of Juniper-equipment out of a 10th floor window, in order to replace it with Cisco-gear.  It's quite possible to do that, but again, that doesn't mean you should.

I think the gist of the issue here is that you have a problem, and you're (correctly) thinking you can solve a lot if you NAT the two networks together.  That's not wrong, it's completely true.  You can get a lot to work in that way.

Then you also have some random-looking guy on a mailing-list telling you that "Yes, you can do that.  But you shouldn't".  I get how hard it can be to take that kind of advice, especially when you know and have been told that it's quite possible.

If you really, really want to explore that route, then here's one way to go about it:

Use the VPN just to get the link up, don't worry about using NAT with MPD.  It's nice to keep all of the nat/firewall-bits in a single place, and pf is a good solution to it.

If you're running the VPN off of the primary gateway, this should be fairly straight-forward, and you should be able to use something like this:

pf.conf on gateway/vpn-endpoint in lan_a:
lan_a = ""
lan_b = ""
vpn_a = ""
vpn_b = ""

binat on $vpn_if from $lan_a to any -> $vpn_a

pf.conf on gateway/vpn-endpoint in lan_b:
lan_a = ""
lan_b = ""
vpn_a = ""
vpn_b = ""

binat on $vpn_if from $lan_b to any -> $vpn_b

The VPN-tunnel itself could ignore any concept of the conflicting, and simply deal with being on one end, and on the other.

If you're standing in lan_a, and your local address is, and you'd like to reach in lan_b, you'd talk to

In lan_a, the conneciton would be seen as ->

Crossing the lan_a VPN-endpoing going into the tunnel, it'd get rewritten to be ->
Crossing the lan_b VPN-endpoint going into lan_b, it'd get rewritten to be ->

You'd then hit the right server.

The response from (in lan_b) would get routed back over the VPN-tunnel, since it's sent to

That is, in lan_b the response would be ->

Crossing the lan_b VPN-endpoing going into the tunnel, on the way back to lan_a, it'd get rewritten to be ->
Crossing the lan_a VPN-endpoing going from the tunnel, into lan_a, it'd get rewritten to be ->

This is what you want I think?

(you'd have to fix DNS and routing as well, though routing would work out if the VPN is on the default gateway).

Now, if we take this setup, and go back to the example of SIP, so see how it'd play out over this config:

A phone at in lan_a, registeres against the SIP-server at in lan_b.

If we run the rewrites, the request comes in from to the SIP-server, and the SIP-servers response gets back through the same routing and rewriting.

All good, right?

Well, it's not quite that easy.

In the SIP-headers (not the IP or TCP headers), the phone will list something like this:

Contact: <sip:>

The server would register that the phone is available at (locally, in lan_b), while the server would actually need to send to, in order to reach in lan_a.

Exactly how this would behave depends on a lot of factors, but you'd quickly end up with a situation in which the phone *appears* to work, can register against the server and call out (both client-initiated), but where incoming calls just don't work (sent to in lan_b, rather than in lan_a).

Then you'll not only have to debug the NAT-setup, but SIP as well.

Again, there's different ways to solve this.  You could do a similar rewriting on the gateways for SIP as you do for IP, and you could solve it on the server.

Some SIP-servers actually include logic for this kind of thing by default, but that logic might not be applied because this is private IPs, which are often excluded from that kind of thing.

You could always apply the logic, but then you'd be running calls between two phones in lan_a over the VPN to lan_b and back again, because of all of this would need to be solved for RTP-headers and RTP-streams as well.

Then you have to instantly turn into not only a networking and NAT expert, but an expert on VoIP and the specific VoIP-solutions used as well.

All completely avoidable, if you were to renumber the networks instead.

And SIP is just one example.

(all of this is slightly simplified, and intending more to illustrate the poing and explain how it can be done, than as full and extensive documentation).


More information about the freebsd-questions mailing list