SSH 命令从新手入门到安全运维

一、SSH基础命令

ssh 是SSH协议的核心命令,用于建立客户端与远程服务器的加密连接并实现登录。其最核心的价值在于"安全"------所有数据传输(包括密码、指令、返回结果)均通过非对称加密+对称加密的组合方式加密,有效防止数据被监听、篡改或伪造。

1. 基本语法与默认登录

基本格式:ssh [选项] 远程用户@远程主机

默认情况下,SSH使用22号端口,若远程服务器未修改SSH端口,可直接通过简化命令登录:

bash 复制代码
# 示例:使用root用户登录IP为192.168.1.100的服务器
ssh root@192.168.1.100

执行后会提示输入远程用户的密码,验证通过后即可进入远程服务器的命令行界面。

2. 常用核心选项

  • -p:指定非默认端口 :若远程服务器修改了SSH端口(如为了安全改为2222),必须通过-p指定端口,否则连接失败。

    示例:ssh -p 2222 root@192.168.1.100

  • -i:指定身份验证密钥 :使用密钥认证时,通过-i指定本地私钥文件路径,替代密码登录。

    示例:ssh -i ~/.ssh/my_ssh_key root@192.168.1.100

  • -o:自定义连接参数 :用于覆盖/etc/ssh/ssh_config~/.ssh/config中的默认配置,常见场景如禁用严格主机密钥检查(首次连接时跳过指纹确认)、设置连接超时等。

    示例1(跳过主机指纹确认):ssh -o StrictHostKeyChecking=no root@192.168.1.100

    示例2(设置连接超时10秒):ssh -o ConnectTimeout=10 root@192.168.1.100

  • -t:强制分配伪终端 :在远程执行需要交互的命令(如sudo、top)时,需通过-t分配终端,否则可能无法正常交互。

    示例:ssh -t root@192.168.1.100 sudo systemctl restart nginx

  • -L/-R:端口转发 :实现本地端口与远程端口的映射,用于穿透防火墙、访问内网服务等场景(反向代理核心用法)。

    本地端口转发(访问远程内网服务):ssh -L 本地端口:远程内网主机:远程内网端口 远程服务器用户@远程服务器IP

    示例:通过192.168.1.100访问其内网10.0.0.5的80端口,本地映射到8080:ssh -L 8080:10.0.0.5:80 root@192.168.1.100

    远程端口转发(让远程访问本地服务):ssh -R 远程端口:本地主机:本地端口 远程服务器用户@远程服务器IP

    示例:将本地80端口的服务映射到192.168.1.100的8888端口,供远程访问:ssh -R 8888:localhost:80 root@192.168.1.100

3. 免交互执行远程命令

无需登录远程服务器,直接在本地执行远程命令并返回结果,适合批量运维、脚本自动化场景。

bash 复制代码
# 格式:ssh 远程用户@远程主机 "命令1; 命令2"

示例1:查看远程服务器的系统信息

bash 复制代码
ssh root@192.168.1.100 "uname -r; cat /etc/os-release"

示例2:远程创建目录并上传文件(结合后续scp命令)

bash 复制代码
ssh root@192.168.1.100 "mkdir -p /data/backup" && scp backup.tar.gz root@192.168.1.100:/data/backup

二、SSH密钥认证

SSH支持两种认证方式:密码认证(简单但安全性低,易被暴力破解)和密钥认证(基于非对称加密,安全性高,是生产环境的首选)。密钥认证的核心是"公钥-私钥对":私钥保存在本地客户端,绝对保密;公钥可公开,存放在远程服务器的~/.ssh/authorized_keys文件中。以下命令围绕密钥的生成、管理和缓存展开。

1. ssh-keygen:生成SSH密钥对

ssh-keygen 用于生成RSA、ED25519等类型的密钥对,其中ED25519是较新的算法,安全性优于传统RSA,且密钥长度更短(256位即可达到RSA 2048位的安全性),推荐优先使用。

(1)基本用法(生成默认密钥对)
bash 复制代码
ssh-keygen -t ed25519 -C "your_email@example.com"

参数说明:

  • -t ed25519:指定密钥算法为ED25519(若服务器版本较旧不支持,可改用-t rsa -b 2048,2048位RSA密钥);

  • -C:添加备注信息(通常填写邮箱,用于区分不同密钥的用途)。

执行后会出现三次交互提示:

  1. "Enter file in which to save the key":指定密钥保存路径,默认保存在~/.ssh/目录下,文件名默认为id_ed25519(私钥)和id_ed25519.pub(公钥),按回车使用默认路径;

  2. "Enter passphrase":设置私钥密码(推荐设置,即使私钥泄露,攻击者也需密码才能使用),若无需密码直接按回车;

  3. "Enter same passphrase again":重复输入私钥密码,完成生成。

(2)自定义密钥文件名与路径

若需要管理多个密钥(如同时连接多个不同服务器),可自定义密钥文件名,避免冲突:

bash 复制代码
ssh-keygen -t ed25519 -f ~/.ssh/server_1_key -C "server_1_login"

参数-f指定密钥保存路径和文件名,生成后会在~/.ssh/目录下得到server_1_key(私钥)和server_1_key.pub(公钥)。

2. ssh-agent:私钥缓存代理

若私钥设置了密码,每次使用密钥认证登录远程服务器时,都需要输入私钥密码,频繁操作会非常繁琐。ssh-agent 是一个后台进程,用于缓存已解锁的私钥,只需在首次使用时输入一次私钥密码,后续连接时自动复用缓存的私钥,无需重复输入密码。

(1)启动ssh-agent
bash 复制代码
# Linux/macOS(sh/bash/zsh终端)
eval "$(ssh-agent -s)"

# 若使用csh/tcsh终端,需用以下命令
eval `ssh-agent -c`

参数说明:

  • -s:输出sh/bash兼容的环境变量(默认);

  • -c:输出csh兼容的环境变量。

启动成功后,会输出SSH_AGENT_PID(代理进程ID)和SSH_AUTH_SOCK(代理套接字路径),eval 命令会自动将这些环境变量注入当前终端,让后续的ssh-add等命令能找到代理进程。

(2)验证ssh-agent是否启动
bash 复制代码
# 查看ssh-agent进程
ps aux | grep ssh-agent

# 查看环境变量
echo $SSH_AGENT_PID
echo $SSH_AUTH_SOCK
(3)关闭ssh-agent
bash 复制代码
ssh-agent -k

执行后会终止当前终端的ssh-agent进程,缓存的私钥也会失效。

3. ssh-add:管理agent中的私钥

ssh-add 用于将本地私钥添加到ssh-agent的缓存中,也可查看、删除缓存的私钥,是与ssh-agent配合使用的核心命令。

(1)添加私钥到缓存
bash 复制代码
# 添加默认私钥(~/.ssh/id_ed25519 或 ~/.ssh/id_rsa)
ssh-add

# 添加自定义私钥
ssh-add ~/.ssh/server_1_key

若私钥设置了密码,执行后会提示"Enter passphrase for ...",输入正确密码后,私钥即被缓存到ssh-agent中。

(2)查看缓存的私钥
bash 复制代码
# 列出缓存私钥的指纹(简洁模式,便于识别)
ssh-add -l

# 列出缓存私钥对应的公钥内容(详细模式)
ssh-add -L
(3)删除缓存的私钥
bash 复制代码
# 删除指定私钥
ssh-add -d ~/.ssh/server_1_key

# 删除所有缓存的私钥
ssh-add -D
(4)设置私钥缓存超时

为了进一步提升安全性,可设置缓存超时时间,超时后私钥自动从ssh-agent中失效,需重新输入密码添加。

bash 复制代码
# 缓存1小时(3600秒)后失效
ssh-add -t 3600 ~/.ssh/id_ed25519

三、SSH免密登录

生成密钥对后,需要将本地公钥复制到远程服务器的~/.ssh/authorized_keys文件中(该文件用于存储允许登录的客户端公钥),才能实现密钥认证。手动复制公钥容易出现权限错误、格式问题,ssh-copy-id 命令可一键完成公钥复制,并自动配置正确的权限,是实现免密登录的核心工具。

1. 基本用法(复制默认公钥)

bash 复制代码
ssh-copy-id root@192.168.1.100

执行流程:

  1. 提示输入远程服务器的用户密码(最后一次输入密码,后续即可免密);

  2. 验证通过后,自动读取本地默认公钥(~/.ssh/id_ed25519.pub~/.ssh/id_rsa.pub);

  3. 在远程服务器的~/.ssh/目录下创建authorized_keys文件(若不存在),并将本地公钥追加到该文件中;

  4. 自动配置~/.ssh/目录(权限700)和authorized_keys文件(权限600),避免因权限过高导致SSH拒绝使用密钥认证。

2. 复制指定公钥

若使用自定义密钥对(如前面生成的server_1_key),需通过-i参数指定公钥文件路径:

bash 复制代码
ssh-copy-id -i ~/.ssh/server_1_key.pub root@192.168.1.100

注意:-i后必须跟公钥文件(带.pub后缀),不可指定私钥。

3. 远程SSH端口非默认时

若远程服务器修改了SSH端口(如2222),需通过-p参数指定端口:

bash 复制代码
ssh-copy-id -p 2222 -i ~/.ssh/server_1_key.pub root@192.168.1.100

4. 手动复制公钥(备用方案)

若服务器不支持ssh-copy-id命令(如部分老旧系统),可手动复制公钥内容到远程服务器的authorized_keys文件:

bash 复制代码
# 本地读取公钥内容并复制到远程
cat ~/.ssh/id_ed25519.pub | ssh -p 2222 root@192.168.1.100 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh"

四、SSH文件传输

除了远程登录,SSH还支持加密的文件传输,核心工具为scp(Secure Copy,基于SSH的文件复制)和sftp(Secure FTP,基于SSH的文件传输协议),两者均通过SSH加密通道传输数据,安全性远高于传统FTP。

1. scp:简单高效的文件复制

scp 用法与Linux本地cp命令类似,支持"本地→远程""远程→本地""远程→远程"三种传输方向,自动递归复制目录。

(1)本地文件传输到远程
bash 复制代码
# 格式:scp [选项] 本地文件 远程用户@远程主机:远程路径
scp -P 2222 ~/local_file.tar.gz root@192.168.1.100:/data/backup/

参数说明:-P(大写)指定SSH端口(注意与ssh命令的-p小写区分);若传输目录,需添加-r参数(递归复制)。

bash 复制代码
# 传输本地目录到远程
scp -r -P 2222 ~/local_dir root@192.168.1.100:/data/
(2)远程文件传输到本地
bash 复制代码
# 格式:scp [选项] 远程用户@远程主机:远程文件 本地路径
scp -P 2222 root@192.168.1.100:/data/backup/remote_file.tar.gz ~/local_backup/
bash 复制代码
# 传输远程目录到本地
scp -r -P 2222 root@192.168.1.100:/data/remote_dir ~/local_dir/
(3)常用优化选项
  • -v:显示详细传输日志(用于排查传输错误);

  • -C:传输时压缩数据,提升传输速度(适合大文件);

  • -i:使用指定私钥进行认证(免密传输)。

bash 复制代码
# 免密、压缩传输大文件
scp -C -i ~/.ssh/my_ssh_key -P 2222 large_file.iso root@192.168.1.100:/data/

2. sftp:交互式文件传输

sftp 提供交互式的文件传输界面,支持文件上传、下载、删除、重命名、创建目录等操作,适合需要多次交互的文件管理场景(如批量上传/下载多个零散文件)。

(1)连接远程服务器
bash 复制代码
# 格式:sftp [选项] 远程用户@远程主机
sftp -P 2222 root@192.168.1.100

连接成功后,提示符变为sftp>,进入交互式模式。

(2)核心交互命令
  • 本地操作(前缀l):lpwd(查看本地当前目录)、lcd 路径(切换本地目录)、lls(列出本地文件);

  • 远程操作:pwd(查看远程当前目录)、cd 路径(切换远程目录)、ls(列出远程文件)、mkdir 目录名(创建远程目录)、rm 文件名(删除远程文件);

  • 文件传输:put 本地文件(本地→远程)、get 远程文件(远程→本地)、put -r 本地目录(递归上传目录)、get -r 远程目录(递归下载目录);

  • 退出连接:exitquit

(3)示例:交互式上传/下载
bash 复制代码
# 连接远程服务器
sftp -P 2222 root@192.168.1.100

# 查看远程当前目录
sftp> pwd

# 切换远程目录到/data/backup
sftp> cd /data/backup

# 查看本地当前目录
sftp> lpwd

# 切换本地目录到~/local_backup
sftp> lcd ~/local_backup

# 上传本地文件到远程
sftp> put backup.tar.gz

# 下载远程文件到本地
sftp> get remote_backup.tar.gz

# 退出连接
sftp> exit

五、SSH服务端配置:sshd_config与sshd

前面介绍的命令均为客户端命令,若需要配置SSH服务器(如修改端口、禁用密码登录、限制登录用户等),需操作服务端的sshd_config配置文件(SSH服务端主配置文件)和sshd服务命令。

1. 核心配置文件:/etc/ssh/sshd_config

修改配置前,建议先备份原配置文件:

bash 复制代码
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

常用核心配置项(修改后需重启sshd服务生效):

  • Port 22:SSH服务端口,建议修改为非22端口(如2222),降低暴力破解风险;

  • PermitRootLogin no:禁用root用户直接登录(推荐,可通过普通用户登录后su切换到root);

  • PasswordAuthentication no:禁用密码认证,仅允许密钥认证(推荐,彻底杜绝暴力破解);

  • PubkeyAuthentication yes:启用密钥认证(默认开启);

  • AuthorizedKeysFile .ssh/authorized_keys:指定公钥存储文件路径(默认值,无需修改);

  • AllowUsers user1 user2:仅允许指定用户登录(白名单机制,提升安全性);

  • ClientAliveInterval 60:每隔60秒向客户端发送心跳包,避免连接超时;

  • ClientAliveCountMax 3:客户端无响应3次后断开连接。

2. sshd服务管理命令

sshd是SSH服务端的守护进程,需通过系统服务命令管理(不同系统命令略有差异)。

bash 复制代码
# 查看sshd服务状态(CentOS/RHEL 7+/Ubuntu 16.04+)
systemctl status sshd  # CentOS/RHEL
systemctl status ssh   # Ubuntu(服务名是ssh)

# 重启sshd服务(修改配置后必须重启)
systemctl restart sshd  # CentOS/RHEL
systemctl restart ssh   # Ubuntu

# 设置sshd服务开机自启
systemctl enable sshd  # CentOS/RHEL
systemctl enable ssh   # Ubuntu

# 停止sshd服务
systemctl stop sshd  # CentOS/RHEL
systemctl stop ssh   # Ubuntu

注意:修改SSH端口后,重启服务前需确保防火墙开放新端口(如2222),否则会无法连接。

六、完整实操流程:从密钥生成到安全运维

结合前文命令,整理一套"生成密钥→免密登录→安全配置"的完整实操流程,适用于生产环境服务器初始化:

1. 客户端生成密钥对

bash 复制代码
ssh-keygen -t ed25519 -f ~/.ssh/prod_server_key -C "prod_server_login"

2. 启动ssh-agent并添加私钥

bash 复制代码
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/prod_server_key  # 输入私钥密码缓存

3. 复制公钥到远程服务器

bash 复制代码
ssh-copy-id -i ~/.ssh/prod_server_key.pub -p 22 root@192.168.1.100

4. 验证免密登录

bash 复制代码
ssh -i ~/.ssh/prod_server_key -p 22 root@192.168.1.100

5. 服务端安全配置(远程服务器操作)

bash 复制代码
# 备份sshd配置文件
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# 编辑配置文件(使用vim)
vim /etc/ssh/sshd_config

# 修改以下配置项
Port 2222                # 改端口
PermitRootLogin no       # 禁用root登录
PasswordAuthentication no  # 禁用密码认证
AllowUsers prod_user     # 仅允许prod_user登录
ClientAliveInterval 60
ClientAliveCountMax 3

# 保存退出vim后,重启sshd服务
systemctl restart sshd

# 开放防火墙2222端口(CentOS示例)
firewall-cmd --add-port=2222/tcp --permanent
firewall-cmd --reload

6. 客户端测试新配置连接

bash 复制代码
ssh -i ~/.ssh/prod_server_key -p 2222 prod_user@192.168.1.100

七、常见问题与避坑指南

  1. 密钥认证失败

    原因1:远程authorized_keys~/.ssh权限过高(如777),SSH会拒绝使用。解决方案:登录远程服务器执行chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

    原因2:公钥内容复制不完整或格式错误。解决方案:重新使用ssh-copy-id复制,或手动复制时确保公钥一行完整。

    原因3:客户端私钥权限过高(如644),SSH会提示"Permissions are too open"。解决方案:chmod 600 ~/.ssh/prod_server_key

  2. ssh-agent重启终端后失效

    解决方案1(macOS):开启Keychain集成,执行ssh-add -K ~/.ssh/prod_server_key,将私钥密码存入Keychain,下次自动加载。

    解决方案2(Linux):将启动命令加入终端配置文件(如~/.bashrc),但需注意自动加载会跳过密码验证,仅适合本地安全机器:
    echo 'eval "$(ssh-agent -s)" && ssh-add ~/.ssh/prod_server_key' >> ~/.bashrc,执行source ~/.bashrc生效。

  3. 修改SSH端口后无法连接

    原因:防火墙未开放新端口,或配置文件中Port参数写错。解决方案:登录服务器本地(或通过控制台)开放端口,检查sshd_config中Port配置是否正确,重启sshd服务。

  4. scp传输大文件中断

    解决方案:使用-C压缩传输,或通过rsync(基于SSH)实现断点续传:rsync -avz -e "ssh -p 2222 -i ~/.ssh/prod_server_key" ~/large_file.iso root@192.168.1.100:/data/

八、总结

SSH相关命令构成了远程服务器管理的核心工具链,从基础的ssh登录,到安全的密钥管理(ssh-keygenssh-agentssh-add),再到免密配置(ssh-copy-id)和文件传输(scpsftp),以及服务端安全配置(sshd_config),每个命令都有其明确的应用场景。掌握这些命令的核心用法,不仅能提升远程操作的效率,更能保障服务器的安全。建议在实际使用中遵循"密钥认证优先、禁用密码登录、修改默认端口、限制登录用户"的安全原则,构建可靠的远程管理环境。

相关推荐
Aphasia3111 天前
VPN 与内网穿透
安全
Mr_愚人派2 天前
当"Claude"不再是 Claude:一次第三方 API 代理引发的 AI 身份伪造排查实录
人工智能·安全
大树883 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
开发者联盟league3 天前
安装pnpm
ssh
DaLi Yao3 天前
【无标题】
人工智能·安全
Inhand陈工3 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn863 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
网络研究院3 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展