How To Chain SSH Tunnels - networking

I am trying to set up a simple SSH tunnels chain.
I have the following machines:
local machine, at 10.0.0.1.
remote machine, at 10.0.0.2.
I have the following programs:
client.py:
import socket
CLIENT_HOST = [...]
CLIENT_PORT = [...]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.connect((CLIENT_HOST, CLIENT_PORT))
sock.send('test')
sock.close()
server.py:
import socket
SERVER_HOST = [...]
SERVER_PORT = [...]
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((SERVER_HOST, SERVER_PORT))
server.listen(1)
client = server.accept()[0]
print client.recv(1024)
client.close()
server.close()
Now:
I run client.py (CLIENT_HOST='127.0.0.1', CLIENT_PORT=8000) and server.py (SERVER_HOST='', SERVER_PORT=8000) on the same machine, and it works as expected.
I run client.py (CLIENT_HOST='127.0.0.1', CLIENT_PORT=8000) on the local machine, and server.py (SERVER_HOST='', SERVER_PORT=8001) on the remote machine. I then run PuTTY and add a local SSH tunnel with the source port 8000 and the destination 10.0.0.2:8001, and it works as expected.
I run client.py (CLIENT_HOST='127.0.0.1', CLIENT_PORT=8001) on the remote machine, and server.py (SERVER_HOST='', SERVER_PORT=8002) on the local machine. I then run PuTTY and add a remote SSH tunnel with the source port 8001 and the destination 127.0.0.1:8002, and it works as expected.
However, when I run client.py (CLIENT_HOST='127.0.0.1', CLIENT_PORT=8000) and server.py (SERVER_HOST='', SERVER_PORT=8002) on the local machine, and run two PuTTYs, one with a local SSH tunnel from source port 8000 to destination 10.0.0.2:8001, and one with a remote SSH tunnel from source port 8001 to destination 127.0.0.1:8002, nothing happens.
As I see it, the message from client.py should be sent to the local machine's port 8000, where PuTTY listens and should redirect it via SSH to the remote machine's port 8001, where a PuTTY listens and should redirect it via SSH to the local machine's port 8002, where it should reach server.py.
What is wrong, and how do I fix it?
Thanks.

You probably need to tick 'Local ports accept connections from other hosts' and 'Remote ports do the same'.
By the way, netcat is a more useful standard utility for trying this kind of thing out, if it's available on your OS.

Related

reverse tunnel with ssh: channel 0: connection failed: Connection refused

I am trying to set up a reverse ssh tunnel between a local machine behind a router and a machine on the Internet, so that the Internet machine can tunnel back and mount a disk on the local machine.
On the local machine, I type
/usr/bin/ssh -N -f -R *:2222:127.0.0.1:2222 root#ip_of_remote_machine
This causes the remote machine to listen on port 2222. But when I try to mount the sshfs disk on the remote machine, I get "connection refused" on the local machine. Interestingly, port 2222 doesn't show up on the local machine as being bound. However, I'm definitely talking to ssh on the local machine since it complains
debug1: channel 0: connection failed: Connection refused
I have GatewayPort set to Yes on both machines. I also have AllowTcpForwarding yes on both machines as well.
First, the line needs to be
/usr/bin/ssh -N -f -R *:2222:127.0.0.1:22 root#ip_of_remote_machine
Where port 22 represents the ssh server of the local machine.
Second, since I am using sshfs, the following line needs to be in its sshd_config
Subsystem sftp /usr/lib64/misc/sftp-server

HTTP request to VM

I have a jetty server running under port 8080 on VM. VM in its turn runs on remote server under port 10000. Is it legit to address it as http://someremote.org:10000:8080/request? Or should I use SSH somehow?
What I was looking for is called ssh tunneling. You make a tunnel from your port to remote's machine port like that:
ssh -p 10000 -L 18080:localhost:8080 user#remote.host.org
18080 here is port, that you use on your local machine in order to get to remote's 8080 port.

SSH forward port to local host name

I have next setup:
Local host - my work PC
Project VM - Vagrant box with project files, runned on my work PC
Remote host - remote PC, from which I need to access hosts on Project VM
Project VM setup (/etc/hosts on Local host):
192.168.100.102 host1.vm.private
192.168.100.102 sub1.host1.vm.private
192.168.100.102 sub2.host1.vm.private
"host1" subdomains resolved by application router and served by nginx (config for "host1.vm.private" on Project VM):
server {
listen 80;
server_name ~^(.+\.)?host1\.vm\.private$;
...
}
I need to make "sub(1|2|N).host1.vm.private" reachable from remote host. How this can be done?
So, i found the solution: Trouble SSH Tunneling to remote server
The main issue is that invalid HTTP header was sent and nginx cant resolve a virtual host.
Run on local PC ssh -R 8888:192.168.100.102:80 <remote_pc_credentionals>. Or, run "inversed" command with ssh -L flag on remote PC.
Add "sub1.host1.vm.private" to /etc/hosts on remote PC: 127.0.0.1 sub1.host1.vm.private
OR
Send "Host" header with each request: curl -H "Host: sub1.host1.vm.private" "http://localhost:8888/some/path"

Can't connect to local MySQL server through socket error when using SSH tunel

I am trying to use dplyr to connect to a remote database, that I usually query through a ssh tunnel.
I first set up a ssh tunnel like the following:
alias tunnel_ncg='ssh -fNg -L 3307:127.0.0.1:3306 mysqluser#myhost mysql5 -h 127.0.0.1:3306 -P 3307 -u mysqluser -p mypassword'
At this point I can access the database by connecting to localhost:3307. For example:
mysql -h '127.0.0.1' -P 3307 -u mysqluser
If I try to access the same database through dplyr, I get an error complaining that it can't connect to the local MySQL socket:
> conDplyr = src_mysql(dbname = "mydb", user = "mysqluser", password = "mypassword", host = "localhost", port=3307)
Error in .local(drv, ...) :
Failed to connect to database: Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
My understanding is that RMySQL/dplyr are trying to looking for a socket file in the local computer, however they should really be looking for it in the remote server. Is there a way to fix this, or a work-around?
UPDATE:
If I try to connect through dbConnect/RMySQL, the connection works fine:
> dbConnect(dbDriver("MySQL"), user="mysqluser", password="mypassword", dbname="mydb", host="127.0.0.1", port=3307)
<MySQLConnection:0,1>
As silly as it sounds replacing localhost with an IP address (127.0.0.1) solves the problem.
src_mysql(
dbname = "mydb", user = "mysqluser", password = "mypassword",
host = "127.0.0.1", port=3307)
For an explanation take a look at the MySQL documentation:
On Unix, MySQL programs treat the host name localhost specially, in a way that is likely different from what you expect compared to other network-based programs.
For connections to localhost, MySQL programs attempt to connect to the local server by using a Unix socket file. This occurs even if a --port or -P option is given to specify a port number.
To ensure that the client makes a TCP/IP connection to the local server, use --host or -h to specify a host name value of 127.0.0.1, or the IP address or name of the local server.

Detect conflicting forwarded ports on VM

I am using Oracle VirtualBox on Windows. I've setup NAT and forwarded ports.
When some forwarded ports are accidentally conflicting with host machine's ones, no errors are shown and all forwarded ports are failing.
Is there any possibility to detect those conflicting ports? I have used VBoxManage tool and there are neither output messages, nor verbose mode for startvm command.
Thanks
I would recommend using a combination of netstat and VBoxManage and parse the output. You can easily replace the findstr command with grep on non-Windows hosts.
First, I would get a listing of NAT ports on the VM in question. The VBoxManage showvminfo command will output a bunch of info about the configuration which you can filter to look for just the NAT rules. You will want to look for the host port and protocol fields in the output (and possibly host ip if configured) as that is what you will be looking to see if it is already in use.
C:\>vboxmanage showvminfo Linux | findstr Rule
NIC 1 Rule(0): protocol=tcp, host ip=, host port=2222, guest ip=, guest port=22
Second, using the info from above I know I need to check if anything is listening on port TCP port 2222, so I can use the netstat command to show me all the listening sockets, filtered by my criteria:
C:\>netstat -an | findstr LISTENING | findstr TCP | findstr 2222
Proto Local Address Foreign Address State
TCP 0.0.0.0:2222 0.0.0.0:0 LISTENING
Because my guest is already running I can see that it has already grabbed a connection on TCP 2222. If you don't get any output then nothing is listening on that specific port and you are safe to start your VM.

Resources