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 ~]#
最後還是要特別再次提醒安全問題!