
SSH常用配置详解
SSH(Secure Shell)是一种加密网络协议,用于在不安全的网络(如互联网)上安全地进行远程登录、命令执行、文件传输等操作。它取代了早期不安全的明文协议(如 Telnet、FTP、rlogin),是系统管理员、开发者和IT运维人员必备的核心工具。
一、核心功能与用途
安全远程登录: 登录到远程服务器执行命令(替代 Telnet)。
安全文件传输:
scp
(Secure Copy):基于 SSH 的命令行文件传输工具。
sftp
(SSH File Transfer Protocol):提供类似 FTP 的交互式文件传输接口。
rsync over SSH
:高效的文件同步工具,利用 SSH 加密传输。
端口转发 / 隧道:
本地端口转发: 将本地端口映射到远程服务器的端口(访问本地端口即访问远程服务)。
远程端口转发: 将远程服务器端口映射到本地端口(让远程访问本地服务)。
动态端口转发: 创建 SOCKS 代理,将所有流量通过 SSH 服务器转发。
安全执行远程命令: 无需登录交互式 Shell,直接在远程执行单条命令。
安全 X11 转发: 在本地显示运行在远程服务器上的图形界面程序(需要 X Server)。
代理转发: 允许通过跳板机(Bastion Host/Jump Server)连接到无法直接访问的内网服务器。
二、核心组件
SSH 客户端: 发起连接请求的程序(如
ssh
,scp
,sftp
, PuTTY, SecureCRT, MobaXterm)。SSH 服务器: 接收连接请求并处理的后台程序(通常称为
sshd
)。密钥对:
公钥: 放置在远程服务器上(
~/.ssh/authorized_keys
)。私钥: 严格保管在本地客户端(
~/.ssh/id_rsa
,~/.ssh/id_ed25519
等),通常设置权限600
。
三、工作原理(SSHv2)
TCP 连接建立: 客户端连接到服务器的 22 端口(默认)。
协议版本协商: 客户端和服务端协商使用 SSH 协议版本(强烈推荐使用 SSH-2)。
密钥交换: 使用 Diffie-Hellman 等算法协商出一个临时的会话密钥。此过程确保即使攻击者截获了交换信息,也无法计算出会话密钥(前向保密)。
服务端认证:
服务端向客户端发送其 主机密钥(公钥)。
客户端检查此密钥是否在已知信任列表(
~/.ssh/known_hosts
)中。如果是首次连接,客户端会提示用户验证并确认接受该主机密钥(防止中间人攻击)。
用户认证:
密码认证: 用户输入密码,密码通过加密通道传输到服务端验证。
公钥认证(推荐):
客户端告知服务端其想使用的公钥 ID。
服务端检查该公钥是否在用户的
authorized_keys
文件中。服务端生成一个随机数,用该公钥加密,发送给客户端。
客户端用对应的私钥解密,将结果发回服务端。
服务端验证结果正确则认证成功。
其他方式:键盘交互认证(用于一次性密码)、基于主机的认证(较少用)。
加密通道建立: 使用协商好的会话密钥和对称加密算法(如 AES, ChaCha20)加密后续所有通信。
数据完整性: 使用 HMAC(基于哈希的消息认证码)算法(如 SHA-256)保证传输的数据未被篡改。
会话复用: 通过
ControlMaster
和ControlPath
配置,复用已建立的连接,避免重复认证开销。
四、配置文件
客户端全局配置:
/etc/ssh/ssh_config
客户端用户配置:
~/.ssh/config
(非常常用,简化连接)使用:
ssh myserver
,ssh internal-db
服务端配置:
/etc/ssh/sshd_config
(修改后需重启sshd
服务)关键配置项:
Port
:监听端口。
PermitRootLogin
:是否允许 root 登录 (推荐no
或prohibit-password
)。
PasswordAuthentication
:是否允许密码认证 (推荐no
,强制使用公钥)。
PubkeyAuthentication
:是否启用公钥认证 (推荐yes
)。
AllowUsers
/AllowGroups
:限制可登录的用户/组。
X11Forwarding
:是否允许 X11 转发。
PermitEmptyPasswords
:是否允许空密码 (必须no
)。
ClientAliveInterval
/ClientAliveCountMax
:保持连接活跃设置。
五、基本用法(命令行客户端)
使用密码登录的方式连接:
安装SSHyum install openssh -y # Centos和RedHat # 或 apt install openssh-server -y # Debain和Ubuntu
修改ssh的配置文件,使客户端可以正常连接
vim /etc/ssh/sshd_config 找到并修改以下内容: Port 22 # 监听22端口 Protocol 2 # 强制使用SSHv2 PermitRootLogin yes # 运行root用户登录
重新启动ssh服务
systemctl restart sshd
可以使用以下格式连接:
ssh root@192.168.10.10 # 默认使用22端口,如果使用别的端口,需要使用-p后跟端口(小写p)
如果我们仅仅允许某个用户登录,其他用户为了安全不允许登录,可以设置白名单AllowUsers xxxx
使用密钥登录:
在本地生成密钥对:
ssh-keygen -t ed25519
(推荐) 或ssh-keygen -t rsa -b 4096
Windows端
CMD或PowerShell输入,一直回车即可
ssh-keygen -t rsa -b 4096 # 生成RSA算法的SSH私钥和公钥,不加-d选项也可
生成私钥和公钥后会存储在C盘该用户目录下的.ssh目录内,接下来将公钥发送到Linux服务器上
scp C:\Users\OpenNW\.ssh\id_rsa.pub opennw@172.16.0.102:/home/opennw
Linux端
cd /hmoe/opennw mkdir .ssh chmod 700 .ssh mv id_rsa.pub authorized_keys chmod 600 authorized_keys mv authorized_keys .ssh/
vim /etc/ssh/sshd_config 修改以下内容: Port 22 # 监听22端口 Protocol 2 # 强制使用SSHv2 LoginGraceTime 1m # 登录超时时间1分钟 PermitRootLogin without-password # 仅允许Root用户使用秘钥登录 DenyUsers xxx # 禁止xxx用户登录 MaxAuthTries 3 # 最大认证次数3 MaxSessions 2 # 最大会话数2 PasswordAuthentication no # 禁止密码验证登录 PermitEmptyPasswords no # 禁止空密码验证 UseDNS no # 不对客户端进行DNS泛解析验证,加快SSH连接速度 PubkeyAuthentication yes # 开启SSH公钥认证登录 AuthorizedKeysFile .ssh/authorized_keys # 用户登录公钥路径,如果该用户需要多设备免密登录,可以再authorized_keys文件内另起一行写入其他设备的公钥,也可以在此配置后再跟上.ssh/xxx_keys即可 RSAAuthentication yes # 允许RSA算法验证 保存并退出
systemctl restart sshd systemctl enable sshd
随后,客户端使用SSH命令登录服务器端无需输入密码即可登录,且为了安全我们已经设置了强制使用密钥登录(禁止密码登录),接下来我们要做的就是保证刚才生成的私钥文件不被泄露即可~
执行远程命令:
ssh username@hostname 'command_to_run' # 例如:ssh alice@server.example.com 'ls -l /tmp'
文件传输:
scp (复制文件):
首先确保ssh服务端配置文件中开启了以下内容Subsystem sftp /usr/lib/openssh/sftp-server
随后,在客户端上可进行以下命令使用scp文件传输
# 复制本地文件到远程 scp /path/to/local/file username@hostname:/path/to/remote/directory # 复制远程文件到本地 scp username@hostname:/path/to/remote/file /path/to/local/directory # 指定端口需要使用scp -P 2222 ...(大写P) # 传输目录需要使用scp -r ...
sftp (交互式文件传输):
sftp username@hostname sftp> put localfile [remotepath] # 上传 sftp> get remotefile [localpath] # 下载 sftp> ls # 列出远程目录 sftp> lls # 列出本地目录 sftp> cd, lcd, mkdir, rmdir, ... # 类似 FTP 命令 sftp> exit / bye
六、端口转发(隧道)
本地端口转发: 将本地端口绑定到远程服务的端口。
场景: 访问远程服务器内部网络的服务(如数据库)。
命令:
ssh -L [bind_address:]local_port:remote_host:remote_port username@ssh_server
示例: 将本地
3307
端口映射到远程服务器内网主机db.internal
的3306
(MySQL) 端口:ssh -L 3307:db.internal:3306 alice@jumpserver.example.com
访问本地的
127.0.0.1:3307
即访问jumpserver
能访问到的db.internal:3306
。
远程端口转发: 将远程服务器端口绑定到本地服务的端口。
场景: 将本地开发环境暴露给外部访问(临时演示)、让内网服务被外网访问。
命令:
ssh -R [bind_address:]remote_port:local_host:local_port username@ssh_server
示例: 将远程服务器
jumpserver
的8080
端口映射到本地127.0.0.1:3000
(本地 Web 服务):ssh -R 8080:localhost:3000 alice@jumpserver.example.com
访问
jumpserver.example.com:8080
即访问本地的localhost:3000
。
注意: 默认远程服务器只监听
127.0.0.1
(localhost
),如需外部访问,需在服务端sshd_config
中设置GatewayPorts yes
并重启sshd
。
动态端口转发: 创建 SOCKS 代理服务器。
场景: 所有应用程序流量通过 SSH 服务器转发,绕过本地网络限制或加密流量。
命令:
ssh -D [bind_address:]local_socks_port username@ssh_server
示例: 在本地
1080
端口启动 SOCKS5 代理:ssh -D 1080 alice@proxy.example.com
随后终端会像正常连接ssh一样登录到远程服务器上,但同时如果你在Windows终端使用
netstat -ano | findstr :1080
会看到该端口已经被监听,然后只要终端不关闭,就可以使用Socks5配置SSH代理,使流量被远程服务器代理转发。且由于Socks5是应用层代理也不需要配置复杂的NAT;系统代理:可在控制面板中,找到
网络和Internet
—Internet选项
—连接
—局域网设置
—勾选为LAN使用代理服务器
—高级
—套接字地址为127.0.0.1,端口为1080
,其余都删除。取消掉对本地不使用代理服务器
随后代理生效。但需要注意的是,设置了代理后,系统中并不是所有程序都会监听代理,如命令行及UDP,而浏览器默认是支持的,这是和VPN的一个主要区别;浏览器代理:在火狐浏览器或系统网络设置中配置代理为
SOCKS5
,地址127.0.0.1
,端口1080
,则所有流量通过proxy.example.com
加密转发。浏览器代理:如果使用的是谷歌浏览器,默认不支持SOCKS5,可在浏览器扩展中安装扩展
Socks5 configurator
,在扩展页面设置即可好后保存即可,接下来浏览器查询自己的IP地址即可发现IP地址已经发生变化。如果希望关闭代理,最好先在扩展中关闭,然后再关闭终端窗口。
七、日志查看(基于debain)
修改SSH配置文件,日志为auth类型
vim /etc/ssh/sshd_config
SyslogFacility AUTH
LogLevel VERBOSE # 日志等级为“详细”
保存退出
修改rsyslog中auth类型日志存放位置
vim /etc/rsyslog.conf
auth,authpriv.* /var/log/auth.log
保存退出
重启SSH服务和rsyslog服务
systemctl restart sshd
systemctl restart rsyslog
查看登录成功简要信息
last
查看登录失败简要信息
lastb
查看日志中登录成功和失败的详细信息
cat /var/log/auth.log | grep Accepted
cat /var/log/auth.log | grep Failed
八、最佳安全实践
强制使用 SSHv2: 禁用过时且不安全的 SSHv1。
禁用密码登录: 仅允许公钥认证。这是防止暴力破解密码的最有效手段 (
PasswordAuthentication no
)。禁用 Root 直接登录: 使用普通用户登录后
sudo
(PermitRootLogin no
或prohibit-password
)。使用强密码/密码短语: 保护私钥和用户账户。
限制访问来源: 使用防火墙 (iptables, ufw, firewalld) 限制 SSH 端口访问 IP。
更改默认端口: 减少自动化扫描攻击 (但非绝对安全,需结合其他措施)。
使用非标准用户: 避免使用
admin
,administrator
,test
等常见用户名。保持软件更新: 及时更新 SSH 客户端和服务端 (
openssh-server
,openssh-client
)。监控日志: 定期检查
/var/log/auth.log
或/var/log/secure
中的 SSH 登录尝试。使用 Fail2ban: 自动封禁多次登录失败的 IP 地址。
谨慎使用代理转发 (
ForwardAgent
): 仅在完全信任目标服务器时使用。
九、高级技巧/应用场景
ssh-agent
和 ssh-add
: 管理私钥密码短语,避免多次输入。多因素认证 (MFA): 结合 Google Authenticator 等为 SSH 登录增加一层保护。
Git over SSH: Git 远程仓库使用 SSH URL (
git@github.com:user/repo.git
)。
sshfs
: 使用 FUSE 将远程目录挂载到本地文件系统。远程调试/服务管理:
ssh -t myserver 'sudo systemctl status nginx; journalctl -u nginx -f'
连接调试: 使用
-v
(verbose) 参数诊断连接问题:ssh -vvv username@hostname
总结
SSH 是安全远程管理的基石。理解其核心原理(加密、认证、隧道)、熟练掌握基本命令(登录、scp/sftp、端口转发)和配置文件 (~/.ssh/config
, /etc/ssh/sshd_config
),并遵循严格的安全实践(禁用密码、禁用root登录、更新、监控),是高效、安全使用 SSH 的关键。它的灵活性和强大功能使其成为连接和管理远程系统的首选工具。
- 感谢你赐予我前进的力量