2015年10月

本来树莓派(Raspberry Pi 2 Model B)在家中安静地连上Internet,并定时下载网盘上的电脑,就已经很实用了。但是发现花生壳推出针对树莓派的内网端口及socket5映射软件,就试玩了一下:

树莓派花生壳(内网版)攻略
http://service.oray.com/question/2680.html

该软件的作用就是把处于内网环境的树莓派的端口或socket5映射到外网,实现外网直接访问树莓派,可玩性一下子提高几个等级。但是由于是免费版,拥有N多限制,包括流量、响应时间、可映射端口数量等等。查了相关资料,有网友说其实是利用了ssh隧道来实现的,既然这样,为什么不自己部署一个?安全性及相关限制都可以自己设置的。

所需条件
1)外网可访问的服务器或VPS(下文简称VPS),并且可运行SSH服务,最好是Linux系统
2)可访问VPS的树莓派(下文简称RPi)
3)域名,非必须

原理
RPi通过ssh客户端主动连接VPS的ssh服务,并开启VPS上的端口,映射到PRi的端口。为了方便创建连接,VPS上的ssh服务需要无密码访问,这里采用了证书登录。由于网络断掉后,ssh客户端的连接也会断掉,所以采用autossh代替ssh客户端。

关于ssh服务
参考以下文章:

1)此文章说明了很多ssh服务的安全相关配置,可用作VPS上的ssh服务配置参考。
SSH 安全性和配置入门
https://www.ibm.com/developerworks/cn/aix/library/au-sshsecurity/

2)详细说明了如果配置证书登录ssh服务
ssh证书登录(实例详解)
http://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646346.html

3)介绍ssh隧道的使用
SSH Tunnel解决无公网IP 80被封等问题
http://blog.bbzhh.com/index.php/archives/60.html

4)介绍用autossh的使用
autossh在Ubuntu上的配置 ssh 隧道
http://yuanxiao.sinaapp.com/pages/122/132/377/article_index.html

配置
1)RPi上,创建证书。需要输密码时,直接按回车跳过。

ssh-keygen -t rsa

这里采用了rsa方式,默认生成两个文件:公钥(id_rsa.pub)和私钥(id_rsa)。把公钥(id_rsa.pub)文件,上传到VPS。

2)VPS上,生成授权文件,把自制的公钥都放入去。

cat id_rsa.pub >> ~/.ssh/authorized_keys

3)VPS上,安装并配置sshd。配置文件路径/etc/ssh/sshd_config,比较重要的配置项如下:

# 禁用root账户登录,增加安全性,非必要
PermitRootLogin no

# 是否让 sshd 去检查用户家目录或相关档案的权限数据,
# 避免使用者将某些重要文件的权限设错,而可能导致一些问题发生。
# 例如使用者的 ~/.ssh/ 权限设错时,某些特殊情况下会不许用户登入
StrictModes no

# 是否允许用户自行使用成对的密钥系统进行登入行为,仅针对 version 2。
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      %h/.ssh/authorized_keys

# 禁用密码登录,增加安全性
PasswordAuthentication no

配置完成后,记得重启sshd服务,使配置生效。

4)VPS上,安装TCP Echo服务,供autossh判断网络隧道连通情况。默认运行端口为7。

apt-get install openbsd-inetd

安装后,需要修改配置文件/etc/inetd.conf,在文件末尾增加以下内容:

echo        stream    tcp    nowait    root    internal

然后就可以启动服务了。

5)RPi上,用autossh连接VPS并进行端口映射

# 安装autossh
sudo apt-get install autossh

# 创建port_forward.sh文件
cat >> port_forward.sh << EOF
#!/bin/bash
export AUTOSSH_PIDFILE=/var/run/autossh.pid
export AUTOSSH_POLL=60
export AUTOSSH_FIRST_POLL=30

# -f是后台运行
# -M 后台管理端口:VPS的echo服务端口
# -NR VPS端口:本机地址:本机端口,本例把RPi端口80映射到VPS端口8080
# 后面的就是登录相关信息
autossh -f -M 4567:7 -NR 8080:localhost:80 user@vps_name.net -p 22 -i /path/to/id_rsa 

# 设置可执行权限
chmod 755 port_forward.sh

# 运行
./port_forward.sh

6)最后就可以直接访问http://vps_name.net:8080就可以访问RPi端口80上的服务了。

经过一段时间的研究和实践,终于把树莓派(Raspberry Pi 2 Model B)作为家庭服务器用起来了。简单来说,就是树莓派作为无线路由、网盘下载机和提供DLNA服务,Chromecast作为播放器在电视机播放多媒体内容,用Android手机作为遥控器控制一切。

树莓派
1)无线路由
参考前面的Bolg
Setup Raspberry Pi 2 as Wireless Router
http://blog.foxail.org/index.php/archives/661/

2)网盘下载机
这里选择了百度盘,其空间足够大(免费2TB空间),有Linux的客户端(第三方开发的)。树莓派上安装客户端:
https://github.com/GangZhuo/BaiduPCS

然后设置个定时同步下载,就可以自动下载电影了。下载前,还会上传当前的下载状态及硬盘空间使用情况到网盘,方便查看。

3)安装USB存储设备
参考以下文章,增加自动挂载USB存储设备:
树莓派自动挂载usb移动存储设备
http://rpi.linux48.com/usbstorage.html

该脚本在Debian 8上有问题,修改了一下,如下:

KERNEL!="sd*", GOTO="media_by_label_auto_mount_end"
SUBSYSTEM!="block",GOTO="media_by_label_auto_mount_end"
IMPORT{program}="/sbin/blkid -o udev -p %N"
ENV{ID_FS_TYPE}=="", GOTO="media_by_label_auto_mount_end"
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="Untitled-%k"
ACTION=="add", ENV{mount_options}="relatime,sync"
ACTION=="add", ENV{ID_FS_TYPE}=="vfat", ENV{mount_options}="iocharset=utf8,uid=1000,gid=1000,umask=000"
ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", ENV{mount_options}="iocharset=utf8,uid=1000,gid=1000,umask=000"
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}"

ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"
LABEL="media_by_label_auto_mount_end"

如果是U盘,直接插上就可以了。但如果是移动硬盘,要考虑树莓派的电流不足的问题,会导致硬盘mount不上,或者不能写入数据。不得不换了个2A的USB电源和有源USB Hub。现在算是能顺利运行了,但还是想简化电路和连接方式,后面再考虑。

4)DLNA服务
装个minidlna就可以了。如果需要识别rmvb文件,需要改源码并重新编译。参考这个:
Raspiberry Pi安装minidlna1.1.4并支持rmvb
http://raspi.vanabel.info/wordpress/?p=92

Chromecast
国内真的不推荐用这个,因为要连上google才能使用。为了连上google,花了很多时间去研究,最后采用简单的方案:设置某个固定ip采用代理。本文前面的“无线路由”配置中,包含了相关配置。

关于ROOT。感觉不获取ROOT权限,也不会影响使用。不过个人习惯,ROOT后会增加更多的可能性。并且,升级到最新版系统后,目前不能ROOT了。

检查是否可ROOT:[INFO] Rootable Serial Numbers
http://forum.xda-developers.com/showthread.php?t=2537022

ROOT教程,需要借助硬件Leonardo Pro Micro(基于芯片ATmega32U4):Chromecast ROOT
http://raspberrypihelp.net/motornavigatie-dutch/62-chromecast-root

Android手机
目前安装了connectbot,作为SSH客户端连接树莓派。项目源码:
https://github.com/connectbot/connectbot

DLNA方面,采用BubbleUPnP,可以用本机播放树莓派的多媒体内容,可以把树莓派的多媒体内容推送到Chromecast。Google Play下载:
https://play.google.com/store/apps/details?id=com.bubblesoft.android.bubbleupnp