OpenVPN client connected to a server while listening to SSH?
I want to have a Linode with:
SSH server listening to the Linode's public IP port 22
OpenVPN (client!) connected to an external OpenVPN server
Tunnel all the traffic that the Linode generates through the OpenVPN.
I have created a fresh new Linode (with Ubuntu) to do my tests. I thought it was a fairly easy setup, but I am running into issues.
Basically, as soon as I start the OpenVPN, any SSH connection drops, and I cannot connect again to the Linode at all using its public IP.
I am far from being an expert with iptables, and I cannot find the magic lines that will let me connect via SSH to my Linode while the OpenVPN tunnel is on.
Can anyone tell me how to get this configuration working? Or maybe point me to a website where it is explained? I have googled it and all I can find is people asking the same question - but no answers…
Thanks a lot in advance,
Fernando
16 Replies
This will mean all traffic to your local IP address will bypass the VPN. Them's the breaks.
"ip route add
I have no idea how to continue from here…
(First, I assume you've tested the VPN and verified that it's actually working, i.e. you can make connections from your Linode and they're routed over the VPN.)
This is a classic problem: when you connect to the Linode by its public IP address, the return packets get routed over the VPN. You need to force these packets to be routed over the public eth interface. These route commands should do the trick:
ip rule add from x.x.x.x table 128
ip route add table 128 to y.y.y.y/y dev ethX
ip route add table 128 default via z.z.z.z
Where x.x.x.x is your Linode's public IP, y.y.y.y/y should be the subnet of your Linode's public IP address, ethX should be your Linode's public Ethernet interface, and z.z.z.z should be the default gateway.
For example:
ip rule add from 172.16.9.132 table 128
ip route add table 128 to 172.16.9.0/24 dev eth0
ip route add table 128 default via 172.16.9.1
Note that this will apply to all ports, not just ssh. If you only want to accept ssh traffic on your public IP address you'll need iptables rules like these:
iptables -A INPUT -d x.x.x.x -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -d x.x.x.x -j DROP
(again, x.x.x.x is your public IP address)
I have created two little bash files for /etc/network/if-up.d and if-down.d to run those 3 lines automatically using the real values of the network.
And as far as I can tell, everything is working correctly! OpenVPN up and running, traffic going through the VPN, and SSH still listening (and replying) through eth0.
For the record, I had ufw with a single allow rule for the SSH port - that seems to work now even after these changes.
Thank you again AGWA! Very much appreciated.
Regards, Fernando
@AGWA:
Hi,
(First, I assume you've tested the VPN and verified that it's actually working, i.e. you can make connections from your Linode and they're routed over the VPN.)
This is a classic problem: when you connect to the Linode by its public IP address, the return packets get routed over the VPN. You need to force these packets to be routed over the public eth interface. These route commands should do the trick:
ip rule add from x.x.x.x table 128 ip route add table 128 to y.y.y.y/y dev ethX ip route add table 128 default via z.z.z.z
Where x.x.x.x is your Linode's public IP, y.y.y.y/y should be the subnet of your Linode's public IP address, ethX should be your Linode's public Ethernet interface, and z.z.z.z should be the default gateway.
For example:
ip rule add from 172.16.9.132 table 128 ip route add table 128 to 172.16.9.0/24 dev eth0 ip route add table 128 default via 172.16.9.1
Note that this will apply to all ports, not just ssh. If you only want to accept ssh traffic on your public IP address you'll need iptables rules like these:
iptables -A INPUT -d x.x.x.x -p tcp --dport 22 -j ACCEPT iptables -A INPUT -d x.x.x.x -j DROP
(again, x.x.x.x is your public IP address)
Does this work over IPSEC? Thank you AGWA, looking forward to making my own bash file
My issue is that my distro / kernel doesn't support "ip rule".
I would like to achieve the same thing using iptables instead.
Alternatively, if I could somehow route traffic from certain IPs via tun0, then I wouldn't need to push "redirect-gateway def1 bypass-dhcp" which causes the problem.
I have wasted hours of my life on this problem. Any ideas? Thanks.
> My issue is that my distro / kernel doesn't support "ip rule".
Is it that the "ip" command doesn't exist, or does it exist but your kernel doesn't support it? If it's the former, look for a package called "iproute" or "iproute2." If it's the latter, are you using a stock kernel or did you compile your own? If you compiled your own, compile a new one with "IP: Advanced Router" support (CONFIGIPADVANCED_ROUTER). I'd be very surprised if a distro shipped a kernel without this enabled, or didn't have an iproute package available - this is pretty mainstream stuff.
I'm pretty sure it's not possible to accomplish this with iptables. You need to cause certain packets to use a different default gateway, which iptables can't do on its own.
I'm not sure what you mean by "route traffic from certain IPs via tun0." If you mean you only want to route packets to certain IPs via the VPN, you can push specific routes to the VPN client (push "route 1.2.3.4" push "route 5.6.7.8" etc.) instead of pushing redirect-gateway.
Yes the 'ip' command does exist but alas it doesn't support the 'rule' option. I'm actually running on a Synology NAS box backed with BusyBox. I don't much fancy compiling a kernel for this thing either.
nas> ip
BusyBox v1.16.1 (2012-12-11 12:54:00 CST) multi-call binary.
Usage: ip [OPTIONS] {address | route | link | } {COMMAND}
> I'm not sure what you mean by "route traffic from certain IPs via tun0."
I have a Google TV which I want to access the web via the VPN. Nothing else on my lan needs to. If it routes all of its traffic over the gateway, then I can use the TV as intended but it renders the NAS box inaccessible from anywhere outside the LAN. I now understand that I can push routes from the VPN server to the VPN client but that's not what I want
I'm not sure if the kernel supports this or how to check. I did update BusyBox and the new version does show a rule command but sadly:
nas> ./busybox-1.20.2 ip rule
ip: RTNETLINK answers: Operation not supported
ip: dump terminated
I guess that means new kernel time.
Thanks again.
> I have a Google TV which I want to access the web via the VPN. Nothing else on my lan needs to. If it routes all of its traffic over the gateway, then I can use the TV as intended but it renders the NAS box inaccessible from anywhere outside the LAN. I now understand that I can push routes from the VPN server to the VPN client but that's not what I want
I understand now. It's possible, but it too requires advanced router support, so it looks like you're stuck building a new kernel.
The rules would be something like this (warning: not tested):
ip rule add from x.x.x.x table 128
ip route add table 128 default via y.y.y.y
where x.x.x.x is your Google TV and y.y.y.y is the remote end of the VPN. If you do this, you wouldn't need to push redirect-gateway to the client.
Edit: I should mention that the "ip route" command can only be run when the VPN is up, and will go away if the VPN dies. You might want to put the "ip rule" command in a system startup script, and run the "ip route" command from an OpenVPN "up" script.
Thanks again.
@AGWA:
Hi,
(First, I assume you've tested the VPN and verified that it's actually working, i.e. you can make connections from your Linode and they're routed over the VPN.)
This is a classic problem: when you connect to the Linode by its public IP address, the return packets get routed over the VPN. You need to force these packets to be routed over the public eth interface. These route commands should do the trick:
ip rule add from x.x.x.x table 128 ip route add table 128 to y.y.y.y/y dev ethX ip route add table 128 default via z.z.z.z
Where x.x.x.x is your Linode's public IP, y.y.y.y/y should be the subnet of your Linode's public IP address, ethX should be your Linode's public Ethernet interface, and z.z.z.z should be the default gateway.
For example:
ip rule add from 172.16.9.132 table 128 ip route add table 128 to 172.16.9.0/24 dev eth0 ip route add table 128 default via 172.16.9.1
Note that this will apply to all ports, not just ssh. If you only want to accept ssh traffic on your public IP address you'll need iptables rules like these:
iptables -A INPUT -d x.x.x.x -p tcp --dport 22 -j ACCEPT iptables -A INPUT -d x.x.x.x -j DROP
(again, x.x.x.x is your public IP address)
Seriously, thank you, this is with your advice I finally complete a huge project
Regards.
Thanks in advance
ip -6 rule add from 2a01:7e00::x:x:x:x table 129
ip -6 route add table 129 to 2a01:7e00::/64 dev eth0
ip -6 route add table 129 default via fe80::1 dev eth0
Sorry to resurrect this post but it may help someone else like myself in the future. I have completed the above steps using my IP/gateway info and I can successfully connect my VPN and keep SSH connections alive, but my DNS seems to no longer be working when connected to the VPN.
I ran these steps (substituting my IP/Gateway/Subnet):
ip rule add from x.x.x.x table 128
ip route add table 128 to y.y.y.y/y dev ethX
ip route add table 128 default via z.z.z.z
And connected my OpenVPN connection while remaining connected via SSH.
I can then ping remote servers via their IP address, but not their domain name
and I can ping a remote server via IP:
PING 172.217.15.78 (172.217.15.78) 56(84) bytes of data.
64 bytes from 172.217.15.78: icmpseq=1 ttl=53 time=89.0 ms 64 bytes from 172.217.15.78: icmpseq=2 ttl=53 time=87.10 ms
64 bytes from 172.217.15.78: icmp_seq=3 ttl=53 time=88.6 ms
but not via domain name:
ping: google.com: Temporary failure in name resolution
Is there an additional step I need to take to ensure DNS works with my VPN activated? I use this same VPN service on my local desktop with no issues.
Thanks!
@tokenwizard I'm having the exact same issue, have you found a solution?
I'm about to start investigating what's wrong with the DNS after I connect my remote server to a VPN via OpenVPN, but it would be nice to have a heads up :)
Anyone can help with this?