Raspberry Pi从零开始搭建低成本NAS(9)-外网登录树莓派

有时候我们可能需要在外网环境下控制家里面的树莓派,根据实际网络情况,提供下面两个方案供选择。

  • 外网远程登录树莓派SSH
  • 基于Web的SSH

在详细介绍这两种方案之前,我们需要先解决一个问题,如何获取树莓派外网(公网)IP地址?我们的树莓派一般处于路由器后面,外网不可见。

外网IP地址

有两种方法可以获取到外网IP地址,一,通过Python脚本获取,二,动态域名。因为免费的动态域名时不时会抽风,为了保证可靠性,可以同时使用这两种方法。

Python脚本获取

这种方法是通过树莓派自己获取公网IP,然后自动发动到指定的Email。创建文件external_ip.py,

sudo vim /home/pi/external_ip.py

输入如下内容,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import urllib
import socket
import time
import smtplib
from email.mime.text import MIMEText
#############
#To address
mailto_list=["xx@gmail.com","xx@126.com","xx@hotmail.com"]
#####################
#Set server, account, password and email postfix
'''
# no tls
mail_host="smtp.126.com"
mail_user="xx" #用户名
mail_pass="xx" #密码
mail_postfix="126.com"
'''
#tls
mail_host="smtp-mail.outlook.com:587"
mail_user="xx@hotmail.com"
mail_pass="xx"
mail_postfix="hotmail.com"
'''
#tls
mail_host="smtp.gmail.com:587"
mail_user="xx@gmail.com"
mail_pass="xx"
mail_postfix="gmail.com"
'''
######################
def send_mail(to_list,sub,content):
'''
to_list: to address
sub:subject
content:content
send_mail("aaa@126.com","sub","content")
'''
me=mail_user+"<"+mail_user+"@"+mail_postfix+">"
msg = MIMEText(content)
msg['Subject'] = sub
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
s = smtplib.SMTP()
s.connect(mail_host)
s.starttls() # TLS need this
s.login(mail_user,mail_pass)
s.sendmail(me, to_list, msg.as_string())
s.close()
return True
except Exception, e:
print str(e)
return False
current_ip = None
def getip():
sock = socket.create_connection(('ns1.dnspod.net', 6666))
ip = sock.recv(16)
sock.close()
return ip
'''
def getip():
f = urllib.urlopen("http://www.canyouseeme.org/")
html_doc = f.read()
f.close()
m = re.search('(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)',html_doc)
print m.group(0)
data=m.group()
return data
'''
if __name__ == '__main__':
while True:
try:
ip = getip()
#print ip
if current_ip != ip:
if send_mail(mailto_list,"Raspberry Pi external ip address", 'Raspberry Pi External IP Addreds is ' + ip + ' ...!'):
current_ip = ip
#print('Send OK')
except Exception, e:
print e
pass
time.sleep(60) # Check the ip address every one minute

编辑文件rc.local,设置开机自动运行

sudo vim /etc/rc.local

在 exit 0 之前, 加入以下代码:
su root -c “python /home/pi/external_ip.py”

简单介绍一下上面的脚的功能,树莓派开机自动获取公网IP地址并发送到指定邮箱,然后每分钟监测IP是否发生变化,如果变了,则发送变化之后的IP到指定邮箱。需要修改的地方如下:
mailto_list里面填想要收到IP的邮箱,可以填多个,发送邮箱我列出了三个邮箱,126,hotmail,gmail(可能被墙,不建议使用),根据自己情况选择一个,如果想用其他邮箱,请自行修改。关于getip()函数,我列了两个,目前在我这两个都能用,请根据自己实际情况选择。

动态域名

如果路由器支持动态域名(DNS)功能,可以选择这种方法,注册一个动态域名服务,比如花生壳等,然后在路由器里面设置动态DNS,如下图所示。



外网远程登录树莓派SSH

这种方法我想大家应该不陌生了,前面我们操作树莓派,都是通过登录SSH,只不过是内网登录。外网登录其实没什么区别,就是需要在路由器上做端口映射。
如果你所在网络对外只开放了80和8080等web端口,那么这种方法就不怎么好使了,需要修改SSH端口号为80端口,还有更糟糕的情况,恰好你的网络供应商封锁了80和8080等web端口(http://www.canyouseeme.org/可以查询),就像我一样,握个抓,目前我所知道的简单有效的方法是用手机来登录SSH,Android平台推荐使用JuiceSSH,有虚拟键键盘,可以很方便输入Tab, Ctrl等特殊按键,音量键放大缩小字体,可旋转成横屏,甩ConnectBot几条街,IOS平台可以使用Serverauditor。另外可以通过搭建代理转发服务来实现登录如果还有其他好方法,也欢迎分享。

基于Web的SSH

如果幸运,web端口没有被封,那么可以采用基于web的SSH,在任何有网络的地方,只需要浏览器就就可以搞定一切。基于web的SSH软件有很多,我也不一一介绍了,感兴趣的可以自己参考 ,下面我以shellinabox为例介绍,
先安装,

sudo apt-get install shellinabox -y

然后编辑shellinabox配置文件

sudo vim /etc/default/shellinaboxd

更改SHELLINABOX_PORT=4200,为想要的端口。

# Should shellinaboxd start automatically
SHELLINABOX_DAEMON_START=1

# TCP port that shellinboxd's webserver listens on
SHELLINABOX_PORT=4200

# Parameters that are managed by the system and usually should not need
# changing:
# SHELLINABOX_DATADIR=/var/lib/shellinabox
# SHELLINABOX_USER=shellinabox
# SHELLINABOX_GROUP=shellinabox

# Any optional arguments (e.g. extra service definitions).  Make sure
# that that argument is quoted.
#
#   Beeps are disabled because of reports of the VLC plugin crashing
#   Firefox on Linux/x86_64.
SHELLINABOX_ARGS="--no-beep"

重启shelinabox服务。

sudo service shellinabox restart

现在,去你的客户端系统,打开Web浏览器并导航到:https://ip-address-of-remote-servers:4200。
如果你改变了端口,请填写修改后的端口。