OpenSSH 是一个开源的 SSH(Secure SHell)协议的实现,用于在不安全的网络中为网络服务提供安全的传输环境。OpenSSH 包括服务器端和客户端工具,可用于远程登录、文件传输和其他安全网络服务。
openssh分为服务端openssh-server
和客户端openssh-clients
:
使用 dnf
安装 OpenSSH。
sudo dnf install openssh-server openssh-clients
OpenSSH 服务器的主要配置文件为 /etc/ssh/sshd_config
。在进行任何修改后,需要重启 SSH 服务以使配置生效。
sudo systemctl restart sshd
#Port 22 # 默认SSH监听端口为22
#AddressFamily any # 指定SSH监听的地址族,any表示同时监听IPv4和IPv6
#ListenAddress 0.0.0.0 # 指定监听的IPv4地址,0.0.0.0表示监听所有地址
#ListenAddress :: # 指定监听的IPv6地址,::表示监听所有地址
HostKey /etc/ssh/ssh_host_rsa_key # 指定RSA密钥文件路径
HostKey /etc/ssh/ssh_host_ecdsa_key # 指定ECDSA密钥文件路径
HostKey /etc/ssh/ssh_host_ed25519_key # 指定ED25519密钥文件路径
# Ciphers and keying
#RekeyLimit default none # 指定重新生成密钥的数据量限制,default表示使用默认值
# Logging
#SyslogFacility AUTH # 指定日志记录的设施,AUTH表示使用auth设施
SyslogFacility AUTHPRIV # 指定日志记录的设施,AUTHPRIV表示使用authpriv设施
#LogLevel INFO # 指定日志级别,INFO表示记录信息级别的日志
# Authentication:
#LoginGraceTime 2m # 设置登录超时时间为2分钟
PermitRootLogin yes # 允许root用户通过SSH登录
#StrictModes yes # 检查用户目录和密钥文件的权限
#MaxAuthTries 6 # 设置最大认证尝试次数为6
#MaxSessions 10 # 设置最大会话数为10
#PubkeyAuthentication yes # 允许使用公钥认证
AuthorizedKeysFile .ssh/authorized_keys # 指定授权密钥文件的位置
#AuthorizedPrincipalsFile none # 指定授权主体文件的位置,none表示不使用
#AuthorizedKeysCommand none # 指定外部命令用于验证密钥,none表示不使用
#AuthorizedKeysCommandUser nobody # 指定执行AuthorizedKeysCommand的用户
#HostbasedAuthentication no # 禁止基于主机的认证
#IgnoreUserKnownHosts no # 不忽略用户known_hosts文件
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes # 忽略rhosts文件
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes # 允许密码认证
#PermitEmptyPasswords no # 不允许空密码
PasswordAuthentication yes # 允许密码认证
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes # 允许s/key密码认证
ChallengeResponseAuthentication no # 禁止s/key密码认证
# Kerberos options
#KerberosAuthentication no # 禁止Kerberos认证
#KerberosOrLocalPasswd yes # 允许Kerberos或本地密码认证
#KerberosTicketCleanup yes # 清理Kerberos票据
#KerberosGetAFSToken no # 不获取AFS令牌
#KerberosUseKuserok yes # 使用Kerberos用户ok文件
# GSSAPI options
GSSAPIAuthentication yes # 允许GSSAPI认证
GSSAPICleanupCredentials no # 不在会话结束时清理GSSAPI凭据
#GSSAPIStrictAcceptorCheck yes # 对GSSAPI接受者进行严格检查
#GSSAPIKeyExchange no # 禁止GSSAPI密钥交换
#GSSAPIEnablek5users no # 不启用k5users
UsePAM yes # 使用PAM进行认证
#AllowAgentForwarding yes # 允许SSH代理转发
#AllowTcpForwarding yes # 允许TCP转发
#GatewayPorts no # 网关端口,no表示仅监听环回接口
X11Forwarding yes # 允许X11转发
#X11DisplayOffset 10 # 设置X11显示偏移量
#X11UseLocalhost yes # 使用localhost进行X11转发
#PermitTTY yes # 允许分配TTY
PrintMotd no # 不显示motd消息
#PrintLastLog yes # 显示上次登录信息
#TCPKeepAlive yes # 发送TCP保持活动包
#PermitUserEnvironment no # 不允许用户环境
#Compression delayed # 延迟压缩
#ClientAliveInterval 0 # 设置客户端活动间隔
#ClientAliveCountMax 3 # 设置客户端活动最大次数
#UseDNS no # 不使用DNS
#PidFile /var/run/sshd.pid # 指定PID文件路径
#MaxStartups 10:30:100 # 最大启动数
#PermitTunnel no # 不允许隧道
#ChrootDirectory none # 不使用chroot目录
#VersionAddendum none # 不添加版本后缀
#Banner none # 不显示默认banner
# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS # 接受环境变量
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server # 指定sftp子系统
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no # 对特定用户禁止X11转发
# AllowTcpForwarding no # 对特定用户禁止TCP转发
# PermitTTY no # 对特定用户禁止分配TTY
# ForceCommand cvs server # 对特定用户强制命令
实际上最常用的几个参数:
命令 | 功能 | 推荐值 |
---|---|---|
加速连接速度 | ||
UseDNS no | 是否开启反向解析 | 关闭 |
GSSAPIAuthentication no | GSS认证功能 | 关闭 |
安全优化选项 | ||
Port | ssh端口号,被注释时默认为22 | 1~65535,推荐1w以上随机端口 |
PermitRootLogin | 是否运行Root用户远程登陆,默认yes(ubuntu默认no) | 在安全场景最好更改为no,提前设置好sudo权限的普通用户 |
ListenAddress | 监听的地址,允许哪些网段来ssh | 可修改,配合堡垒机等进行使用 |
PasswordAuthentication yes | 是否允许密码验证,默认yes | 可修改,配合密钥登陆一同使用 |
UsePAM yes | 是否使用PAM认证,默认yes | 需进行安全规划再选择是否关闭 |
出于安全考虑,可以将 SSH 服务器监听的端口更改为非标准端口。编辑 /etc/ssh/sshd_config
文件,找到 Port
选项,修改为所需的端口号。
Port 2222
为了增强安全性,建议禁止 root 用户通过 SSH 直接登录。编辑 /etc/ssh/sshd_config
文件,找到 PermitRootLogin
选项,修改为 no
。
PermitRootLogin no
为了提高安全性,建议使用密钥认证方式登录 SSH。要注意,密钥认证仅单向有效(收到公钥的主机,可以被免密登录。在本场景,即A想要免密访问B,所以是A生成密钥并发送公钥到B),需要双向,需要双方都发送。
#不需要再回车确认信息的命令
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''
ssh-copy-id
命令将公钥 ~/.ssh/id_rsa.pub
的内容复制到B的 ~/.ssh/authorized_keys
文件中。# 如果公钥在默认路径'~/.ssh'下,也可以不需要'-i'参数;
ssh-copy-id -i .ssh/id_rsa.pub root@服务端ip
/etc/ssh/sshd_config
文件,确保以下选项已正确设置:PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
sshpass
命令直接输入密码yum install -y sshpass
#sshpass -p 密码 ssh root@ip 执行的命令
sshpass -p password ssh root@192.168.100.150 w
sshpass
可以配合ssh-copy-id
#可能会遇到没有fingerprint,需要输入yes/no的情况,可以加-o StrictHostKeyChecking=no临时不检查主机信息
sshpass -p password ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@192.168.100.150
为了进一步提高安全性,可以禁止使用密码进行 SSH 登录。编辑 /etc/ssh/sshd_config
文件,找到 PasswordAuthentication
选项,修改为 no
。
PasswordAuthentication no
openssh-clients中的三个核心功能:
ssh -p 端口号 用户名@ip 执行的命令
#-p 可选,指定端口号,默认22
#执行的命令 可选,用于在ssh成功后直接执行的命令
ssh -p12321 root@192.168.100.151 whoami
root
scp 文件/目录 用户名@ip:路径
#-r 递归传输,传输目录
#-p 保持属性信息不变
#-P(大写) 指定端口号
scp -rp -P 22 /etc/hostname root@192.168.100.149:/tmp/
OpenSSH 客户端的主要配置文件为 /etc/ssh/ssh_config
。用户级别的配置文件为 ~/.ssh/config
。
# Host *
# ForwardAgent no # 是否转发认证代理的连接
# ForwardX11 no # 是否转发X11连接
# PasswordAuthentication yes # 是否允许使用密码进行认证
# HostbasedAuthentication no # 是否允许基于主机的认证
# GSSAPIAuthentication no # 是否允许使用GSSAPI进行认证
# GSSAPIDelegateCredentials no # 是否委派GSSAPI凭据
# GSSAPIKeyExchange no # 是否使用GSSAPI密钥交换
# GSSAPITrustDNS no # 是否信任DNS来解析GSSAPI主机名
# BatchMode no # 是否以批处理模式运行,不提示用户输入
# CheckHostIP yes # 是否检查主机IP地址
# AddressFamily any # 指定地址族,any表示同时使用IPv4和IPv6
# ConnectTimeout 0 # 连接超时时间,0表示不超时
# StrictHostKeyChecking ask # 是否严格检查主机密钥,ask表示询问用户
# IdentityFile ~/.ssh/id_rsa # 指定RSA密钥文件路径
# IdentityFile ~/.ssh/id_dsa # 指定DSA密钥文件路径
# IdentityFile ~/.ssh/id_ecdsa # 指定ECDSA密钥文件路径
# IdentityFile ~/.ssh/id_ed25519 # 指定ED25519密钥文件路径
# Port 22 # 指定默认的SSH端口
# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc # 指定允许的加密算法
# MACs hmac-md5,hmac-sha1,umac-64@openssh.com # 指定允许的MAC算法
# EscapeChar ~ # 指定转义字符
# Tunnel no # 是否创建隧道
# TunnelDevice any:any # 指定隧道设备
# PermitLocalCommand no # 是否允许执行本地命令
# VisualHostKey no # 是否显示视觉主机密钥
# ProxyCommand ssh -q -W %h:%p gateway.example.com # 指定代理命令
# RekeyLimit 1G 1h # 指定重新生成密钥的数据量和时间限制
# This system is following system-wide crypto policy.
# To modify the system-wide ssh configuration, create a *.conf file under
# /etc/ssh/ssh_config.d/ which will be automatically included below
Include /etc/ssh/ssh_config.d/*.conf # 包含/etc/ssh/ssh_config.d/目录下的所有.conf配置文件
在客户端,使用以下命令登录 SSH 服务器:
ssh 用户名@服务器地址 -p 端口号
如果使用密钥认证,客户端会自动使用 ~/.ssh/id_rsa
私钥进行认证。
为了简化使用 SSH 密钥的过程,可以使用 SSH 代理。运行以下命令以启动 SSH 代理:
ssh-agent
将生成的 SSH 密钥添加到代理中:
ssh-add ~/.ssh/id_rsa
检查服务器上的 SSH 服务是否正在运行:
sudo systemctl status sshd
确保防火墙允许 SSH 端口的流量通过:
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
检查客户端和服务器上的 SSH 密钥文件权限是否正确。正确的权限设置如下:
~/.ssh/id_rsa
:600~/.ssh/authorized_keys
:600~/.ssh
:700检查客户端和服务器上的 DNS 解析是否正常。编辑 /etc/ssh/ssh_config
文件,添加以下行以禁用 DNS 解析:
UseDNS no
#!/bin/bash
#author:tassel
#desc: 一键创建密钥,并分发
#0.import function lib
. /etc/init.d/functions
#1.variable
passwd="Huawei@123"
iplist="192.168.100.148 192.168.100.149 192.168.100.150"
#2.create id_rsa
if [ -f ~/.ssh/id_rsa ]; then
echo "已经创建密钥"
else
echo "创建密钥ing"
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' &>/dev/null
if [ $? -eq 0 ]; then
action "密钥创建成功" /bin/true
else
action "密钥创建失败" /bin/false
fi
fi
#3.copy-id
for ip in $iplist
do
sshpass -p $passwd ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@$ip &>/dev/null
if [ $? -eq 0 ]; then
action "$ip 密钥分发成功" /bin/true
else
action "$ip 密钥分发失败" /bin/false
fi
done
sh secretautosend.sh
创建密钥ing
密钥创建成功 [ OK ]
192.168.100.148 密钥分发成功 [ OK ]
192.168.100.149 密钥分发成功 [ OK ]
192.168.100.150 密钥分发成功 [ OK ]
[root@manager ~]# cat sshtest.sh
#!/bin/bash
#author: tassel
#desc: 自动测试ssh是否可以免密
#0.import function lib
. /etc/init.d/functions
#1.test
for ip in 192.168.100.{147..150}
do
ssh $ip hostname &>/dev/null
if [ $? -eq 0 ]; then
action "$ip测试成功" /bin/true
else
action "$ip 测试失败,请检查" /bin/false
fi
done
------
[root@manager ~]# sh sshtest.sh
192.168.100.147 测试失败,请检查 [FAILED]
192.168.100.148测试成功 [ OK ]
192.168.100.149测试成功 [ OK ]
192.168.100.150测试成功 [ OK ]