VPN tunnels and "bind local address"

Nowadays most tools seem to have an option to specify the local address or local ip to use for a connection.
Surprizingly, git doesn't (in http mode). So I asked this question here - let's see what comes out of it.

The background: when connecting two machines with openvpn, for a direct connection between both, the ip routing will select the tunnel address locally because that is the outgoing interface. But this is usually a private 10.x.x.x address - it is not supposed to be used anywhere. So, to make things working, one will likely end up configuring these private addresses everywhere: DNS, firewall, webserver, documentation...

This is very undesireable. It is much nicer to tell the specific programs on the client that they should bind the regular local address. But that works only when the programs support it.
The other, more radical solution might be to always insert a NAT into both ending piers of a tunnel, for rewriting the respective address.

Ideas, improvements, comments, suggestions?
 
IP servers create sockets for binding to something for listening. IP clients create a socket and connect to servers. If you want, you perhaps can break this connection down into some sort of binding before, however this binding is not something which can be freely chosen like on the server side, since the client’s binding (if you insist on naming it as this) is determined by the IP address (or net) to which the client wants to connect.

That said, I fail to understand the rest of your problem. If the connection request from the git client does not want to go through your tunnel, then what is wrong with simply adjusting the routing table?

Look at it with netstat -nr, then add new routes using route(8).
 
use a http proxy that can specifiy bind address on its end and git thru the proxy
I agree, that would be a working solution.
Only, I don't have a http proxy at hand on the client. I just went for the NAT solution - which then actually was a matter of copying two lines of config and entering five mouseclicks - as I have alreary enabled tooling that auto-creates ipfw rulesets with an arbitrary number of filters (blacklisters, nats, forwards...) - now finally this effort seems to pay off (the headless came up with no issue and worked).
 
IP servers create a socket and bind to something for listening, IP clients create a socket and connect to servers. If you want, you perhaps can break this connection down into som sort of binding before, however this binding is not somthing which can be freely chosen as on the server side, since it is determined by the IP address (net) to which the client wants to connect.
From my experience it can be freely chosen amongst the locally configured IPs - only the client software must actively choose it instead accepting the default provided from the IP stack. It seems not to matter to which network the client then actually connects - I am rewriting and forwarding lots of things and actually do my own source-based routing from within ipfw - and all that works fine.
That said, I do not understand the rest of your problem. If the connection request from the git client does not want to go through your tunnel, then what is wrong with simply adjusting the routing table?
It is going thru the tunnel, and appears on the other side - with a client IP of 10.1.2.3 (which is the IP on the tun interface configured into openvpn).
Then any server that does any check on the client ip will not know that ip - because it is not the regular ip of the client (which it would use when going a different route). And any firewall that filters on rfc1918 does throw it away. So the consequence would be a configuration pain: making these tunnel ips known at every concerned place. That to avoid is the issue.
 
Well then this boils down to a matter of taste whether setting up NAT is more easy then one firewall rule like:
ipfw -q add xyz allow ip from any to me via tun*
 
Well then this boils down to a matter of taste whether setting up NAT is more easy then one firewall rule like:
ipfw -q add xyz allow ip from any to me via tun*
That would depend on the site configuration: specifically, this quoted rule would allow everything from the Internet onto my machine. (That machine in question is my VPN server -etc etc- and you can reach it via that tunnel - to open another tunnel within that tunnel). :)
 
See also: https://idea.popcount.org/2014-04-03-bind-before-connect/

It's talking a lot about Linux although little of this information is Linux specific. It contains a good summary at the end.

Now I get it: putting the bind-local-address option into a client program is not as simple as I thought; it is programming effort and it might introduce bottlenecks on the number of possible connections.
So one cannot expect this option to be available in any program one might want to use.
 
Yep, that's the point. You can bind(2) before you connect(2), but that's not the "normal" thing to do. So sure, it makes sense to offer such an option, but I wouldn't really expect such an option to be present. Normally, you should set up your networking in a way that doesn't require a specific client-side bind(2) for routing decisions ;)
 
Normally, you should set up your networking in a way that doesn't require a specific client-side bind(2) for routing decisions ;)
Okay so far. And I certainly agree that issues should be solved where they arise, whenever possible, insead of spreading them around. So what is a good way to do so?

Let's look at a specific situation. Given there is such a layout of machines that should act in concert, but are not directly connected (I don't know if that is practically useful or should be done, it is just something we can look at and understand the matter):
Code:
  |  ---------------                              ---------------
I |  | machine one |           openvpn            | machine three
N |--| official ip | ---------------------------- | official ip |
T |  |   1.2.3.1   |  10.0.1.1          10.0.1.2  |   1.2.3.3   |
E |  ---------------                              ---------------
R |
N |  ---------------                              ---------------
E |  | machine two |           openvpn            | machine four|
T |--| official ip | ---------------------------- | official ip |
  |  |   1.2.3.2   |  10.0.2.1          10.0.2.2  |   1.2.3.4   |
  |  ---------------                              ---------------
  |
  |.. and eventually more ...
   |

Now, when machine-one talks to machine-four, it uses it's regular IP, but when it talks to machine-three, it uses the local tunnel ip.
And any distributed application would need to know this: one cannot just say, the allowed peers are 1.2.3.0/24.
 
just create a bogus route and use ipfw fwd
here is my setup
location1 is 10.1.1.0/24
location2 is 10.1.2.0/24
they are linked thru openvpn as
10.1.4.1 --> 10.1.4.2
the gw boxes are 10.1.1.1 and 10.1.2.1 which are also connected directly to the internet
now i telnet from 10.1.1.1 to 10.1.2.1 25
telnet 10.1.2.1 25 Trying 10.1.2.1... Connected to mail.box2. Escape character is '^]'. 220 mail.box2 ESMTP of Borg. You will be assimilated; Mon, 26 Apr 2021 14:25:00 +0300 (EEST) ehlo x 250-mail.box2 Hello [10.1.4.1], pleased to meet you 250-ENHANCEDSTATUSCODES 250-PIPELINING
so the server sees my tunnel endpoint ip
now i add the bogus route
route add 10.1.2.1 10.1.1.254 add host 10.1.2.1: gateway 10.1.1.254
ping 10.1.2.1 normally times out because 10.1.1.254 does not exist / and does not even arp-resolve

now we force packets from 10.1.1.1 to 10.1.2.1 thru openvpn ignoring kernel route
ipfw add 5 fwd 10.1.4.2 ip from 10.1.1.1 to 10.1.2.1 00005 fwd 10.1.4.2 ip from 10.1.1.1 to 10.1.2.1 telnet 10.1.2.1 25 Trying 10.1.2.1... Connected to mail.box2 Escape character is '^]'. 220 mail.box2 ESMTP of Borg. You will be assimilated; Mon, 26 Apr 2021 14:32:58 +0300 (EEST) ehlo x 250-mail.box2 Hello [10.1.1.1], pleased to meet you 250-ENHANCEDSTATUSCODES
and im seen as 10.1.1.1

this was/is a common trick for ipsec ESP tunnels (create gif to get a tunnel-able ip without the need to specify a client bind address every time you needed to connect to services on the other part of the tunnel -- you just didn't need the ipfw fwd part because the ipsec policy was doing just that)
 
Now, when machine-one talks to machine-four, it uses it's regular IP, but when it talks to machine-three, it uses the local tunnel ip.
And any distributed application would need to know this: one cannot just say, the allowed peers are 1.2.3.0/24.
Unless I'm missing something here, why not simply have a route to 1.2.3.3/32 via the tunnel on machine 1 and that's it (similar on machine 2)? You'll might need an OpenVPN iroute to go with that, but it shouldn't be a problem. Does the whole thing even work without such a route? :-/
 
if 1.2.3.X are real public IPs and you just want traffic to be encrypted between you boxes its probably be easier to just use ipsec in transport mode and forget about tunnels
 
just create a bogus route and use ipfw fwd
That one does work, yes.

if 1.2.3.X are real public IPs and you just want traffic to be encrypted between you boxes its probably be easier to just use ipsec in transport mode and forget about tunnels
In my case, I don't even care about the encryption, because it's public traffic. I just use the tunnels to move spare IP addresses to the place where I want to compute. ;)
 
Back
Top