Reverse SSH Tunnel – 反向 SSH Tunnel

 

Reverse SSH Tunnel,通常拿來應用在客戶端的 Linux Server,是在 NAT 之後,不能直接使用 ssh,連線到 Public IP,或是,透過 DNAT 轉進去的情況!對於 SI 維護而言,能夠遠端維護,是 C/P 值很高的,但是,要注意安全就是了!

這裡是使用兩台同網段,直接連線的電腦【兩台都是 RHEL 8】做測試,但是,實際上,請想像左手邊的 servera【172.25.250.10】是在客戶端的 NAT 之後的 Linux Server右手邊的 serverb【172.25.250.11】是無法直接連線的。右手邊的 serverb,需要 Public IP,或是 DNAT 可以轉進去的連線!

 

遠端 – 客戶端的Linux Server           本地端 – SI 廠商的Linux【Public IP】

servera【172.25.250.10】            serverb【172.25.250.11】

 

在遠端 – 客戶端的Linux Server【servera】,先產生一組 ssh key pair,用來登入 SI 廠商的 Linux,可以自動登入,不需要密碼【因為要自動登入,要設定為 no passphrase

[root@servera ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+eyuXfR5ObDqyy2yHyWnURHmdNHSPE0Kqm7roKX5Ou0 root@servera.lab.example.com
The key's randomart image is:
+---[RSA 2048]----+
|            .=.*=|
|           .+.+o=|
|          .  o...|
|         o  .    |
|        S  o.+   |
|       . o .*.o..|
|     .o o oo..oo.|
|    .=.o =.o+  ..|
|    ==E.++O*o.   |
+----[SHA256]-----+
[root@servera ~]#

 

在本地端 – SI廠商的Linux【serverb】,建立一個非root帳號,專門給特定廠商連線,這台Linux最好是台專用的虛擬機,不提供其他服務,要注意安全。

[root@serverb ~]# useradd test1
[root@serverb ~]#
[root@serverb ~]# echo "12345678" | passwd test1 --stdin
Changing password for user test1.
passwd: all authentication tokens updated successfully.
[root@serverb ~]#

切換到遠端 – 客戶端的Linux Server【servera】,將剛剛產生的 ssh 的 Public Key,複製過去

[root@servera ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub test1@172.25.250.11
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
test1@172.25.250.11's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'test1@172.25.250.11'"
and check to make sure that only the key(s) you wanted were added.

[root@servera ~]#

 

遠端 – 客戶端的Linux Server【servera】,手動建立連線

參數說明:
-N:不執行任何指令
-f:在背景執行
-R:建立Reverse Tunnel
測試時,可以考慮拿掉 -N -f,只使用 -R

[root@servera ~]# /usr/bin/ssh -NfR 2222:localhost:22 test1@172.25.250.11 -p 22
[root@servera ~]#

 

在本地端 – SI廠商的Linux【serverb】,應該要看到一個 TCP(2222) 的連線

[root@serverb ~]# netstat -tupln | grep 2222
tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN      1422/sshd: test1
tcp6       0      0 ::1:2222                :::*                    LISTEN      1422/sshd: test1
[root@serverb ~]#

 

試著從本地端 – SI廠商的Linux【serverb】,登入到遠端 – 客戶端的Linux Server【servera】,這時候可以觀察到一個 ::1 的登入

[root@serverb ~]# ssh -p 2222 -o StrictHostKeyChecking=no root@localhost
root@localhost's password:
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Mon Feb  3 11:52:49 2020 from 172.25.250.11
[root@servera ~]# w
 12:34:10 up 45 min,  2 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    172.25.250.250   11:51    5:11   0.04s  0.04s -bash
root     pts/1    ::1              12:33    2.00s  0.02s  0.00s w
[root@servera ~]#

 

人雖然在本地端 – SI廠商的Linux【serverb】,但,已經透過 Reverse SSH Tunnel 登入到 客戶端的Linux Server【servera】,使用 last 觀察登入紀錄

[root@servera ~]# last
root     pts/1        ::1              Mon Feb  3 12:33   still logged in
root     pts/1        172.25.250.11    Mon Feb  3 11:52 - 11:52  (00:00)
root     pts/0        172.25.250.250   Mon Feb  3 11:51   still logged in
root     pts/0        172.25.250.250   Mon Feb  3 11:50 - 11:50  (00:00)
reboot   system boot  4.18.0-80.el8.x8 Mon Feb  3 11:48   still running
reboot   system boot  4.18.0-80.el8.x8 Tue Nov 12 11:22   still running
reboot   system boot  4.18.0-80.el8.x8 Wed May 22 11:20 - 11:22  (00:01)

wtmp begins Wed May 22 11:20:27 2019
[root@servera ~]#

 

只要在本地端 – SI廠商的Linux【serverb】,kill 掉 TCP(2222) 的連線,就可以成功斷線。

[root@servera ~]# exit
logout
Connection to localhost closed.
[root@serverb ~]# netstat -tupln | grep 2222
tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN      1422/sshd: test1
tcp6       0      0 ::1:2222                :::*                    LISTEN      1422/sshd: test1
[root@serverb ~]# kill 1422
[root@serverb ~]#
[root@serverb ~]# ssh -p 2222 -o StrictHostKeyChecking=no root@localhost
ssh: connect to host localhost port 2222: Connection refused
[root@serverb ~]#

 

手動的連線已經 ok,再來要來加工,先將本地端 – SI廠商的Linux【serverb】,設定成為 crontab 排程自動建立 Reverse SSH Tunnel,這樣可以解釋,剛剛為何要先建立 ssh key pair

想要留下 LOG,可以使用這個語法

* * * * * /usr/bin/ssh -NfR 2222:localhost:22 test1@172.25.250.11 -p 22 2>&1 > /dev/null | /usr/bin/tee -a /var/log/debug | /usr/bin/logger

每分鐘自動重新連線,這樣可以省掉使用 autossh,自動重連的需求…

 

等待一分鐘之後,在遠端 – SI廠商的Linux【serverb】,就應該要看到連線已經建立了!

[root@serverb ~]# netstat -tupln | grep 2222
tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN      1492/sshd: test1
tcp6       0      0 ::1:2222                :::*                    LISTEN      1492/sshd: test1
[root@serverb ~]#

 

最後要解決的是,從 遠端 – SI廠商的Linux【serverb】,登入到 本地端 – 客戶端的Linux Server【servera】,是需要回答密碼【password】的

[root@serverb ~]# ssh -p 2222 -o StrictHostKeyChecking=no root@localhost
root@localhost's password: <-- 需要回答 root password
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Mon Feb  3 12:33:57 2020 from ::1
[root@servera ~]#

 

在本地端 – SI廠商的Linux【serverb】,產生 ssh key pair

[root@servera ~]# exit
logout
Connection to localhost closed.
[root@serverb ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:GSyljBJuuBeM8shHx8Bfs1ML0XMARoShVPK9JgM0U+o root@serverb.lab.example.com
The key's randomart image is:
+---[RSA 2048]----+
|  oBo+=*=..      |
| =ooX+oB + .     |
|+ *=o+=.B +      |
|o=ooo. +.+       |
|o.oE o oS        |
| ..   +          |
|                 |
|                 |
|                 |
+----[SHA256]-----+
[root@serverb ~]#

 

本地端 – SI廠商的Linux【serverb】的 Public key –> /root/.ssh/id_rsa.pub,複製到 遠端 – 客戶端的Linux Server【servera】

[root@serverb ~]# scp -P 2222 /root/.ssh/id_rsa.pub root@localhost:/root/.ssh/authorized_keys
root@localhost's password:
id_rsa.pub                                                    100%  410   315.2KB/s   00:00
[root@serverb ~]#

 

這樣子就可以從 本地端 – SI廠商的Linux【serverb】,自動登入到 遠端 – NAT 後面的 客戶端的Linux Server【servera】

[root@serverb ~]# ssh -p 2222 -o StrictHostKeyChecking=no root@localhost
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Mon Feb  3 13:45:26 2020 from ::1
[root@servera ~]#

 

最後,是抹掉痕跡的方式,剛剛在 本地端 – SI廠商的Linux【serverb】,crontab 排程的語法,可以改成不寫 LOG

[root@servera ~]# crontab -e
crontab: installing new crontab
[root@servera ~]#
[root@servera ~]# crontab -l
#* * * * * /usr/bin/ssh -NfR 2222:localhost:22 test1@172.25.250.11 -p 22 2>&1 > /dev/null | /usr/bin/tee -a /var/log/debug | /usr/bin/logger
* * * * * /usr/bin/ssh -NfR 2222:localhost:22 test1@172.25.250.11 -p 22 2>&1 > /dev/null
[root@servera ~]#

 

遠端 – 客戶端的Linux Server【servera】,如果不想留下登入紀錄及 history,可以在 遠端 – 客戶端的Linux Server【servera】改成以下指令

[root@serverb ~]# ssh -p 2222 -o StrictHostKeyChecking=no root@localhost 'hostname'
servera.lab.example.com
[root@serverb ~]#

這樣無論是 history、w、last,通通都不會留下紀錄

已經可以隱身登入執行指令之後,最後是雙向 scp 檔案

人當然都是在本地端 – SI廠商的Linux【serverb】

本地端 – SI廠商的Linux【serverb】/etc/motd,複製檔案到 遠端 – 客戶端的Linux Server【servera】/tmp/motd

要注意,不可以加 -o StrictHostKeyChecking=no

[root@serverb ~]# scp -P 2222 /etc/motd root@localhost:/tmp/motd
motd                                                          100%   24    16.5KB/s   00:00
[root@serverb ~]#

 

將檔案從遠端 – 客戶端的Linux Server【servera】/etc/passwd,複製回到本地端的  SI廠商的Linux【serverb】/tmp/passwd1

[root@serverb ~]# scp -P 2222 -o StrictHostKeyChecking=no root@localhost:/etc/passwd /tmp/passwd1
passwd                                                        100% 1563     1.0MB/s   00:00
[root@serverb ~]#

 

最後還是要特別再次提醒安全問題!

本篇發表於 CentOS 6, CentOS 7, Docker, Linux, RHEL 6, RHEL 7, RHEL 8, ubuntu。將永久鏈結加入書籤。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s