Debian服务器默认的SSH配置在公网环境下并不安全。很多运维人员安装完系统后直接使用密码登录root账户,这等于把服务器大门敞开。远程访问安全加固的核心思路只有一条:减少攻击面,增加认证难度,记录所有行为。下面直接进入具体操作。

SSH服务的基础加固

先处理SSH配置文件。打开/etc/ssh/sshd_config,逐项检查以下参数。PermitRootLogin必须设置为no,禁止root直接远程登录。日常维护使用普通用户,需要提权时通过sudo完成。PasswordAuthentication设置为no,完全禁用密码认证,只保留密钥登录。如果某些场景必须保留密码,至少设置PermitEmptyPasswords no来禁止空密码。

MaxAuthTries设置为3,限制单次连接的认证尝试次数。LoginGraceTime设置为30,超过30秒未完成认证就断开。这两个参数能有效拖慢暴力破解的速度。X11Forwarding设置为no,AllowTcpForwarding根据实际需求决定,如果不需要端口转发就设为no。这两个功能被利用时可能成为内网渗透的跳板。

PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowTcpForwarding no

修改完成后执行systemctl restart sshd使配置生效。不要关闭当前会话,新开一个终端测试能否正常登录,确认无误后再退出旧会话。

密钥认证的规范管理

密钥登录虽然比密码安全,但管理不善同样会出问题。生成密钥对时使用ed25519算法,不要再用RSA 2048。ed25519在同等安全强度下密钥更短,运算更快,抗侧信道攻击能力更强。客户端执行ssh-keygen -t ed25519 -a 100,-a参数指定KDF轮数,增加暴力破解私钥的难度。

公钥部署到服务器后,检查~/.ssh/authorized_keys文件的权限。目录权限必须是700,文件权限必须是600,所有者必须是用户本人。很多安全事件就是因为权限设置过松,其他用户或服务可以读取密钥文件。同时建议在sshd_config中设置AuthorizedKeysFile .ssh/authorized_keys,明确指定公钥文件位置,避免被其他路径干扰。

私钥在客户端也要设置强口令保护。虽然每次登录需要输入私钥口令,但配合ssh-agent可以做到一次输入、会话期间免密。私钥文件绝对不要复制到多台设备,每台管理终端使用独立的密钥对,这样某台设备丢失时可以单独吊销对应公钥。

网络层访问控制

SSH端口不需要对全网开放。如果管理人员的IP地址相对固定,最直接的做法是用iptables或nftables限制来源IP。例如只允许某个办公网段访问22端口:

iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

如果无法固定来源IP,至少改变SSH的默认端口。把Port 22改为一个高位端口,比如22222。这不是真正的安全措施,但能过滤掉绝大多数自动化扫描流量。修改后记得同步更新防火墙规则和客户端配置。

更严格的方案是使用端口敲门技术。服务器默认不开放SSH端口,客户端按特定顺序访问几个预设端口后,防火墙才临时放行SSH连接。knockd是Debian上常用的实现。配置/etc/knockd.conf,定义敲门序列和放行时间窗口:

[openSSH]
sequence = 7000,8000,9000
seq_timeout = 15
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn

[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 15
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn

客户端使用knock命令敲门后再连接SSH。这种方式隐蔽性很强,但增加了操作复杂度,适合对安全要求极高的场景。

Fail2ban动态封禁

即使禁用了密码登录,服务器仍然会收到大量扫描和探测请求。Fail2ban通过监控日志,自动封禁可疑IP。Debian安装:apt install fail2ban。创建/etc/fail2ban/jail.local,针对SSH服务配置封禁策略:

[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600

maxretry设为3,10分钟内失败3次就封禁1小时。如果使用非标准端口,port参数要同步修改。Fail2ban的封禁基于iptables,重启服务后封禁列表会清空,可以配置持久化或接受这个特性。对于使用密钥登录的环境,认证失败通常意味着有人在尝试非法访问,封禁策略可以更激进。

双因素认证的落地

密钥认证解决了密码被猜解的问题,但私钥泄露后服务器仍然会被入侵。双因素认证在密钥之外增加一层验证,即使私钥被盗,没有动态验证码也无法登录。Debian上使用libpam-google-authenticator实现TOTP双因素认证。

安装apt install libpam-google-authenticator。每个需要远程登录的用户执行google-authenticator命令,按提示生成密钥和恢复码。然后在/etc/pam.d/sshd的第一行添加:

auth required pam_google_authenticator.so

同时修改/etc/ssh/sshd_config,设置ChallengeResponseAuthentication yes,AuthenticationMethods publickey,keyboard-interactive。这样登录流程变为先验证密钥,再输入动态验证码。注意配置顺序,先测试密钥认证正常,再启用双因素,避免把自己锁在服务器外。

双因素认证的代价是每次登录多一步操作,而且需要确保手机时间与服务器时间同步。对于多人管理的服务器,每个管理员使用独立的TOTP密钥,离职时删除对应用户即可。

审计与监控

加固不是一次性工作,持续监控才能发现异常。Debian的SSH日志默认记录在/var/log/auth.log。重点关注的日志模式包括:短时间内大量认证失败、成功登录后立刻出现提权操作、非工作时间段的登录行为。可以配置logwatch或自写脚本定期分析日志,但更实时的方式是使用auditd监控关键文件变化。

对于已登录会话的监控,ss命令可以查看当前SSH连接:ss -tnp | grep sshd。who命令列出已登录用户。如果发现可疑会话,用pkill -u 用户名强制踢出。建议设置TMOUT环境变量,在/etc/profile.d/中添加超时配置,闲置会话自动断开:

export TMOUT=600
readonly TMOUT

600秒无操作自动退出,降低管理员离开终端后的风险。

系统层面的配套措施

SSH加固只是远程访问安全的一部分,底层系统不加固,SSH配置再严格也白费。Debian的自动安全更新必须开启。安装unattended-upgrades,配置自动安装安全补丁。很多入侵事件利用的都是已知漏洞,补丁延迟就是给攻击者留窗口。

用户权限管理同样关键。每个管理员使用独立账户,通过sudoers文件精确控制可执行的命令。不要为了方便把所有管理员都加入sudo组并赋予ALL权限。最小权限原则意味着每个账户只能执行工作必需的指令。sudo日志记录在/var/log/auth.log,定期审查可以发现异常提权行为。

内核参数也需要调整。编辑/etc/sysctl.conf,开启SYN cookie防护,减少SYN flood攻击的影响:net.ipv4.tcp_syncookies = 1。关闭ICMP重定向,防止路由被篡改:net.ipv4.conf.all.accept_redirects = 0。这些参数对远程访问的稳定性也有帮助。

备份与恢复预案

任何加固操作都有把自己锁在外面的风险。执行配置修改前,务必做好备份。SSH配置文件、PAM配置、防火墙规则、用户目录下的.ssh目录,这些都要定期备份到安全位置。同时准备带外管理通道,比如云服务器的VNC控制台或物理服务器的IPMI。当SSH无法连接时,通过带外通道进入系统恢复配置。

测试恢复流程和测试加固本身同样重要。定期演练从备份恢复SSH配置的过程,确保紧急情况下不会手忙脚乱。记录所有配置变更,使用etckeeper自动将/etc目录纳入版本控制,每次修改都有历史记录可查。

Debian服务器远程访问安全加固是一个持续迭代的过程。从禁用密码登录到双因素认证,从防火墙限制到行为审计,每一层都增加攻击者的成本。安全没有终点,只有不断调整策略来应对新的威胁。把上述措施落实到位,你的服务器在面对绝大多数自动化攻击和定向入侵时,都能保持足够的防御能力。