天天看點

SSH反向連接配接及Autossh

最近因為工作需要,要給生産環境的MySQL在雲上搞災備執行個體【 專有網絡的VPC主機,×××專線太貴,走公網又不安全,暫時準備用ssh隧道跑着試試看】

0.接觸Linux恐怕對SSH再熟悉不過了,還有scp,sftp各種友善的功能,一般的使用都需要ip:port(如果不是預設22的話),但有些情況比較特殊,就是想連接配接一台内網主機(比如公司内網,當然你肯定做不了Port Forwarding,除非你想在公司防火牆上拆個洞)。稍懂一點網絡的童鞋會明白,Internet上去主動連接配接一台内網是不可能的,一般的解決方案分兩種,一種是端口映射(Port Forwarding),将内網主機的某個端口Open出防火牆,相當于兩個外網主機通信;另一種是内網主機主動連接配接到外網主機,又被稱作反向連接配接(Reverse Connection),這樣NAT路由/防火牆就會在内網主機和外網主機之間建立映射,自然可以互相通信了。但是,這種映射是NAT路由自動維持的,不會持續下去,如果連接配接斷開或者網絡不穩定都會導緻通信失敗,這時内網主機需要再次主動連接配接到外網主機,建立連接配接。

1.理論的介紹完了,下面實際操作:

A要控制B

A主機:外網,ip:123.123.123.123,sshd端口:2221

B主機:内網,sshd端口:2223

無論是外網主機A,還是内網主機B都需要跑ssh daemon

1.1.首先在B上執行

$ ssh -NfR 1234:localhost:2223 [email protected] -p2221
      

這句話的意思是将A主機的1234端口和B主機的2223端口綁定,相當于遠端端口映射(Remote Port Forwarding)。

這裡每次需要輸入A主機user1的登陸密碼,後面會講到解決辦法。

1.2.這時在A主機上sshd會listen本地1234端口

$ ss -ant
State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port
LISTEN     0      128               127.0.0.1:1234                     *:*
      

1.3.像平時一樣連接配接到A主機的1234端口就可以控制内網B主機了

$ ssh localhost -p1234
      

2.一開始提到,這種反向連接配接(Reverse Connection)不穩定,可能随時斷開,需要内網主機B再次向外網A發起連接配接,這時需要個“朋友”幫你在内網B主機執行這條指令。它就是Autossh。

在此之前還要解決之前的一個問題,那就是每次内網主機B連接配接外網主機A時都需要輸入密碼,這個問題ssh本身是提供另外一種驗證方式——通過密鑰驗證使用者身份,實作自動登入。

2.1.在内網B主機上生産公鑰和私鑰

$ ssh-keygen
...(一直按Enter,最後在~/.ssh/下生成密鑰)
$ ls ~/.ssh/
id_rsa id_rsa.pub known_hosts
      

2.2.複制B主機上生成的id_rsa.pub公鑰到外網A主機上,并将内容加入到~/.ssh/authorized_keys中

$ cat id_rsa.pub >> ~/.ssh/authorized_keys
      

試下,内網B主機連接配接外網A主機,就不再輸入密碼驗證了

補充:今天了解到ssh-copy-id這個指令,上面這個操作就變的簡單了

$ ssh-copy-id [email protected]
      

2.3.再來看看Autossh的用法

$ autossh -M 5678 -NR 1234:localhost:2223 [email protected] -p2221
      

比之前的指令添加的一個-M 5678參數,負責通過5678端口監視連接配接狀态,連接配接有問題時就會自動重連,去掉了一個-f參數,因為autossh本身就會在background運作。

3.終極方案:當重新開機内網B主機,誰來自動Autossh呢,加入daemon吧

以daemon方式執行,相當于root去執行autossh, ssh,這時剛才普通使用者目錄下的.ssh/authorized_keys檔案會不起效。有兩種辦法解決,一種是用autossh的參數指定.ssh路徑;另外一種是以普通使用者身份執行daemon,下面是第二種方式。

/bin/su -c '/usr/bin/autossh -M 5678 -NR 1234:localhost:2223 [email protected] -p2221' - user1
      

autossh還有很多參數,用來設定重連間隔等等。

将上面指令放入下面各啟動方式中,根據自己系統自己配置:

SysV:/etc/inid.d/autossh

Upstart: /etc/init/autossh.conf

systemd: /usr/lib/systemd/system/autossh.service

參考文章:http://www.cnblogs.com/eshizhan/archive/2012/07/16/2592902.html

實際操作:

ssh 伺服器A          用戶端 B

将用戶端B 的 公鑰i d_rsa.pub内容 拷貝到 ssh伺服器 ~/.ssh/authorized_keys 内  

[root@localhost ~]# cat /root/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA1Il0XVTxsXotDGAhe2DMt8qvDDkmq3i3bA4xgZBlBZCSTe0q7dbaAc3wYlxQUFzhoqZgkz/UwmmbtTky7GDJxVXr942ymTLrWvhnNxF8gi80miqWc+S0qblN1YOYHVeB6TX7Czqp7c7V+OVSSSe1TwzlCnduWscE3yHeGKF7BVFSL2rheEqb9uz2JxLqzZNajSNYPLdkqFVXy4YXSy2+Yef9tkXcQeQE6WFXIFn3zNClcUsnc9tiVydIIV/UlZJoKB+X53wYsscPmZsV4rGauKnVyZqCkn65cl9R0GgsqcpzgDl4df6RPnUwQu8KKmBkyL7Ut/74rknoR3k2I6oZ [email protected]

伺服器A  上

$ cat ~/.ssh/authorized_keys

sh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA1Il0XVTxsXotDGAhe2DMt8qvDDkmq3i3bA4xgZBlBZCSTe0q7dbaAc3wYlxQUFzhoqZgkz/UwmmbtTky7GDJxVXr942ymTLrWvhnNxF8gi80miqWc+S0qblN1YOYHVeB6TX7Czqp7c7V+OVSSSe1TwzlCnduWscE3yHeGKF7BVFSL2rheEqb9uz2JxLqzZNajSNYPLdkqFVXy4YXSy2+Yef9tkXcQeQE6WFXIFn3zNClcUsnc9tiVydIIV/UlZJoKB+X53wYsscPmZsV4rGauKnVyZqCkn65cl9R0GgsqcpzgDl4df6RPnUwQu8KKmBkyL7Ut/74rknoR3k2I6oZ [email protected]

測試用戶端B是否可以免密登入伺服器A

[root@localhost ~]# ssh root@*.*.*.*

Last login: Fri Oct 20 14:39:43 2017 from 60.186.216.123

# root @ iZm5e2ln1ze72tyk6xghd4Z in

用戶端B 設定:

[root@localhost ~]# cat /root/.ssh/config 

StrictHostKeyChecking no

用戶端B:

[root@localhost ~]# rpm -qa|grep autossh

autossh-1.4e-1.el7.x86_64

[root@localhost ~]# autossh -f -M 30002 -NR 20002:localhost:22 root@*.*.*.* -p22

[root@localhost ~]# ps aux|grep ssh

root 19110 0.0 0.0 80356 3564 ? Ss 13:48 0:00 /usr/sbin/sshd -D

root 23857 0.0 0.0 6456 448 ? Ss 14:23 0:00 autossh -M 30002 -NR 20002:localhost:22 root@*.*.*.* -p22

root 23858 0.0 0.0 73912 3896 ? S 14:23 0:00 /usr/bin/ssh -L 30002:127.0.0.1:30002 -R 30002:127.0.0.1:30003 -NR 20002:localhost:22 -p22 root@*.*.*.*

root 25724 0.0 0.0 143376 5524 ? Ss 14:37 0:00 sshd: root@pts/0

root 27950 0.0 0.0 112660 972 pts/0 S+ 14:53 0:00 grep --color=auto ssh

伺服器A:

# root @ iZm5e2ln1ze72tyk6xghd4Z in ~ [14:44:45] 

$ ssh [email protected] -p 20002

[email protected]'s password: 

Last login: Fri Oct 20 14:37:23 2017 from 192.168.4.135

[root@localhost ~]# ifconfig

br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

inet 192.168.4.4 netmask 255.255.255.0 broadcast 192.168.4.255

inet6 fe80::424:40ff:fe4f:c068 prefixlen 64 scopeid 0x20<link>

ether d0:17:c2:8c:4c:ca txqueuelen 0 (Ethernet)

RX packets 790553 bytes 185836627 (177.2 MiB)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 1501288 bytes 2066559368 (1.9 GiB)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

enp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

ether d0:17:c2:8c:4c:ca txqueuelen 1000 (Ethernet)

RX packets 906083 bytes 216184400 (206.1 MiB)

RX errors 0 dropped 51 overruns 0 frame 0

TX packets 1501283 bytes 2066559110 (1.9 GiB)

伺服器A可以正常登入用戶端B