Millet Porridge

English version of https://corvo.myseu.cn

0%

OpenSSH Series 6: Port Forwarding

Proxy server

Some readers may have heard of shadowsocks, which allows users to access the Internet through a remote server. Well, OpenSSH can do the same thing.

1
~ ❤  ssh -D 9000 ali

It means you listen to the 9000 ports as an entry port for proxy. A good way to test this is to use the Firefox proxy settings.

Well, you could check the port by using netstat:

1
2
3
4
5
~ ❤  netstat -tnlp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 23882/ssh
...


You probably know that OpenSSH tunnels can be used to handle traffic, let me give you two more specific examples of packet communication.

Remote Port Forwarding

Cast local port to the remote port.

Here is a scenario, when I need to develop on my local host, I have an HTTP service listening on TCP port 8080. Now, if I want to share this service to a remote host, so that anyone who has access to the remote host can access my service.

Here is the command:

1
2
# In local host: cast local 8080 to the remote 8080
~ ❤ ssh -N -v -g -R 8000:127.0.0.1:8080 ali
1
2
3
4
5
6
7
8
9
10
# In remote host: we can see the port listend by ssh daemon
root@xxx ~$ netstat -tnlp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 26741/sshd
...

# Use curl to access the service
root@xxx ~$ curl 127.0.0.1:8000
<html>
</html>

Here is the configuration:

1
2
3
4
5
6
7
8
9
10
Host ali
HostName 1.2.3.4
Port 22
User root
IdentityFile ~/.ssh/id_rsa_test
RemoteForward 8000 localhost:4000

Controlmaster auto
Controlpath ~/.ssh/ssh-%r@%h:%p.sock
ControlPersist 600

Local Port Forwarding

Cast remote port to the local port

There is also a situation where I am running a MySQL host on a remote host, listening on TCP port 3306. But incoming traffic to that port has been blocked by iptables, which means I can’t directly access MySQL with remote_host:3306.

1
2
3
4
## There is an mysql service in the remote host
root@xxx ~$ netstat -tnlp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 28498/mysqld

Now, I can use OpenSSH to forward traffic to the remote hosts:

1
2
3
4
5
6
7
8
9
10
## ssh will convert the traffic to `local_host:13306 => remote_host:33061
~ ❤ ssh -L 13306:127.0.0.1:3306 ali

## In local host, ssh listen to the 13306
~ ❤ netstat -tnlp
tcp6 0 0 :::13306 :::* LISTEN 27577/ssh:
...

## In local host, we could use mysql directly
~ ❤ mysql -u root -h 127.0.0.1 -P 13306 -p

It’s also can be used in ssh_config.

1
2
3
4
5
6
7
8
9
10
Host ali
HostName 1.2.3.4
Port 22
User root
IdentityFile ~/.ssh/id_rsa_test
LocalForward 13306 127.0.0.1:3306

Controlmaster auto
Controlpath ~/.ssh/ssh-%r@%h:%p.sock
ControlPersist 600