I have this port forwarding solution for testing purposes. There is a distant server named box and a local machine named tower, on two separate networks. box is accessible through the internet.
On tower, I run the following command:
ssh -R 80:localhost:80 box.sleblanc
This connects to box and setups a socket on port 80 that will access a web service on tower, port 80. When a connection is established with box:80, I find that it appears to the web service in the logs as coming from 127.0.0.1. I find this annoying as I cannot reliably distinguish between the connections that are legitimately from my localhost as opposed to those that come from via the proxy.
By setting the
BindAddress option to something different (e.g. 192.168.0.100) the connections to the proxy actually show up as that address instead, which solves my problem, but it forces my service to run on a network address other than localhost.
I found that running
curl --interface 127.0.0.2 localhost:80 will produce requests from the IP address
127.0.0.2, which fulfills my requirement of being able to distinguish between legitimately local requests versus proxied requests, however, when setting
BindAddress to 127.0.0.2, SSH can no longer reach box, as the 127.0.0.0/8 network is not routeable.
Ultimately, my question is: how can I bind the SSH client to multiple different addresses, so that the client can connect to an Internet host while the remote port redirection will come from an unrouteable address other than 127.0.0.1? That is, strictly bind connections to the remote forwarded port to the local address 127.0.0.2?
Toying with socat, I discovered this solution:
% socat TCP4-Listen:1234,fork TCP:127.0.0.1:80,bind=127.0.0.2 &
% ssh -R 80:127.0.0.1:1234 box.sleblanc
This sets up a socket on that listens to incoming connections on port 1234 and forwards them to 127.0.0.1:80 by binding to the local address 127.0.0.2. It works exactly as intended, but I am wondering if there is a way to streamline this into the SSH command.