How can I achieve OpenVPN client routing without NAT on Linode
Solution 1
Answering my own question:
As further background, these machines are hosted on Linode. It turns out that they use static maps in their switches in order to route traffic to specific nodes on the LAN. Since the VPN source IPs aren't part of those static maps, the traffic wasn't routed anywhere.
So this turns out to be a Linode specific issue, but hopefully it can help others to know that.
Solution 2
Since you found that the connection between Machine A and Machine B is not really a switched Ethernet, and that it can only handle traffic using the IP addresses you have been assigned, you need to find another solution.
This can be achieved through the use of a tunnel. There are various kinds of tunnels, that could be used. One is to use VPN, which might be the simplest since Machine A is already a VPN server. Then you just need to make Machine B a VPN client, and then add routing table entries to forward the needed prefixes through that VPN connection.
Another option is to use a GRE tunnel or simply IP over IP. Those tunnels and associated routes could be configured statically, which would give them an advantage over the VPN approach.
Related videos on Youtube
![Oz Solomon](https://i.stack.imgur.com/I9gDe.jpg?s=256&g=1)
Oz Solomon
Updated on September 18, 2022Comments
-
Oz Solomon almost 2 years
I've set up an OpenVPN network, and it is working properly in the sense that I can access the inner/LAN machines from the remote client. However, my problem is that all traffic from the remote machines appears to the LAN machines as though it is coming from the OpenVPN server machine, and not from the client machine.
To Better explain, consider my network topology:
Machine R connected to the OpenVPN server on Machine A, and got assigned the IP address of 10.200.200.5.
Machine R then makes a request to Apache running on Machine B. The request arrives properly and I get a response. The problem is that Machine B sees the request coming in from 192.168.0.10 (Machine A's IP) and not 10.200.200.5.
I would like the latter.
My Current Setup
Machine A
This is a snippet of the relevant iptables rules:
*nat :PREROUTING ACCEPT [18:1080] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] -A POSTROUTING -o eth0 -j MASQUERADE *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] // snip # accept incoming VPN connections -A INPUT -p udp -m udp --dport 1194 -j ACCEPT # forward VPN traffic -A FORWARD -s 10.200.200.0/25 -d 192.168.128.0/17 -i tun0 -j ACCEPT -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
I have also enabled ip_forwarding:
echo 1 > /proc/sys/net/ipv4/ip_forward
.. and made the appropriate changes to /etc/sysctl.conf to make it permanent.
In the OpenVPN configuration, I have:
server 10.200.200.0 255.255.255.128 push "route 192.168.0.0 255.255.255.0"
Machine B
Since Machine A is not Machine B's gateway, I manually added a route on Machine B as follows:
ip route add 10.200.200.0/25 via 192.168.0.10 dev eth0
To test the which IP is being routed, I created a small PHP script called showip.php:
<?php echo "Your IP is: ", $_SERVER['REMOTE_ADDR'], "\n"; ?>
Machine R
# wget -q -O - http://192.168.0.11/showip.php Your IP is: 192.168.0.10
How do I get it to say 10.200.200.5?
Update
To clarify, in my particular case Machine A has one NIC (eth0) which serves both the LAN and WAN.
-
Zoredache about 10 yearsWhy do you have a nat rule enabled in your firewall if you don't want NAT? Perhaps you should start by removing your
-A POSTROUTING -o eth0 -j MASQUERADE
and figure out what happens? Also your question is unclear, since you haven't told us ifeth0
is the lan or wan interface. In any case, you should be looking at traceroutes and tcpdump. These are the tools that help solve routing problems. -
Oz Solomon about 10 yearsTo answer some of your questions: (1) eth0 is both the LAN and WAN interface (2) As expected, removing
-A POSTROUTING -o eth0 -j MASQUERADE
makes it stop working. I'm not an iptables expert, but I believe this line is what is creating a NAT which is what I don't want, and I don't know what to replace it with (hence this question). (3) traceroutes are worthless because they either hang or return * * * * (4) I'm happy to run tcpdump if anyone can suggest what to look for
-
-
Oz Solomon about 10 yearsAs stated in the original question, Machine B already had the appropriate
ip route add
applied. If I remove the NAT/MASQUERADE line, I can no longer ping Machine B. -
kasperd about 10 years@OzSolomon In that case the problem is a little less obvious. But it can still be found. Which interface on B is connected to A? If it is eth0, then look at the output from
tcpdump -pni eth0 'host 10.200.200.5'
on host B while you are trying to request the page. -
Oz Solomon about 10 yearsThank you for your help. I have discovered the issue, please see my other answer.
-
Erico almost 10 yearsHey Oz, Actually I'm having the exactly same problem, but I'm running the servers in Amazon. Do you know if it's possible to fix that there ? Thanks.
-
Oz Solomon almost 10 years@Erico I don't know enough about AWS. I suggest you start a new question and specifically mention AWS in the question title.
-
Erico almost 10 yearsHey Oz, thanks a lot for your answer, actually I was able to make it work. It was a problem with my AWS security settings.
-
Ben Penwell almost 8 yearshow it was done in AWS would be interesting to know details of.
-
Paul Grimshaw about 6 years@Erico, could you say what security setting this was in AWS? Have same issue...
-
Paul Grimshaw about 6 years@Erico, thanks - but still wasn't working with that disabled on both servers. I have parked for now, but need to dive back into this at some point. If anyone else has any ideas in the meantime, please let me know!