🌐 第05章 · SSH 与远程连接

ssh scp ssh-keygen sshd_config

SSH 与远程连接

SSH 是运维的根本——你敲的每条命令,大概率是从某台电脑 SSH 连进服务器执行的。这一章讲 SSH 的密钥机制、怎么连接和传文件、以及最重要的一环:sshd_config 如何加固,让服务器只能靠密钥登录。

SSH 是什么

SSH(Secure Shell)是加密的远程登录协议,默认端口 22,替代不安全的明文 telnet。它把传输全程加密,并支持基于公钥/私钥的身份认证。

连接一次的过程大致是:

客户端发起连接 → 服务器发公钥指纹,客户端确认
    → 双方协商加密,建立安全信道
    → 客户端用密钥/密码完成认证
    → 交互式 shell 建立

首次连接会弹"确认主机密钥指纹"的提示,敲 yes 即可,回车后主机指纹被记录到 ~/.ssh/known_hosts。

用 ssh 登录

ssh root@2.25.183.241         # 以 root 登录(默认端口 22)
ssh -p 2222 root@host         # 指定非默认端口
ssh root@bangdream.xyz        # 用域名登录

提示 首次登录出现 Are you sure you want to continue connecting (yes/no)? 是正常的指纹确认,输入 yes。如果连接时提示 Host key verification failed,说明服务器主机密钥变了(重装/换了机器),要 ssh-keygen -R host 清掉旧指纹再连,或手动编辑 ~/.ssh/known_hosts 删除该行。

密钥机制:ssh-keygen 与免密登录

SSH 用非对称加密:一把私钥(留在本地)、一把公钥(放到服务器)。登录时服务器用公钥加密挑战,客户端用私钥解密,既能认证用户又能避免密码在网络上传递。

ssh-keygen -t ed25519 -C "my-key"     # 生成默认 ed25519 密钥
ssh-keygen -t rsa -b 4096             # 或生成 4096 位 RSA
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519   # 指定输出目录
cat ~/.ssh/id_ed25519.pub             # 查看公钥内容

生成后在本地 ~/.ssh 会得到 id_ed25519(私钥,保密)和 id_ed25519.pub(公钥,发给服务器)。把公钥放到服务器的授权文件即可:

ssh-copy-id root@bangdream.xyz       # 一键把本机公钥装到服务器
# 等价于:把公钥内容追加到服务器 ~/.ssh/authorized_keys
ssh-copy-id -p 2222 root@bangdream.xyz   # 指定端口

警告 私钥(id_ed25519)绝不能泄露外传。私钥权限必须是 600(chmod 600 ~/.ssh/id_ed25519),authorized_keys 权限 600、目录 ~/.ssh 权限 700。权限过宽会让 SSH 拒绝使用密钥甚至直接拒绝登录。

传文件:scp 与 sftp

往服务器传配置、日志、项目文件,用 scp 最直接:

scp ./local.txt root@bangdream.xyz:/root/       # 本机上传到服务器
scp root@bangdream.xyz:/var/log/nginx/access.log .  # 从服务器下载
scp -P 2222 -r ./dir root@host:/root/          # 递归传目录,-P 指定端口

SSH 登录后也可以用 sftp 交互式传文件。现代 SSH 也支持 SFTP 子命令,和 scp 同一套加密传输,传输重要文件用 sftp 更稳。

配置文件 ~/.ssh/config

如果你常在固定的几台机器间切换,写一个 ~/.ssh/config 能省不少事:

Host bangdream
    HostName bangdream.xyz
    User root
    Port 22
    IdentityFile ~/.ssh/id_ed25519

之后直接 ssh bangdream 即可,不再输地址、端口、用户。

加固 sshd_config:只留密钥登录

这是运维的重中之重。/etc/ssh/sshd_config 控制服务器端行为。真实这台机当前生效配置:

sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|pubkeyauthentication|port|maxauthtries'
port 22
permitrootlogin without-password   # root 不得用密码登录(等同 prohibit-password)
pubkeyauthentication yes
passwordauthentication yes         # 普通用户仍可密码登录,建议改 no
maxauthtries 6

关键项及含义:

配置项 含义 推荐值
PermitRootLogin 是否允许 root 登录 prohibit-password(只允许密钥)
PasswordAuthentication 是否允许密码登录 no(只允许密钥)
PubkeyAuthentication 是否允许密钥登录 yes
Port SSH 监听端口 默认 22,加固可改非标端口
MaxAuthTries 最大认证尝试次数 设小一点,配合 fail2ban
PermitEmptyPasswords 是否允许空密码 no

易错点 当前机器 permitrootlogin without-password 表示 root 只能用密钥登录;但 passwordauthentication yes 表示普通用户仍可密码登录。若要彻底禁止密码登录,改成 PasswordAuthentication no 才是干净的,只留密钥。root 密码登录已封,普通用户密码仍可破,这是很多人忽略的盲区。

改完必须 reload 再验证:systemctl reload ssh(或 sshd -t 先校验语法),并新开一个终端测试连通后再关原来的连接——否则改错了立马失联。

一次完整的加固操作

# 1. 确认密钥已能登录(先做这一步,否则加固会把自己锁死)
ssh-copy-id root@bangdream.xyz

# 2. 改配置
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config

# 3. 校验语法 + 重载
sshd -t
systemctl reload ssh

# 4. 新开终端测连接,再确认

警告 上面第 2 步 PasswordAuthentication no 会立刻禁止密码登录。务必先确认你已有可用的密钥登录方式,并且保留一个已登录的会话,再用另一个终端验证新配置能连上。一旦漏配,可能连不上、回不来,只能走云商控制台救援。

易错点

  • 先验证密钥、再禁密码:顺序反了会把管理员自己锁在门外。
  • 私钥权限必须严格:600 私钥、700 ~/.ssh 目录、600 authorized_keys。
  • 改 sshd_config 后 systemctl reload,别用 restart 断掉现有连接;且先 sshd -t 校验语法。
  • Host key verification failed 是新机/换机指纹变化,ssh-keygen -R 清掉旧记录再连。
  • 公网 SSH 建议配合 fail2ban + 白名单 IP(见第 6、8 章),裸奔 22 端口很容易被暴力扫描。

相关命令

ssh、scp、sftp、ssh-keygen、ssh-copy-id、sshd、ssh-agent(加载密钥)、ssh-add。配置文件:/etc/ssh/sshd_config、~/.ssh/authorized_keys、~/.ssh/config。