Scenario
上圖的樹莓派里面跑著我用于Blockchain + IOT的一個小demo喝噪,但是就面臨著內(nèi)網(wǎng)穿透的問題旺韭,畢竟不可能為每個IOT分配IP地址的兰吟。
場景一:
假設(shè)你擁有大量的樹莓派設(shè)備,有一臺公網(wǎng)服務(wù)器茂翔,也有一臺個人電腦混蔼。這時候你需要通過個人電腦控制大量的樹莓派設(shè)備。
場景二:
假設(shè)你是一個很牛逼的AI實驗室的成員珊燎,剛好你要到外地工作一段時間惭嚣,剛好你需要實驗室里的幾張1080Ti顯卡的服務(wù)器,但是實驗室的服務(wù)器一般是局域網(wǎng)使用的悔政,這個時候晚吞,你面臨的問題就是如何在外地訪問它。
解決這個場景的主要框架如下圖谋国,我們在IOT端反向映射到云服務(wù)器槽地,然后在本機(jī)電腦正向映射到云服務(wù)器,這樣就可以實現(xiàn)從本機(jī)訪問內(nèi)網(wǎng)的機(jī)器了芦瘾。
具體的步驟是這樣的:
一捌蚊、Cloud Server Configuration
首先,我們創(chuàng)建為ssh的接入創(chuàng)建一個獨立的用戶近弟。
(on the server)
sudo useradd -m tunnel
然后缅糟,我們使用tunnel用戶登陸,然后創(chuàng)建相對應(yīng)的ssh配置祷愉。
(on the server)
sudo su tunnel
mkdir ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
然后窗宦,我們需要切換出tunnel用戶,為了安全起見二鳄,我們會禁掉tunnel用戶執(zhí)行命令的功能赴涵。
(on the server)
# if you are still logged in as tunnel, exit:
exit
sudo chsh -s /bin/false tunnel
然后,我們需要對/etc/ssh/sshd_config文件進(jìn)行修改订讼,控制tunnel用戶的權(quán)限髓窜。把下面的內(nèi)容加到文件的末尾。
(on the server)
...
Match User tunnel
AllowAgentForwarding no
AllowTcpForwarding remote
GatewayPorts no
AllowStreamLocalForwarding no
二躯嫉、IoT (Raspberry Pi) Configuration
為了穩(wěn)定的ssh連接纱烘,我采用了autossh對ssh進(jìn)行穩(wěn)定監(jiān)控和管理。采用supervisord對autossh進(jìn)行監(jiān)控祈餐。 so擂啥,我們需要install這兩個東西。
( on the Raspberry Pi)
sudo apt install autossh -y
sudo apt install supervisor -y
需要配置一下supervisord帆阳。
( on the Raspberry Pi)
[program:ssh-forward]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/autossh -M 10001 -N -R 10000:localhost:22 tunnel
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/ssh-forward.log
上述的配置可以通過啟動帶有監(jiān)控端口10001和10002的autossh來監(jiān)控ssh連接哺壶,從而tunnel可以在云服務(wù)器上通過打開10000端口來和IOT進(jìn)行通信。
我們還需要創(chuàng)建私鑰和公鑰蜒谤,而且需要由root來開啟tunnel山宾,因為ssh port是小于1024的而且無法前向。
( on the Raspberry Pi)
# login as root
sudo -i
ssh-keygen -t rsa
nano /root/.ssh/config
Add the following to the config file (replace 123.123.123.123 with your cloud server’s IP address):
Host tunnel
Hostname 123.123.123.123
User tunnel
然后把樹莓派的公鑰加到云服務(wù)器的/home/tunnel/.ssh/authorized_keys中鳍徽,(這個就不用我講了吧= =#)
Ok资锰,我們需要先測試一下ssh的轉(zhuǎn)發(fā)功能有沒有效果。
( on the Raspberry Pi)
ssh -N -R 10000:localhost:22 tunnel
-N: 表示轉(zhuǎn)發(fā)功能阶祭,ssh會一直堵塞監(jiān)聽轉(zhuǎn)發(fā)的绷杜。當(dāng)執(zhí)行這個命令的時候,ssh會對tunnel這個服務(wù)器的包進(jìn)行tcp轉(zhuǎn)發(fā)濒募。假如看見一直堵塞鞭盟,沒有報錯,說明樹莓派的ssh配置好了瑰剃。
然后齿诉,我們可以啟動supervisor了。
service supervisor reload
service supervisor status
# login to your cloud server with your normal (NOT tunnel) user
netstat -tulpn | grep 10000
# and you will see
tcp 0 0 127.0.0.1:10000 0.0.0.0:* LISTEN -
tcp6 0 0 ::1:10000 :::* LISTEN -
三晌姚、Accessing your IoT Device remotely
最后在本地的機(jī)器上運行
(your pc)
ssh -N -L 9090:localhost:10000 youruser@yourserver
youruser是指云服務(wù)器上區(qū)別于tunnel的user粤剧,yourserver是指云服務(wù)器上的ip地址。
本地建立了ssh通道之后挥唠,通過執(zhí)行一下命令就可以連到樹莓派/內(nèi)網(wǎng)服務(wù)器了俊扳。一定要注意的是!user指的是樹莓派的用戶猛遍,或者內(nèi)網(wǎng)的用戶馋记!
(your pc)
ssh user@localhost -p 9090
隨便一談
對于我來說,掌握內(nèi)網(wǎng)穿透和遠(yuǎn)程控制技術(shù)十分重要懊烤。特別是遇到blockchain + IOT的項目研發(fā)方向梯醒,我需要控制/喚醒大規(guī)模的物聯(lián)網(wǎng)設(shè)備;遇到跨地域開發(fā)的時候腌紧,也需要用到各個地區(qū)的服務(wù)器資源來跑AI茸习。Teamviewer無疑是一個好東西,但是lisences太貴了壁肋,作為吃飯都成問題的學(xué)生黨号胚,真的無法承受籽慢,只能從開源項目著手。(致敬開源精神猫胁。箱亿。。)
在搭建網(wǎng)絡(luò)的過程中弃秆,會遇到很多很多的問題届惋。 本文也是避免描述這些問題的解決方案,在解決問題的過程中菠赚,需要各個小伙伴對TCP/IP的機(jī)制很熟悉脑豹,不然會容易疑惑為什么有時候能連上,有時候連不上衡查。如果實在無法解決瘩欺,可以發(fā)郵件一起討論和學(xué)習(xí)。(再次致敬開源精神拌牲。击碗。。)