丈母娘想让我解决她们家Wifi信号弱的问题,我决定把家里原来唯一的无线路由器变成纯AP,弱电箱里放一个星际宝盒,另外在客厅放一台K2保证全家的Wifi覆盖。
本来路由器这种东西设置好了就不会再动了,可是我还需要解决他们家网络电视的问题,网络电视这种东西,直播源很容易失效,感觉以后会涉及到远程维护了。
我之前写过Ubuntu下用Autossh建立反向连接的博文,现在想照搬到OpenWrt上。但是OpenWrt上是用Dropbear作为SSH工具,与OpenSSH有些许不同,记录一下过程。

前期准备

  • 公网服务器A 开放端口5680(转发ssh连接),开放端口5681(监听连接状态),开放端口22,用OpenSSH做SSH服务器
  • 内网机器B OpenWrt with Dropbear

修改公网服务器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
#You can get the key using
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
#注意Dropbear在建立SSH连接时不会自己带着私钥,需要指定
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

1
opkg install autossh

将AutoSSH添加到开机自启

注意在OpenWrt里,官方的autossh早就给你准备好了 /etc/init.d/autossh 文件,你只需要在/etc/config/autossh中修改参数即可,下面贴出我的配置

1
2
3
4
5
6
config autossh
option ssh '-i /etc/dropbear/dropbear_rsa_host_key -N -T -R 5678:localhost:22 公网服务器A的用户名@公网服务器A的IP'
option gatetime '0'
option monitorport '5679'
option poll '180'
option enabled '1'

修复Dropbear的一个小bug

必须要指定HOME目录,详见Github
修改/etc/init.d/autossh,添加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
#!/bin/sh /etc/rc.common
# Copyright (C) 2007-2011 OpenWrt.org

START=80

start_instance() {
local section="$1"

config_get ssh "$section" 'ssh'
config_get gatetime "$section" 'gatetime'
config_get monitorport "$section" 'monitorport'
config_get poll "$section" 'poll'
config_get_bool enabled "$section" 'enabled' '1'

[ "$enabled" = 1 ] || exit 0

export AUTOSSH_GATETIME="${gatetime:-30}"
export AUTOSSH_POLL="${poll:-600}"
export HOME=/root
service_start /usr/sbin/autossh -M ${monitorport:-20000} -f ${ssh}
}

boot() {
return
}

start() {
config_load 'autossh'
config_foreach start_instance 'autossh'
}

stop() {
service_stop /usr/sbin/autossh
}

然后开机启动Autossh
/etc/init.d/autossh enable