远程 Mac 的
SSH 安全加固清单
一台常年在线的远程 Mac,SSH 是最重要的入口,也是最常被扫描的端口。本文按顺序完成加固:只用密钥登录、在正确的位置修改 sshd 配置、限制可登录的用户、打开 macOS 防火墙、用 Tailscale 代替公网暴露,以及查看登录记录。每一步都给出可验证的命令。
先确认密钥登录可用
禁用密码之前,必须先确认密钥登录已经能用,否则会把自己锁在外面。在本地生成密钥并上传公钥:
ssh-keygen -t ed25519 -C "laptop"
ssh-copy-id -i ~/.ssh/id_ed25519.pub alice@远程主机地址
# 远程 Mac 上检查权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys新开一个终端执行 ssh -o PasswordAuthentication=no alice@远程主机地址,能直接登录才继续下一步。整个加固过程中,保持一个已登录的 SSH 会话不要关闭。
在 sshd_config.d 中修改配置
macOS 的 /etc/ssh/sshd_config 开头有一行 Include /etc/ssh/sshd_config.d/*。sshd 对同一选项采用最先出现的值,因此放在这个目录里的设置会优先于主配置文件,并且系统更新时不会被覆盖。
sudo tee /etc/ssh/sshd_config.d/100-hardening.conf >/dev/null <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
EOF
sudo sshd -t # 语法检查,无输出即正常
sudo sshd -T | grep -Ei 'passwordauth|kbdinteractive|permitroot' # 查看生效值macOS 默认启用 PAM,只关 PasswordAuthentication 时,密码仍可能通过键盘交互方式输入,所以 KbdInteractiveAuthentication 也要关。使配置生效:
sudo launchctl kickstart -k system/com.openssh.sshd如果这条命令在你的系统版本上不可用,到「系统设置 → 通用 → 共享」里把「远程登录」关掉再打开即可(已建立的会话不受影响)。然后新开终端测试密码登录应被拒绝:ssh -o PubkeyAuthentication=no alice@远程主机地址。
限制可以登录的用户
在「系统设置 → 通用 → 共享 → 远程登录」右侧的信息按钮里,把「允许访问」改为「仅这些用户」,只保留需要 SSH 的账户。也可以在配置文件里再加一层:
# 追加到 /etc/ssh/sshd_config.d/100-hardening.conf
AllowUsers alice deploy给 AI 编码助手、CI Runner 等自动化任务单独建普通用户和单独的密钥,日常操作不用管理员账户。
打开 macOS 防火墙
macOS 自带的是应用防火墙,按程序控制传入连接,而不是按端口。在「系统设置 → 网络 → 防火墙」中打开,或用命令行:
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on
/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate远程登录、屏幕共享等系统共享服务在开启时会被允许。需要按端口、按来源 IP 过滤时,要用 pf,规则写错同样可能断开连接,建议先在本地机器上练熟。
用 Tailscale 代替公网暴露
最有效的加固是让 22 端口根本不出现在公网上。用 Tailscale 等私有网络工具组网后,只有你自己的设备能访问 SSH,路由器上也不需要端口转发。配置好并验证能通过 Tailscale 地址登录之后,再关闭原有的公网入口。
在住宅宽带上,公网入口通常依赖路由器的端口转发,是否存在以及如何关闭取决于网络的管理方。在三万主机租用的机器,交付时的连接方式会在交付信息里说明,调整前可以先和支持确认,避免两条路同时断开。
登录审计
macOS 的 sshd 日志写入统一日志系统,用 log 命令查询:
log show --last 24h --predicate 'process == "sshd"' | grep -Ei 'accepted|failed|invalid'
log stream --predicate 'process == "sshd"' # 实时查看
last | head -20 # 最近的登录记录
who # 当前登录的用户定期检查 ~/.ssh/authorized_keys 里是否有不认识的公钥;不再使用的电脑、离职成员和退租前的所有密钥都要及时删除。
常见问题
为什么不直接改 /etc/ssh/sshd_config?
macOS 的主配置文件属于系统文件,系统更新时可能被替换。主配置开头已经包含 /etc/ssh/sshd_config.d/ 目录,把自己的设置放在这个目录下的单独文件里,更新后仍然有效,也更容易回滚。
改完配置后把自己锁在外面了怎么办?
如果还有屏幕共享或其他通路,登录后删除刚加的配置文件再重启 sshd。所以修改前一定要保留一个已登录的会话,并在新窗口里测试。租用的机器两条路都断了,可以联系服务商的支持协助。
只用 Tailscale 访问,还需要做这些加固吗?
需要,只是风险面小了很多。Tailscale 控制的是谁能连到 22 端口,密钥登录和禁用密码控制的是连上之后能否登录。两层同时做,任何一层出问题都还有另一层兜底。
扫码加微信客服手机上长按二维码识别