树莓派的内网穿透
家里的宽带没有公网IP,从外面没有办法SSH到树莓派上。如果有公网IP的话,现在一般的路由器都支持端口转发功能,在路由器的管理界面添加一条转发规则即可。
不过有一天,我突然想到了SSH的端口转发功能,其实很简单的一条命令:
1 |
ssh -N -f -R 8022:localhost:22 xxx@remote-host.com |
简单解释一下,-N表示了不要执行任何命令,-f表示在后台执行,-R 8022:localhost:22表示remote-host.com上将会监听8022端口,并将所有的流量转发到localhost:22端口上来。就是这么简单。
当然了,前提是你要有一台有公网IP的主机,这个就自己想办法搞定吧,比如阿里云什么的。
但是,这个办法有个缺点,树莓派重启了就失效了,可以参考[这个][autosshd],在树莓派上略加修改就能用了,把autosshd脚本放到/etc/init.d下,再执行
1 |
update-rd.d autosshd defaults |
把autosshd加到自启动项里去。其实这个脚本就是利用了autossh这个工具。
不过我对上面的那个脚本做了些修改,供大家参考:
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 |
#!/bin/bash ### BEGIN INIT INFO # Provides: autossh # Required-Start: $network $local_fs # Required-Stop: $network $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: This script starts and stops the autossh daemon ### END INIT INFO # Source function library. #. /etc/rc.d/init.d/functions # Source networking configuration. #. /etc/sysconfig/network # Check that networking is up. #[ ${NETWORKING} = "no" ] && exit 0 TUNNEL_SSHCONFIG="/home/pi/.ssh/config" TUNNEL_IDENTITY="/home/pi/.ssh/id_rsa" TUNNEL_HOST="xxx@remote-host.com" TUNNEL_REDIRECT="8022:localhost:22" export AUTOSSH_PIDFILE="/var/run/autossh.pid" # By default it's all good. RETVAL=0 # Start function. start() { local name=$1 echo -n $"Starting ${name}: " if [ -e "/var/lock/subsys/${name}" ]; then if [ -e "/var/run/${name}.pid" ] && [ -e /proc/`cat /var/run/${name}.pid` ]; then echo -n $"already exists."; failure $"already exists."; echo return 1 fi fi #daemon /usr/bin/autossh -M 0 -f -nNT -F ${TUNNEL_SSHCONFIG} -i ${TUNNEL_IDENTITY} ${TUNNEL_HOST} /usr/bin/autossh -f -M 0 -CNnqT -F ${TUNNEL_SSHCONFIG} -i ${TUNNEL_IDENTITY} -R ${TUNNEL_REDIRECT} ${TUNNEL_HOST} -o ServerAliveInterval=30 -o ServerAliveCountMax=5 RETVAL=$? [ $RETVAL -eq 0 ] && touch "/var/lock/subsys/${name}" echo return $RETVAL } # Stop function. stop() { local name=$1 echo -n $"Stopping ${name}: " #killproc -p "/var/run/${name}.pid" ${name} kill `cat /var/run/${name}.pid` RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f "/var/lock/subsys/${name}" return $RETVAL } # See how we were called. case "$1" in start) start "autossh" ;; stop) stop "autossh" ;; restart) $0 stop sleep 3 $0 start ;; status) status "autossh" RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit $RETVAL |
做了几点改进:
- 修改了一下在树莓派上可以跑,但是很多地方还有待改进
- 修改了ssh的启动参数,添加了-Cq,可以man ssh自己看
- 添加了-o ServerAliveInterval=30 -o ServerAliveCountMax=5,可以自动检测SSH连接可用性
至此。
好久没有来写日志了。