Skip to content

SSH 远程连接

什么是 SSH?

SSH(Secure Shell)是一种加密的网络协议,用于在不安全的网络中安全地远程登录和执行命令。SSH 取代了不安全的 telnet、rlogin 等协议。

SSH 基础

安装 SSH

bash
# 安装 SSH 客户端(通常已预装)
$ sudo apt install openssh-client

# 安装 SSH 服务端
$ sudo apt install openssh-server

# 启动 SSH 服务
$ sudo systemctl start ssh
$ sudo systemctl enable ssh

# 检查状态
$ sudo systemctl status ssh

基本连接

bash
# 基本格式
$ ssh username@hostname

# 连接远程服务器
$ ssh maxwell@192.168.1.100
$ ssh maxwell@server.example.com

# 指定端口
$ ssh -p 2222 maxwell@192.168.1.100

# 使用当前用户名
$ ssh 192.168.1.100

首次连接

首次连接会显示主机指纹确认:

bash
$ ssh maxwell@192.168.1.100
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.1.100' (ED25519) to the list of known hosts.

SSH 密钥认证

密钥认证比密码认证更安全、更方便。

生成密钥对

bash
# 生成 Ed25519 密钥(推荐)
$ ssh-keygen -t ed25519 -C "your_email@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/maxwell/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/maxwell/.ssh/id_ed25519
Your public key has been saved in /home/maxwell/.ssh/id_ed25519.pub

# 生成 RSA 密钥(兼容性更好)
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 指定文件名
$ ssh-keygen -t ed25519 -f ~/.ssh/mykey -C "comment"

密钥文件

文件说明
~/.ssh/id_ed25519私钥(保密!)
~/.ssh/id_ed25519.pub公钥(可分发)
~/.ssh/authorized_keys授权的公钥列表
~/.ssh/known_hosts已知主机指纹
~/.ssh/config客户端配置

复制公钥到服务器

bash
# 使用 ssh-copy-id(推荐)
$ ssh-copy-id maxwell@192.168.1.100
$ ssh-copy-id -i ~/.ssh/mykey.pub maxwell@192.168.1.100

# 手动复制
$ cat ~/.ssh/id_ed25519.pub | ssh maxwell@192.168.1.100 \
    "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# 查看公钥
$ cat ~/.ssh/id_ed25519.pub

设置正确的权限

bash
# 本地
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/id_ed25519
$ chmod 644 ~/.ssh/id_ed25519.pub
$ chmod 600 ~/.ssh/config

# 服务器
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys

使用特定密钥

bash
$ ssh -i ~/.ssh/mykey maxwell@192.168.1.100

SSH 配置文件

客户端配置 ~/.ssh/config

bash
# 默认配置
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

# 特定主机配置
Host myserver
    HostName 192.168.1.100
    User maxwell
    Port 22
    IdentityFile ~/.ssh/id_ed25519

# 另一个服务器
Host dev
    HostName dev.example.com
    User deploy
    Port 2222
    IdentityFile ~/.ssh/deploy_key

# 通过跳板机连接
Host internal
    HostName 10.0.0.100
    User admin
    ProxyJump bastion

# 跳板机
Host bastion
    HostName bastion.example.com
    User jump

使用配置后的连接:

bash
$ ssh myserver    # 等同于 ssh maxwell@192.168.1.100
$ ssh dev         # 等同于 ssh -p 2222 deploy@dev.example.com

服务器配置 /etc/ssh/sshd_config

bash
# 端口
Port 22

# 监听地址
ListenAddress 0.0.0.0

# 禁止 root 登录
PermitRootLogin no

# 禁止密码认证(仅使用密钥)
PasswordAuthentication no

# 允许公钥认证
PubkeyAuthentication yes

# 授权密钥文件
AuthorizedKeysFile .ssh/authorized_keys

# 最大认证尝试次数
MaxAuthTries 3

# 空闲超时
ClientAliveInterval 300
ClientAliveCountMax 2

# 限制用户
AllowUsers maxwell alice
DenyUsers bob

# 限制组
AllowGroups sshusers

修改配置后重启 SSH:

bash
$ sudo systemctl restart ssh

SSH 高级用法

执行远程命令

bash
# 执行单个命令
$ ssh maxwell@server "ls -la"

# 执行多个命令
$ ssh maxwell@server "cd /var/www && git pull"

# 交互式命令需要 -t
$ ssh -t maxwell@server "sudo apt update"

端口转发

本地端口转发

将本地端口转发到远程主机:

bash
# 格式:ssh -L 本地端口:目标主机:目标端口 跳板机
$ ssh -L 8080:localhost:80 maxwell@server

# 访问远程数据库
$ ssh -L 3306:localhost:3306 maxwell@server
# 然后本地连接 localhost:3306

# 通过跳板机访问内网服务
$ ssh -L 8080:internal.server:80 maxwell@bastion

远程端口转发

将远程端口转发到本地:

bash
# 格式:ssh -R 远程端口:本地主机:本地端口 服务器
$ ssh -R 8080:localhost:3000 maxwell@server
# 远程访问 server:8080 会转发到本地 3000

动态端口转发(SOCKS 代理)

bash
$ ssh -D 1080 maxwell@server
# 本地 1080 端口成为 SOCKS5 代理

后台运行端口转发

bash
# -f 后台运行,-N 不执行命令
$ ssh -fN -L 8080:localhost:80 maxwell@server

文件传输

scp - 安全复制

bash
# 上传文件到服务器
$ scp file.txt maxwell@server:/home/maxwell/
$ scp file.txt maxwell@server:~

# 上传到指定路径
$ scp file.txt maxwell@server:/var/www/

# 下载文件
$ scp maxwell@server:/var/log/app.log ./

# 复制目录
$ scp -r directory/ maxwell@server:~/

# 指定端口
$ scp -P 2222 file.txt maxwell@server:~/

# 使用配置文件中的主机
$ scp file.txt myserver:~/

rsync - 高效同步

bash
# 同步目录到服务器
$ rsync -avz ./local/ maxwell@server:/remote/

# 从服务器同步
$ rsync -avz maxwell@server:/remote/ ./local/

# 删除目标中源不存在的文件
$ rsync -avz --delete ./local/ maxwell@server:/remote/

# 排除文件
$ rsync -avz --exclude='*.log' ./local/ maxwell@server:/remote/

# 显示进度
$ rsync -avz --progress ./local/ maxwell@server:/remote/

# 干运行(不实际执行)
$ rsync -avzn ./local/ maxwell@server:/remote/

sftp - 交互式传输

bash
$ sftp maxwell@server
sftp> ls
sftp> cd /var/www
sftp> put local_file.txt
sftp> get remote_file.txt
sftp> mkdir new_dir
sftp> rm old_file.txt
sftp> quit

SSH Agent

SSH Agent 可以缓存私钥密码:

bash
# 启动 agent
$ eval $(ssh-agent)

# 添加密钥
$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/maxwell/.ssh/id_ed25519:
Identity added: /home/maxwell/.ssh/id_ed25519

# 列出已添加的密钥
$ ssh-add -l

# 删除所有密钥
$ ssh-add -D

# 转发 agent(在跳板机上使用本地密钥)
$ ssh -A maxwell@bastion

跳板机/堡垒机

bash
# 通过跳板机连接
$ ssh -J jump@bastion maxwell@internal

# 多级跳转
$ ssh -J jump1@host1,jump2@host2 maxwell@target

# 在配置文件中设置
Host internal
    HostName 10.0.0.100
    User maxwell
    ProxyJump bastion

安全最佳实践

1. 禁用密码认证

bash
# /etc/ssh/sshd_config
PasswordAuthentication no

2. 禁用 root 登录

bash
# /etc/ssh/sshd_config
PermitRootLogin no

3. 更改默认端口

bash
# /etc/ssh/sshd_config
Port 2222

4. 使用强密钥

bash
# 使用 Ed25519 或 RSA 4096 位
$ ssh-keygen -t ed25519
$ ssh-keygen -t rsa -b 4096

5. 设置密钥密码

生成密钥时设置密码,使用 SSH Agent 管理。

6. 限制用户

bash
# /etc/ssh/sshd_config
AllowUsers maxwell alice

7. 使用 Fail2ban

bash
$ sudo apt install fail2ban
$ sudo systemctl enable fail2ban

故障排查

调试连接

bash
# 详细输出
$ ssh -v maxwell@server
$ ssh -vv maxwell@server   # 更详细
$ ssh -vvv maxwell@server  # 最详细

常见问题

Permission denied

bash
# 检查权限
$ ls -la ~/.ssh/
# 确保 600 权限

# 检查服务器日志
$ sudo tail -f /var/log/auth.log

Connection refused

bash
# 检查 SSH 服务是否运行
$ sudo systemctl status ssh

# 检查端口
$ ss -tlnp | grep 22

# 检查防火墙
$ sudo ufw status

Host key verification failed

bash
# 删除旧的主机密钥
$ ssh-keygen -R 192.168.1.100

小结

本章介绍了 SSH 的使用:

  • 基本连接ssh user@host
  • 密钥认证ssh-keygenssh-copy-id
  • 配置文件~/.ssh/config
  • 文件传输scprsyncsftp
  • 端口转发:本地、远程、动态
  • 安全配置:禁用密码、禁用 root

SSH 是 Linux 服务器管理的核心工具,熟练掌握它将大大提高你的工作效率。


上一章:网络基础

下一章:Shell 脚本基础