SSH out of specific interface
I have a remote, unmanned system that I need to be able to communicate with (it's not remote yet, I still have time to set things up first). It has three internet connections through three different network interfaces for redundancy, all of which are behind NATs with no ability to set up port forwarding.
I want to set up the system to autonomously open and maintain reverse SSH tunnels back to home base so I can connect to it from here, and I would like to be able to open one tunnel per interface using three different ports on the server it's connecting to (eg: the wired interface will open a tunnel to port 9000 on my machine, the wifi interface will go to 9001, the cell interface to 9002, so I can then SSH into the system on any of the three interfaces by picking the appropriate port). The tunnels aren't the problem, but controlling which interface is used to open it is what's giving me grief. I'd rather not change the default gateway/NIC for the entire system every time I open up a tunnel, but I don't think I can use routing rules either since all of these tunnels will be going to the same IP. Do I need to set up a specific route, open the tunnel, delete the route, set up the next route, open the next tunnel, delete the route, etc.? That seems kludgey, but maybe that's the only way to do it? I've seen mention of SSH's "-b" flag, but either it doesn't do anything or I don't know how to use it, because no matter what NIC's IP I put there it always goes out through the system default. |
You can use rule-based routing to route according to various packet fields, including transport protocol ports. Look at the documentation for the "ip" command and scroll down to "ip rule - routing policy database management". The first step of that learning curve is steep, but it gets a lot easier once you get a handle on it. You can find a lot of help by searching for linux+advanced+routing. Here is one useful intro.
|
And, quite frankly, the situation that you are describing would be much better solved by OpenVPN, which is designed to act as a secure router. Furthermore, because by default it uses the UDP protocol rather than TCP/IP, it has no "open socket" to be scanned. If you use its "tls-auth" feature, it can conceal its very existence. Simply connect to the tunnel that you want. If, and only if, you possess the tls-auth certificate and a non-revoked credential certificate, you pass right through. Everyone else in the world finds ... absolutely nothing.
You no longer need "this multiple port nonsense." Each NIC should have its own public IP-address and OpenVPN is told to listen on all three. If any NIC goes down (very unlikely, in my opinion ...), simply use another address. Personally, I question the actual need to have three NICs "for redundancy," because I've never known a NIC to conk-out. Usually, it is the machine that conks out, if anything ever does. |
Quote:
|
Quote:
Quote:
|
Also networks fail, different NICs can go via different ISPs and thus different networks. Say a case where you have one ISP being required because of nepotism, personal investments, or some combination like that but can't maintain availability because of key components like DNS being on playdough like M$. So a second NIC is installed with a second ISP for increased availability to the actual paying customers. Just hypothetically of course. Not that something like that could actually happen or that anyone burned would still be bitter.
Can you say a bit more about how you have been trying -b with the client that sets up the reverse tunnels? |
Three followup questions: Which version of the SSH client do you have? Does ping with the -I option work as expected? How about traceroute with -g, -i, etc?
|
I've done some more testing, and it looks like ssh's "-b" flag only works if the interface you feed it is also the default route. If you give it anything other than the default route it just hangs. Same goes for ping's -I.
eg: Wired interface on internal LAN: 192.168.1.212 Wifi interface on guest LAN: 10.1.10.13 Cell interface: 10.1.1.108 Code:
$ ip route OpenSSH_6.7p1 Debian-5+deb8u3, OpenSSL 1.0.2j 26 Sep 2016 |
Getting closer...
I realized that the problem above is that, while it is using the specified interface with ssh's "-b" or ping's "-I", it's still trying to use the gateway specified in the default route to get there. Since the default gateway is only accessible from its associated interface, that's the only interface that actually works when I use ssh's "-b" or ping's "-I". After some more reading I determined I need policy routing to get where I'm trying to go. Unfortunately the board I'm working on did not have policy routing built into the kernel, so I had to re-build and flash the kernel to get that going. Now that the kernel supports policy routing, I created 3 routing tables (one per interface), each one with its own default gateway, to be used whenever the source address matches the rule. I can now ssh out correctly using "-b" to specify the source address, but unfortunately doing this broke my ability to ssh in on the wired interface for some reason. Still looking into that... Code:
$ echo "1 wired" >> /etc/iproute2/rt_tables |
Fixed the last remaining problem, everything above was fine, I just needed an extra rule in each of the routing tables to handle the local subnet
Code:
$ ip route add 192.168.1.0/24 dev enx00e100005614 proto kernel scope link table wired Code:
CONFIG_IP_ADVANCED_ROUTER=y |
All times are GMT -5. The time now is 11:19 PM. |