这篇文章将会给openwrt的ssh加上totp的验证,方便开到公网上进行ssh并且降低被扫的安全风险
op自带的ssh服务是Dropbear,他不提供pam验证的功能,所以需要用到openssh,这样一来也可以实现对外的ssh需要两步验证,局域网的不需要

首先需要一个linux机器用于生成key配置文件

sudo apt-get install libpam-google-authenticator
google-authenticator -t -d -r 1 -R 30 -W -Q UTF8 -l root@op -f -s op
cat op

cat op输出的内容复制下来备用

这里用的是lean的源码编译的lede,使用openwrt官方的系统大概没那么多事

vi ~/.google_authenticator

按i后将刚刚复制的贴进去,按一下esc再输入:wq回车保存

opkg update
opkg install google-authenticator-libpam openssh-server-pam
mkdir /lib/security
vi /etc/ssh/sshd_config

改一下配置,首先开头的#代表这行是注释,配置的时候要去掉
Port是端口,可以改成10000以上的高位端口,然后再去 网络 防火墙 通信规则 打开路由器端口 里开放
MaxAuthTries是最多尝试的次数,建议改成2
在最后加上

ChallengeResponseAuthentication yes
PermitRootLogin yes

然后配置一下验证pam

vi /etc/pam.d/sshd

将这行加在最后面,这样会先验证密码再验证totp,加在最前面就会先验证totp再验证密码

auth requisite pam_google_authenticator.so

配置好了,重启sshd

/etc/init.d/sshd restart

理想很美好,现实很残酷,你会发现连接这个新ssh服务验证都一切正常,但是却无法打开shell直接就断开连接了
去 状态 系统日志 中看到每次成功连接这个新ssh服务后日志最后有这行错误

fatal: privsep_preauth: preauth child terminated by signal 31

这是openssl版本不匹配导致的,这只需要更新就好了,请确保已经删除软件源中非lede官方的源(镜像可以)避免有其他版本的openssl混在其中

opkg update
opkg install libopenssl-conf libopenssl1.1 openssl-util
/etc/init.d/sshd restart

这就正常了