SSH简易指南#

Secure Shell Protocol(简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中建立安全隧道来实现SSH客户端与服务器之间的连接。SSH最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。

安装启用SSH#

Ubuntu / Debian#

# 客户端 (通常已经安装)
sudo apt update
sudo apt install -y openssh-client

# 服务端
sudo apt install -y openssh-server
sudo systemctl enable --now ssh
sudo systemctl status ssh   # 检查运行状态

CentOS / RHEL#

sudo yum install -y openssh-server openssh-clients
sudo systemctl enable --now sshd
sudo systemctl status sshd

MacOS#

MacOS已经预装OpenSSH客户端, 开启SSH服务方法: System Preferences → Sharing → enable Remote Login

或者使用如下命令:

sudo systemsetup -setremotelogin on

Windows 10/11#

  • 最新版Windows已经包含OpenSSH客户端,命令行下可直接使用: ssh
  • 安装OpenSSH服务: 设置 → 应用 → 可选功能 → 添加OpenSSH服务, 或者使用PowerShell/winget/choco安装。
  • 也可使用 WSL 或 PuTTY (三方客户端).

创建SSH密钥对#

创建密钥时可指定加密算法,推荐使用 ed25519,或者使用兼容性更好的RSA (4096bit)

# 推荐: ed25519 (快速并安全)
ssh-keygen -t ed25519 -a 100 -C "your-email@example.com" -f ~/.ssh/id_ed25519

#如果旧系统需要使用RSA:
ssh-keygen -t rsa -b 4096 -C "your-email@example.com" -f ~/.ssh/id_rsa
  • -a 100 增加KDF轮数,减慢暴力破解速度以提高安全性
  • -C 添加comment(电子邮件)
  • 系统会要求你输入密码短语——建议设置

生成文件如下:

  • ~/.ssh/id_ed25519 (私钥 — 请妥善保管)
  • ~/.ssh/id_ed25519.pub (公钥 — 可以分享)

设置密钥文件权限:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

在服务器上添加公钥#

使用ssh-copy-id命令#

#添加密钥到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server

#连接服务器
ssh user@server

手动安装#

# 本地查看公钥内容
cat ~/.ssh/id_ed25519.pub

# 服务器操作
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 复制公钥内容到authorized_keys
echo "ssh-ed25519 AAAA... your-comment" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

SSH基础用法#

# 登录服务器 (默认端口22)
ssh user@host

# 指定端口
ssh -p 2222 user@host

# 指定私钥文件
ssh -i ~/.ssh/id_ed25519 user@host

#远程执行命令并退出
ssh user@host 'ls -la /var/www'

#复制文件到远端
scp localfile.txt user@host:/home/user/

#递归复制目录
scp -r localdir user@host:/home/user/

SSH实用选项说明#

  • -i /path/to/key → 指定密钥文件
  • -p PORT → 指定端口
  • -C → 启用压缩
  • -N → 不执行远程命令,在端口转发时很有用
  • -f → 发送到后台(或 -N)
  • -L local_port:dest_host:dest_port本地 端口转发
  • -R remote_port:dest_host:dest_port远程 端口转发(反向隧道)
  • -D local_port → 动态 SOCKS 代理(用于通过远程主机代理浏览器)

示例:在本地主机1080端口创建 SOCKS 代理。

ssh -D 1080 -C -N user@server
# 然后就可以再浏览器中设置SOCKS5代理,地址为127.0.0.1:1080

SSH 配置文件#

创建/编辑 ~/.ssh/config 来定义主机别名、端口、密钥以及其他设置:

Host myserver
  HostName server.example.com
  User alice
  Port 2222
  IdentityFile ~/.ssh/id_ed25519
  ForwardAgent no
  ServerAliveInterval 60

# 跳板/堡垒主机示例
Host private-host
  HostName internal.example.local
  User bob
  ProxyJump jumpuser@jumphost.example.com

# 连接服用,用来加速多个会话
Host *
  ControlMaster auto
  ControlPath ~/.ssh/cm-%r@%h:%p
  ControlPersist 10m

使用 ssh myserver 替代冗长的命令


代理与密码管理#

启动代理并添加密钥(将密码保存在内存中):

# Start agent and add key (Linux/macOS)
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# List added keys
ssh-add -l

在macOS上,与钥匙串集成:ssh-add -K ~/.ssh/id_ed25519 (旧版macOS) 或者在较新版本中使用 SSH 代理集成。

在 Windows 上,使用 Pageant(PuTTY)或 Windows OpenSSH 代理。

警告: 转发代理(ForwardAgent yes)允许远程主机使用你的代理——这很方便,但如果远程主机被入侵就会带来风险。


文件传输: scp, sftp, rsync#

# scp复制 (本地 -> 远端)
scp file.txt user@server:/path/

# scp复制 (远端 -> 本地)
scp user@server:/path/file.txt .

# sftp交互式操作
sftp user@server
sftp> put localfile
sftp> get remotefile

# 通过SSH使用rsync同步内容(快速、高效)
rsync -avz -e "ssh -p 2222" ./localdir/ user@server:/remote/dir/

端口转发和隧道示例#

本地端口转发:本地访问远程数据库#

ssh -L 5433:127.0.0.1:5432 user@dbserver -N
# 现在本地连接到端口 5433 -> 转发到远程 127.0.0.1:5432
psql -h 127.0.0.1 -p 5433 -U dbuser dbname

远程端口转发(将本地服务暴露到远程)#

ssh -R 9000:localhost:3000 user@remoteserver -N
# 远程服务器可以通过 localhost:9000 访问您的本地服务

动态SOCKS代理#

ssh -D 1080 user@jumphost -N
# 配置浏览器使用 127.0.0.1:1080 的 SOCKS5

###反向SSH(使NAT内网的计算机可访问)

# 在NAT内网的机器上:
ssh -R 2222:localhost:22 user@public-host -N
# 然后从公共主机:
ssh -p 2222 localhost   #连接到 NAT内网机器

加固SSH服务器安全#

编辑 /etc/ssh/sshd_config文件,完成后重启服务 sudo systemctl restart sshd:

建议设置:

PermitRootLogin no                #禁止root登录
#强制密钥认证,关闭密码登录,请确保配置完密钥重新使用密钥登录成功后再设置该项
PasswordAuthentication no        
ChallengeResponseAuthentication no
UsePAM yes
AllowUsers alice bob              # 设置许可用户
X11Forwarding no                  # 如果不需要则禁用
PermitEmptyPasswords no
Port 22 (如果需要建议改为非标端口)
PubkeyAuthentication yes

另:

  • 使用 ufw 或防火墙只放行必要的端口 (sudo ufw allow OpenSSH).
  • 安装 fail2ban 来阻止重复的错误身份验证尝试。
  • 定期更新 openssh 软件包。

重要提示: 如果您禁用 PasswordAuthentication,请确保已经设置可用的密钥,并通过密钥登陆成功,否则密码登陆将失效可能会把自己关在 门外


验证主机密钥并防止中间人攻击#

首次连接到主机时,SSH 会将服务器的主机密钥存储在 ~/.ssh/known_hosts 中。如果该密钥以后发生更改,SSH服务器会提示你。

最佳做法:在添加服务器时,请与系统管理员核对密钥:

# 服务器操作
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

然后将该密钥与您的客户首次连接时显示的密钥进行比较。如果不认识并且你盲目接受,就有遭受中间人攻击的风险。

非交互式添加主机密钥(如果您信任网络):

ssh-keyscan -t ed25519 server >> ~/.ssh/known_hosts

故障排除#

  • Permission denied (publickey)

    • 意味着服务器没有接受你的密钥。检查服务器上的~/.ssh/authorized_keys文件权限(chmod 700 ~/.ssh,chmod 600 ~/.ssh/authorized_keys),确保用户名正确,或者使用 ssh -i key。
  • Host key verification failed.

    • 已知主机密钥已更改。删除旧条目:ssh-keygen -R hostname,然后重新添加或向管理员验证。
  • Connection refused

    • SSH服务器未运行(sudo systemctl status sshd)或防火墙阻止了端口。
  • No route to host / Network is unreachable

    • 网络/DNS 问题 — 检查网络连接和主机/IP。
  • Too many authentication failures

    • 客户端尝试了多次密钥连接并失败。使用 ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes user@host
  • 使用verbose模式显示详细信息:

ssh -v user@host        # verbose
ssh -vvv user@host      # very verbose

额外提醒#

  • 如果支持,请使用 ed25519 密钥;除非需要,可备用 RSA 4096。
  • 妥善保管私钥(chmod 600)并保留备份(加密)。
  • 使用代理(ssh-agent)以避免重复输入密码短语。
  • 使用 ~/.ssh/config 来简化多主机配置,并使用ProxyJump进行堡垒机跳转。
  • 切勿暴露你的私钥。如果公钥泄露,请从 authorized_keys 中删除。
  • 对于高安全性账户,考虑使用硬件支持的密钥(YubiKey / FIDO2)(ssh-keygen -t ed25519-sk)。
  • 通过 SSH 使用 Git,将你的公钥添加到 Git 托管账户(GitHub/GitLab/Bitbucket)中。

SSH快速配置示例#

  1. 本地生成密钥: ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
  2. 复制公钥到服务器: ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
  3. 登录服务器: ssh user@server
  4. 加固服务器安全: edit /etc/ssh/sshd_configPermitRootLogin no, PasswordAuthentication nosudo systemctl restart sshd
  5. 通过 ~/.ssh/config 配置使用 ssh myalias 以方便使用。

SSH使用快速参考#

# 连接服务器
ssh user@host                # default port 22
ssh -p 2222 user@host        # different port
ssh -i ~/.ssh/id_ed25519 user@host

# 复制文件
scp file.txt user@host:/path/
scp -r dir/ user@host:/path/

# 隧道
ssh -L 8080:127.0.0.1:80 user@host     # local forward
ssh -R 9000:localhost:3000 user@host   # remote forward
ssh -D 1080 user@host -N                # dynamic SOCKS

# 调试
ssh -v user@host
ssh -vvv -i key user@host

# 代理
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Favicon