丈母娘想让我解决她们家Wifi信号弱的问题,我决定把家里原来唯一的无线路由器变成纯AP,弱电箱里放一个星际宝盒,另外在客厅放一台K2保证全家的Wifi覆盖。 本来路由器这种东西设置好了就不会再动了,可是我还需要解决他们家网络电视的问题,网络电视这种东西,直播源很容易失效,感觉以后会涉及到远程维护了。 我之前写过Ubuntu下用Autossh建立反向连接 的博文,现在想照搬到OpenWrt上。但是OpenWrt上是用Dropbear作为SSH工具,与OpenSSH有些许不同,记录一下过程。
前期准备 公网服务器A 开放端口5680(转发ssh连接),开放端口5681(监听连接状态),开放端口22,用OpenSSH做SSH服务器 内网机器B OpenWrt with Dropbear,注意在“SSH访问”中开启“网关端口”。 修改公网服务器A的SSH配置文件/etc/ssh/sshd_config 1 2 3 4 5 6 GatewayPorts yes HostKeyAlgorithms +ssh-rsa PubkeyAcceptedAlgorithms +ssh-rsa PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
这样可以把监听的端口绑定到任意IP 0.0.0.0上,否则只有本机127.0.0.1可以访问。 添加ssh-rsa算法兼容老板版本dropbear 记得重启SSH服务器
1 sudo service restart sshd
用内网B机器保存公网服务器A的密钥,以便免密连接 这里就跟OpenSSH不一样了,因为Dropbear没有ssh-id-copy这个命令,而Dropbear的private key又不是以明文方式存储的。
1 2 dropbearkey -y -f /etc/ dropbear/dropbear_rsa_host_key | grep "^ssh-rsa " > / etc/dropbear/ authorized_keys
然后将key从authorized_keys复制添加到到公网服务器的~/.ssh/authorized_keys中
在内网B机器上尝试建立反向代理 1 2 ssh -NR 5678 :127.0.0.1:22 公网服务器A的用户名@公网服务器A的IP -i /etc/dropbear/dropbear_rsa_host_key
正常情况下,不用输入密码,通道即建立成功。
-N:只建立连接,不打开shell -R:指定端口映射 AutoSSH 自动重连 使用SSH的方式不够稳定,使用AutoSSH可以自动在连接断开时自动重连,再把AutoSSH加入系统服务自动启动,则可以做到稳定的连接。
安装AutoSSH 将AutoSSH添加到开机自启 注意在OpenWrt里,官方的autossh早就给你准备好了 /etc/init.d/autossh 文件,你只需要在/etc/config/autossh中修改参数即可,下面贴出我的配置
1 2 3 4 5 6 7 8 config autossh option localport '22' option remoteport '5676' option ssh '-N -i /etc/dropbear/dropbear_rsa_host_key 公网服务器A的用户名@公网服务器A的IP' option gatetime '0' option monitorport '5679' option poll '60' option enabled '1'
修复Dropbear的一个小bug 必须要指定HOME目录,详见Github 修改/etc/init.d/autossh,添加procd_set_param env HOME=/root,全文见下
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 #!/bin/sh /etc/rc.common USE_PROCD=1 START=80 start_instance () { local section="$1 " local forwarding config_get_bool enabled "$section " enabled 1 [ "$enabled " != "1" ] && return 0 config_get ssh "$section " ssh if [ -z "$ssh " ]; then echo "autossh: ssh option is required" return 1 fi config_get localhost "$section " localhost localhost config_get localport "$section " localport config_get remotehost "$section " remotehost config_get remoteport "$section " remoteport config_get monitorport "$section " monitorport 20000 config_get poll "$section " poll 600 config_get gatetime "$section " gatetime 30 config_get first_poll "$section " first_poll config_get loglevel "$section " loglevel config_get logfile "$section " logfile config_get maxlifetime "$section " maxlifetime config_get maxstart "$section " maxstart config_get message "$section " message config_get_bool ntservice "$section " ntservice 0 config_get path "$section " path config_get pidfile "$section " pidfile if [ -n "$localport " ] && [ -n "$remoteport " ]; then if [ -n "$remotehost " ]; then forwarding="-L ${localport} :${remotehost} :${remoteport} " else forwarding="-R ${remoteport} :${localhost} :${localport} " fi elif [ -n "$localport " ] || [ -n "$remoteport " ]; then echo "autossh: both localport and remoteport options are required" return 1 fi procd_open_instance "$section " procd_set_param env HOME=/root procd_set_param command /usr/sbin/autossh ${forwarding} ${ssh} procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} [ -n "$pidfile " ] && procd_set_param pidfile "$pidfile " [ -n "$monitorport " ] && procd_append_param env "AUTOSSH_PORT=$monitorport " [ -n "$poll " ] && procd_append_param env "AUTOSSH_POLL=$poll " [ -n "$gatetime " ] && procd_append_param env "AUTOSSH_GATETIME=$gatetime " [ -n "$first_poll " ] && procd_append_param env "AUTOSSH_FIRST_POLL=$first_poll " [ -n "$loglevel " ] && procd_append_param env "AUTOSSH_LOGLEVEL=$loglevel " [ -n "$logfile " ] && procd_append_param env "AUTOSSH_LOGFILE=$logfile " [ -n "$maxlifetime " ] && procd_append_param env "AUTOSSH_MAXLIFETIME=$maxlifetime " [ -n "$maxstart " ] && procd_append_param env "AUTOSSH_MAXSTART=$maxstart " [ -n "$message " ] && procd_append_param env "AUTOSSH_MESSAGE=$message " [ "$ntservice " == "1" ] && procd_append_param env "AUTOSSH_NTSERVICE=yes" [ -n "$path " ] && procd_append_param env "AUTOSSH_PATH=$path " [ -n "$pidfile " ] && procd_append_param env "AUTOSSH_PIDFILE=$pidfile " procd_close_instance } start_service () { local instance=$1 config_load 'autossh' if [ -n "$instance " ]; then start_instance "$1 " else config_foreach start_instance 'autossh' fi }
然后开机启动Autossh/etc/init.d/autossh enable