开发中经常会需要用到端口映射这种事情。以前觉得好容易混淆。其实用习惯了就会发现如此简单┑( ̄Д  ̄)┍,下面联系到我日常使用到的一些ssh映射实例讲解一下

  1. -D参数,提供一个socket5级别的代理。

    这个在很多年以前翻墙的时候还是很好用的。不过都已经成为了历史。有代理使用经验的开发者都能很快理解这个玩意

  2. -L(local forward)本地转发

    比如你现在需要连接到正式环境的数据库,那么你不需要先ssh到正式环境再输入数据库命令。我的做法是选择用图形界面查看数据库。命令是这样的

    1
    ssh -L  6789:192.168.10.10:5432 prod

    含义就是将本地6789端口接受到的请求转发到生产环境prod上面的192.168.10.10:5432,这样本地GUI数据库管理程序就能够直接连接本地6789端口显示线上数据了。可以看出它的作用就是将本地端口的请求转发的服务器上面

  3. -R(Remote forward)远程转发

    这个就是和本地转发相反。在连接的服务器上打开一个端口,映射到自己的端口。此时数据流是服务器端口接收到的数据传到了本地。比如你需要一个公网ip(显然我们的办公环境都是没有公网ip的)来调试你的web应用,比如你本地写了个web程序监听8989端口,你远程服务器上有公网ip。你需要把web程序临时分享到公网给别人尝试使用。执行以下命令

    1
    ssh -R 4321:127.0.0.1:8989 prod

    这样别人访问prod_ip:4321就会映射到你本地的8989端口上。

  4. 助记

    刚开始可能觉得端口比较容易混淆。只需要记住xx:xx,前面是入口,后面是出口。本地转发的时候数据是从本地发到远程。所以6789是本地端口。远程转发的时候数据是从远程发到本地。所以8989是本地端口

  5. 辅助参数及工具

    假如你只需要端口映射不需要进入终端执行命令。可以增加-Nf参数,-N为不进入交互式终端。f为后台执行。假如你需要长期使用,那就使用autossh,和ssh一个套路。就不举例了

扩展

其实本地转发和远程转发已经形成了一个双向的数据流动。这样我们就能够实现一些看起来很高级的功能。比如访问内网机器(没有公网ip,不能够被直接访问到)。只要内网机器能够使用ssh访问到外部机器,而这台外部机器我们能够进行访问。那么此时就是搭配本地转发和远程转发的时候了。(注意,如果外部机器能够和内部机器双向访问那么会更简单)

思路就是使用内网机器访问外部机器,使用远程端口映射,将本机的22端口映射到外部机器的任一端口上。之后在外部机器就能够使用ssh localhost -p xx访问到内网机器了。然而这需要我们先登录到外部机器再使用localhost登陆到内网。此时我们可以更简单的使用~/.ssh/config配置文件完成

1
2
3
4
Host demo
user ficapy
HostName localhost
ProxyCommand ssh prod -W %h:7890

ssh demo后会先连接外部机器prod,再将请求转发到localhost:7890上完成对内部机器的登陆。
假如内部机器和外部机器可以双向访问,那么就不需要远程端口转发,只需要这样

1
2
3
4
Host demo
User ficapy
HostName 内网机器ip
ProxyCommand ssh prod -W %h:%p

更坑爹的情况

在严格的环境下,假如禁用了ssh协议。不允许从内部ssh到外部。只允许对外发送http、https请求。此时ssh、ngrok1.7版本、frp这种是无法使用的。推荐使用pagekite自建,亦或者使用速度暴慢的ngrok付费版
遇到过一个问题。测试机上需要访问10.19.2.96的1234和5053端口。处理方案是将10.19.2.96此ip绑定到网卡上面配合ssh转发,sudo ifconfig en0 10.19.15.34 netmask 255.255.255.0 up。然后ssh -NL 10.19.15.34:1234:10.19.15.34:1234 -L 10.19.15.34:5053:10.19.15.34:5053 dev就可以了

收集的ssh配置文件(更好的连接到远端服务器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Host	   *
Port 22
User root
StrictHostKeyChecking no
IdentityFile ~/.ssh/id_rsa
ConnectTimeout 15
ConnectionAttempts 3
ServerAliveInterval 20
ServerAliveCountMax 5
# 多条连接共享
ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
# 长连接(退出服务器后连接依然可重用)
ControlPersist 4h
# 减少延迟
GSSAPIAuthentication no
# 选择合适的Ciphers和MACs http://www.wreck.net/ssh_speed
Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com
MACs umac-128-etm@openssh.com,umac-128@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha1,hmac-sha2-512-etm@openssh.com,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-256
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
HostKeyAlgorithms ssh-ed25519,ssh-rsa
ChallengeResponseAuthentication no
UseRoaming no