在网上搜了下,大概有这么几种方法,当然你要是有公网的IP, 并且80端口是开启的便能直接ssh了,只不过大多数运营商都不会暴露这些…

公网IP直接访问

一般通过路由器(不管是一级路由还是N级路由)拿到的IP都是运营商提供的内网IP, 比如

1
2
3
10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255

获取外网IP

参考IP查询网址:

http://www.ip138.com/
http://ip.qq.com/
http://jsonip.com/
http://www.net.cn/static/customercare/yourip.asp/
http://www.infosniper.net/
http://bgp.he.net/

如果外网IP不固定会变化,可以通过脚本来邮件发送,虽然这种方法比较笨,不过临时用用是可行的。

脚本可参照get_extenal_ip.py

端口映射

在路由器端做端口映射,如果是二级或三级路由,并且需要有上级路由的权限,不然此方法不通。

Resource: http://www.jianshu.com/p/981520f10ed3

这样通过IP+Port访问Raspberry就行了。

Vpn

顾名思义就是让Raspberry与你当前的Client处于同一个网段,然后通过内网ssh.

所以要在vps上搭建VPN, 然后树莓派和控制端都连上VPN

SSH内网穿透

原理是这样的假设vps地址是10.10.10.10,树莓派通过ssh连接到vps,同时将vps上某个端口比如8888映射到树莓派的ssh端口比如22,这样在vps上访问8888端口就相当于访问树莓派的22端口。

1
$ ssh -f -N -R 8888:localhost:22 [email protected]

Autossh

autossh可以使断开的ssh重连。

Add ssh public key
Configure auto connect when crash
1
$ ssh-copy-id [email protected]
Start autossh
1
$ autossh -M 5678 -fNR 8888:localhost:22 [email protected]
Auto Start autossh
1
2
$ cat /etc/rc.local | grep autossh
su pi -c "autossh -M 5678 -fNR 8888:localhost:22 [email protected]"

Resources: https://github.com/ma6174/blog/issues/7

Dynamic DNS

常用的花生壳动态域名, 当然还有很多其他免费的DNS运营商。

http://www.noip.com/
https://duckdns.org/
http://www.dnsdynamic.org/
http://www.dynu.com/
http://www.changeip.com/dns.php
……

注册一个免费的壳域名,在路由器端DNS解析输入申请的壳域名账号及密码,配置完成。所有的工作都交给了壳域名来操作。

如果还做了端口映射,请用壳域名+映射端口来ssh

Resource:
http://hsk.oray.com/get/?icn=hsk_get&ici=hsk_home-grid#topology
http://hsk.oray.com/news/4168.html

Ngrok

ngrok目前是非常流行的反向代理服务,可以进行内网穿透,支持80端口以及自定义tcp端口转发。
这样即使你的树莓派没有公网IP也可以使用SSH远程登陆。

Offical Website: https://ngrok.com/
Open Source: https://github.com/inconshreveable/ngrok

Download & Install
1
2
3
4
mkdir -p ~/proj/ngrok && cd ~/proj/ngrok
wget http://7xl5gf.com1.z0.glb.clouddn.com/assets/natapp/download/ngrok_linux_arm.zip
unzip ngrok_linux_arm.zip
chmod 755 ngrok

添加configuration

1
2
3
4
5
# nano ngrok.cfg

server_addr: "ngrok.natapp.cn:4443"
trust_host_root_certs: false
# because client no ssl, so this value isfalse
Net port Mapping

http & https 80 port

1
./ngrok -config ngrok.cfg -subdomain **example** 80 -subdomain

TCP port mapping

1
./ngrok -proto=tcp -config ngrok.cfg 22

TCP port didn’t support subdomain, it’s need configure tcp parameter manmually.

Mutiple ports mapping

# nano ./ngrok.cfg
tunnels:
    http:
    proto:
    http: 80
    subdomain: example
    ssh:
    proto:
    tcp: 22
    remote_port: 55699
# start
./ngrok -config=ngrok.cfg start http ssh

详细配置参照这篇文章自建ngrok server进行内网穿透

Resources:
https://www.rpicn.org/documentation/remote-access/access-over-internet/ngrok/
https://blog.phpgao.com/ngrok_how_to.html