Linux服务器管理完全攻略 第5篇:SSH与远程服务器管理
Linux Server Administration Complete Guide Part 5
Linux服务器管理完全攻略系列
第4篇:网络与防火墙 | 第5篇:SSH与远程管理 (当前) | 第6篇:Shell脚本基础
前言:SSH,远程服务器管理的核心
SSH(Secure Shell)是通过网络安全连接和管理远程服务器的协议。它通过加密通信保护数据,是现代服务器运维中最重要的工具之一。本篇将从SSH基础到高级用法全面讲解。
1. SSH基础
1.1 SSH基本连接
# 基本连接
ssh username@hostname
# 指定端口连接
ssh -p 2222 username@hostname
# 通过IP地址连接
ssh user@192.168.1.100
# 详细调试模式
ssh -v username@hostname
ssh -vvv username@hostname # 更详细信息
1.2 SSH服务器安装与状态检查
# Ubuntu/Debian
sudo apt update
sudo apt install openssh-server
# RHEL/CentOS
sudo dnf install openssh-server
# 检查SSH服务器状态
sudo systemctl status sshd
# 启动/停止/重启服务
sudo systemctl start sshd
sudo systemctl stop sshd
sudo systemctl restart sshd
# 开机自动启动
sudo systemctl enable sshd
1.3 断开SSH连接
# 正常退出
exit
logout
Ctrl + D
# 会话卡住时强制断开
~. # 按Enter后输入~.
2. SSH密钥认证
2.1 生成密钥对
# 生成RSA密钥(默认)
ssh-keygen -t rsa -b 4096
# 生成Ed25519密钥(推荐,更安全更快)
ssh-keygen -t ed25519
# 指定文件名生成
ssh-keygen -t ed25519 -f ~/.ssh/myserver_key
# 添加注释
ssh-keygen -t ed25519 -C "admin@company.com"
# 查看生成的文件
ls -la ~/.ssh/
# id_ed25519 - 私钥(绝不分享)
# id_ed25519.pub - 公钥(注册到服务器)
2.2 将公钥注册到服务器
# 使用ssh-copy-id(最简单的方法)
ssh-copy-id username@hostname
ssh-copy-id -i ~/.ssh/myserver_key.pub username@hostname
# 手动注册
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 或在服务器上直接操作
# 将公钥内容添加到~/.ssh/authorized_keys文件
# 权限设置(重要!)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
2.3 密钥认证连接
# 使用默认密钥连接
ssh username@hostname
# 指定特定密钥
ssh -i ~/.ssh/myserver_key username@hostname
# 避免输入密码短语(ssh-agent)
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519
ssh-add -l # 查看已注册的密钥
3. SSH配置文件
3.1 客户端配置(~/.ssh/config)
# ~/.ssh/config 示例
# Web服务器
Host webserver
HostName 192.168.1.10
User admin
Port 22
IdentityFile ~/.ssh/webserver_key
# 开发服务器(使用别名)
Host dev
HostName dev.company.com
User developer
Port 2222
# DB服务器(通过跳板机)
Host dbserver
HostName 10.0.0.50
User dbadmin
ProxyJump webserver
# 所有主机通用设置
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
# 现在可以简单连接
# ssh webserver
# ssh dev
3.2 服务器配置(/etc/ssh/sshd_config)
# 主要安全设置
# 更改端口
Port 2222
# 禁用root登录
PermitRootLogin no
# 禁用密码认证(仅允许密钥认证)
PasswordAuthentication no
# 禁止空密码
PermitEmptyPasswords no
# 仅允许特定用户
AllowUsers admin deploy
# 仅允许特定组
AllowGroups sshusers
# 限制登录尝试
MaxAuthTries 3
# 最大会话数
MaxSessions 5
# 禁用X11转发
X11Forwarding no
# 应用设置
sudo sshd -t # 语法检查
sudo systemctl restart sshd
4. 文件传输:SCP和SFTP
4.1 SCP(安全复制)
# 本地 → 远程(文件)
scp file.txt user@host:/path/to/destination/
# 本地 → 远程(目录)
scp -r mydir/ user@host:/path/to/destination/
# 远程 → 本地
scp user@host:/path/to/file.txt ./local/
# 使用其他端口
scp -P 2222 file.txt user@host:/path/
# 使用特定密钥
scp -i ~/.ssh/mykey file.txt user@host:/path/
# 压缩传输(适用于大文件)
scp -C largefile.zip user@host:/path/
# 带宽限制(KB/s)
scp -l 1000 file.txt user@host:/path/
# 服务器间传输
scp user1@host1:/file.txt user2@host2:/path/
4.2 SFTP(SSH文件传输协议)
# SFTP连接
sftp user@host
sftp -P 2222 user@host
# SFTP命令
sftp> pwd # 远程当前目录
sftp> lpwd # 本地当前目录
sftp> ls # 远程文件列表
sftp> lls # 本地文件列表
sftp> cd /path # 切换远程目录
sftp> lcd /path # 切换本地目录
sftp> get file.txt # 下载
sftp> get -r dir/ # 下载目录
sftp> put file.txt # 上传
sftp> put -r dir/ # 上传目录
sftp> rm file.txt # 删除
sftp> mkdir newdir # 创建目录
sftp> exit # 退出
4.3 rsync over SSH
# 基本同步
rsync -avz source/ user@host:/destination/
# 同步已删除的文件
rsync -avz --delete source/ user@host:/destination/
# 使用其他端口
rsync -avz -e "ssh -p 2222" source/ user@host:/dest/
# 显示进度
rsync -avz --progress source/ user@host:/dest/
# 测试运行(dry-run)
rsync -avzn source/ user@host:/dest/
5. SSH隧道(端口转发)
5.1 本地端口转发
将本地机器的端口通过远程服务器连接到其他服务器。
# 语法:ssh -L [本地端口]:[目标主机]:[目标端口] [SSH服务器]
# 示例:通过本地3306连接远程DB服务器
ssh -L 3306:localhost:3306 user@sshserver
# 示例:访问远程服务器后面的其他服务器
ssh -L 8080:internal-web.lan:80 user@sshserver
# 后台运行
ssh -fNL 3306:localhost:3306 user@sshserver
# 现在可以通过localhost:3306连接DB
mysql -h localhost -P 3306 -u dbuser -p
5.2 远程端口转发
将远程服务器的端口连接到本地机器。
# 语法:ssh -R [远程端口]:[本地主机]:[本地端口] [SSH服务器]
# 示例:将远程服务器的8080转发到本地的80
ssh -R 8080:localhost:80 user@sshserver
# 从外部访问远程服务器的8080时转发到本地80
# 后台运行
ssh -fNR 8080:localhost:80 user@sshserver
5.3 动态端口转发(SOCKS代理)
# 创建SOCKS代理
ssh -D 1080 user@sshserver
# 后台运行
ssh -fND 1080 user@sshserver
# 在浏览器或应用程序中配置SOCKS5代理
# 代理:localhost:1080
5.4 跳板主机(代理跳转)
# 使用-J选项(OpenSSH 7.3+)
ssh -J jumphost user@targetserver
# 多个跳板主机
ssh -J jump1,jump2 user@target
# 旧方法(-o ProxyCommand)
ssh -o ProxyCommand="ssh -W %h:%p jumphost" user@target
# 在~/.ssh/config中配置
Host internal
HostName 10.0.0.50
User admin
ProxyJump jumphost
6. SSH安全加固
6.1 sshd_config安全设置
# /etc/ssh/sshd_config
# 禁用密码认证(仅允许密钥)
PasswordAuthentication no
ChallengeResponseAuthentication no
# 禁止root登录
PermitRootLogin no
# 禁止空密码
PermitEmptyPasswords no
# 禁用键盘交互认证
KbdInteractiveAuthentication no
# 仅允许协议版本2(默认)
Protocol 2
# 限制登录尝试
MaxAuthTries 3
LoginGraceTime 30
# 仅允许特定IP连接(sshd_config或防火墙)
# AllowUsers admin@192.168.1.0/24
# 限制TCP转发
AllowTcpForwarding no
AllowAgentForwarding no
# 仅允许强加密算法
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# 应用前语法检查
sudo sshd -t
sudo systemctl restart sshd
6.2 安装Fail2Ban
# Ubuntu/Debian
sudo apt install fail2ban
# RHEL/CentOS
sudo dnf install fail2ban
# 创建配置文件
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# 编辑/etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log # Debian/Ubuntu
# logpath = /var/log/secure # RHEL/CentOS
maxretry = 3
bantime = 3600
findtime = 600
# 启动服务
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# 检查状态
sudo fail2ban-client status sshd
6.3 双因素认证(2FA)
# 安装Google Authenticator
sudo apt install libpam-google-authenticator
# 初始化设置
google-authenticator
# PAM配置(/etc/pam.d/sshd)
auth required pam_google_authenticator.so
# sshd_config设置
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
# 重启服务
sudo systemctl restart sshd
7. SSH代理和密钥管理
7.1 使用SSH代理
# 启动代理
eval $(ssh-agent)
# 添加密钥
ssh-add # 默认密钥
ssh-add ~/.ssh/mykey # 特定密钥
ssh-add -t 3600 ~/.ssh/key # 1小时后自动删除
# 查看已注册的密钥
ssh-add -l
# 删除密钥
ssh-add -d ~/.ssh/mykey # 特定密钥
ssh-add -D # 所有密钥
# 终止代理
ssh-agent -k
7.2 SSH代理转发
# 使用-A选项进行代理转发
ssh -A user@server1
# 现在可以从server1使用本地密钥连接其他服务器
ssh user@server2
# 在~/.ssh/config中配置
Host server1
ForwardAgent yes
# 注意:仅在可信服务器上使用
7.3 密钥管理最佳实践
# 按用途分离密钥
ssh-keygen -t ed25519 -f ~/.ssh/work_key -C "work"
ssh-keygen -t ed25519 -f ~/.ssh/personal_key -C "personal"
# 设置强密码短语
ssh-keygen -t ed25519 -f ~/.ssh/mykey
# (交互式输入密码短语)
# 检查密钥权限
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
chmod 700 ~/.ssh
# 更换旧密钥
# 1. 生成新密钥
# 2. 在服务器上注册新密钥
# 3. 测试
# 4. 删除旧密钥
8. 远程服务器管理技巧
8.1 会话保持(keepalive)
# 客户端配置(~/.ssh/config)
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# 服务器配置(/etc/ssh/sshd_config)
ClientAliveInterval 60
ClientAliveCountMax 3
8.2 与tmux/screen配合使用
# 创建tmux会话
tmux new -s mysession
# 分离会话(Ctrl+B, D)
# SSH连接断开后工作继续
# 重新连接后恢复会话
tmux attach -t mysession
# 列出会话
tmux ls
8.3 同时管理多台服务器
# 在多台服务器上执行相同命令
for server in server1 server2 server3; do
ssh $server "uptime"
done
# 使用parallel-ssh
pssh -h hosts.txt -l user "uptime"
# 使用Ansible(推荐)
ansible all -m ping
ansible all -a "uptime"
8.4 SSH连接复用
# ~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
# 创建socket目录
mkdir -p ~/.ssh/sockets
# 首次连接后,后续连接更快
9. 故障排除
9.1 常见错误
# Permission denied (publickey)
# → 检查密钥权限
chmod 600 ~/.ssh/id_*
chmod 700 ~/.ssh
# Host key verification failed
# → 从known_hosts中删除该主机
ssh-keygen -R hostname
# Connection refused
# → 检查SSH服务器是否运行
sudo systemctl status sshd
# Connection timed out
# → 检查防火墙
sudo ufw status
sudo firewall-cmd --list-all
9.2 调试模式
# 客户端调试
ssh -v user@host # 基本
ssh -vv user@host # 详细
ssh -vvv user@host # 非常详细
# 服务器调试(前台运行)
sudo /usr/sbin/sshd -d -p 2222
10. 实践:SSH安全检查清单
# 1. 设置密钥认证
ssh-keygen -t ed25519
ssh-copy-id user@server
# 2. 禁用密码认证
# /etc/ssh/sshd_config
PasswordAuthentication no
# 3. 禁止root登录
PermitRootLogin no
# 4. 更改端口(可选)
Port 2222
# 5. 配置防火墙
sudo ufw allow 2222/tcp
sudo ufw enable
# 6. 安装Fail2Ban
sudo apt install fail2ban
# 7. 应用设置
sudo sshd -t && sudo systemctl restart sshd
# 8. 测试
ssh -p 2222 user@server
总结
SSH是远程服务器管理的核心工具。使用密钥认证、应用适当的安全设置、利用隧道功能,可以实现安全高效的服务器管理。下一篇我们将通过Shell脚本基础开始服务器管理自动化之旅。