ssh & X11 forwarding

概览:

SSH端口转发

SSH 端口转发是 SSH 提供的一种机制,通过 Server 和 Client 之间的加密连接中继其它端口的流量。因为连接是加密的,所以对于传输使用未加密协议(如IMAP、VNC或IRC)的信息非常有用。

网络拓补图

端口转发分类

  • 本地端口转发

本地端口转发的作用是把 Client 的某个端口的流量通过 SSH 连接转发到 Server ,如图1所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
命令格式如下:

ssh -L <local port>:<remote host>:<remote port> <SSH hostname>

假设 Client 地址是 192.168.111.2,Server 地址是 192.168.111.3。在Client 端执行如下命令:

root@client $ ssh -L 2222:localhost:22 192.168.111.3

通过上面的命令连接上 Server 后,即实现了本地端口转发。只要在 Client 上连接本地的 2222 端口等同于连接 Server 的 22 端口,如下两条命令是等价的,均是连接 Server 的 22 端口:

root@client $ ssh 127.0.0.1 -p 2222 root@client $ ssh 192.168.111.3 -p 22

但是这儿有个问题,就是 Client 的 2222 端口是监听在 lo 接口上的,因此只有 Client 可以连接,为了让其他主机也可以连接 Client 的 2222 端口,上面的命令需要加一个 -g 参数。

root@client $ ssh -gL 2222:localhost:22 192.168.111.3

这样外部其他主机也可以连接 Client 的 2222 端口了。

  • 远程端口转发

与本地端口转发相对应的是远程端口转发,其作用是把 Server 的某个端口的流量通过 SSH 连接转发到 Client ,如图2所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
命令格式如下:

ssh -R <remote port>:<local host>:<local port> <SSH hostname>

Client 上执行如下命令:

root@client $ ssh -R 2222:localhost:22 192.168.111.3

连接 Server 后,远程端口转发生效。此时在 Server 上连接本地的 2222 端口等同于连接 Client 的 22 端口,如下两条命令是等价的,均是连接 Client 的 22 端口:

root@server $ ssh 127.0.0.1 -p 2222 root@server $ ssh 192.168.111.2 -p 22

与本地端口转发不同,远程端口转发不能通过设置 -g 选项使外部主机连接 Server 的 2222 端口。
  • 动态端口转发

另外除了本地端口转发和远程端口转发外,还有一个更方便的动态端口转发。与本地端口转发和远程端口转发把流量转发到某个固定主机的固定端口不同,动态端口转发是根据数据包的目的IP和目的端口实现动态转发的,工作机制类似于代理,如图3所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
命令格式如下:

ssh -D <local port> <SSH hostname>

Client 上执行如下命令:

root@client $ ssh -D 1080 192.168.111.3

为了让外部机器也可以连接,需要添加-g 参数:

root@client $ ssh -gD 1080 192.168.111.3

如此,发往 Client 1080 端口的数据包将通过 SSH 连接发往 Server ,并在 Server 上重新发起请求。

实践

  • Command Test
1
ssh -gD 1080 user@ip

以windows和putty为例。

配置好点 open ,输入账号密码登陆即可。现在一个简单的代理服务已经运行起来了。接下来是浏览器的配置,这里以 Chrome 为例,配置如图6所示。

这里我用到了一个很好用的 Chrome 插件 “SwitchyOmega”,用于设置浏览器的代理。用其他代理插件或 Windows 自带的代理设置也是同样的配置:

1
2
3
protocol:socks5
server:127.0.0.1
port:1080

X11 forwarding

multipass —x11–> Mac OSX

Docker 也可以,只是我习惯用multipass。

Multipass

https://multipass.run

Launch an instance : Mine: multipass launch --name primary -c 2 -d 50G -m 2G lts

See your instances. multipass list

1
2
Name                    State             IPv4             Image
primary Running 192.168.64.2 Ubuntu 18.04 LTS

into the instances:

1
export DISPLAY=xx.xx.xx.xx:0.0

(replace xx.xx.xx.xx with the IP address obtained above).

To test the setting, we can run in the host some simple program:

1
sudo apt install x11-apps

wait xquartz start successful.

1
xlogo & # or xclock

Mac OSX:

  • install xquartz. You can also install xquartz using homebrew by running brew cask install xquartz
  • install socat brew install socat

Note, you will have to log out and log back in to your machine once you have installed xquartz. This is so the X window system is reloaded.

Once you have installed all the prerequisites you need to allow connections from network clients to xquartz. Here is how you do that. First run the following command to open xquart so you can configure it:

1
open -a xquartz

Click on Security tab in preferences and check the “Allow connections” box:

Next, you need to create a TCP proxy using socat which will stream X Window data into xquart. Before you start the proxy you need to make sure that there is no process listening in port 6000. The following command should not return any results:

1
lsof -i TCP:6000

Now you can start a local proxy which will proxy the X Window traffic into xquartz which acts a your local X server:

1
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"