SSH(Secure Shell)是一种能够让用户安全访问远程系统的网络协议,它为不安全网络中的两台主机提供了一个强加密数据通信通道。SSH是Linux、UNIX系统管理员操作和管理主机的首选方式。虽然SSH比其他通信方式更加安全,但是错误的配置也可能导致其出现安全问题。这篇文章的目的就是提供一个帮助你加固SSH的指南。
一、安全需求
远程登录,只允许普通账号通过密钥登录
禁止root远程登录
禁止密码登录
开启防火墙
如果是云主机,同步配置安全规则
禁止ping
二、实际操作
2.1 服务端操作
# 查看是否安装了ssh
systemctl status ssh
# 安装
sudo apt install -y openssh-server
# 确定机器的IP
ip addr
# 确认是否可以访问
ping 192.168.2.123
# 检查防火墙
sudo ufw status verbose
# 开启防火墙
sudo ufw enable
# 开放端口
sudo ufw allow 22
# 设置开放来自某IP访问某端口的权限
sudo ufw allow from your_ip to any port 22
# ssh登录
ssh k8s@192.168.2.123 -p 22
# 修改端口
vi /etc/ssh/sshd_config
# 重启sshd服务
systemctl restart sshd
2.1.1 ssh的管理
Ubuntu
# 检查是否安装
sudo dpkg -l | grep ssh
# 查看运行状态
sudo systemctl status ssh
# 安装
sudo apt install -y openssh-server
# 卸载
sudo apt remove openssh-server
# 启动
sudo systemctl start ssh
# 关闭
sudo systemctl start stop
# 设置开机启动
sudo systemctl enable ssh
# 关闭开机启动
sudo systemctl disable ssh
CentOS
# 检查是否安装
rpm -qa | grep ssh
# 查看运行状态
systemctl status sshd
# 安装
yum install -y openssl openssh-server
# 卸载
yum remove openssh-server
# 启动
systemctl start sshd
# 关闭
systemctl stop sshd
# 设置开机启动
systemctl enable sshd
# 关闭开机启动
systemctl disable sshd
# 查看开机启动的服务
systemctl list-unit-files | grep sshd
2.1.2 ssh的配置
配置文件的位置 /etc/ssh/sshd_config
# 个性端口(默认为22)
Port 12345
# 只用新版本的协议,旧版协议有漏洞(旧版本默认允许新旧(2,1)协议,新版本默认只接受新协议)
Protocol 2
# 禁止使用密码登入(默认允许)
PasswordAuthentication no
# 禁止空密码账户登入(默认禁止)
PermitEmptyPasswords no
# 禁止 root 账户通过密码登入(默认允许)
PermitRootLogin without-password
# 禁止 root 账户通过 SSH 登入(默认允许)
PermitRootLogin no
# 只允许白名单内的用户登入(默认允许所有用户登入)
AllowUsers jack mary
# 或禁止黑名单内的用户通过 SSH 登入(默认允许所有用户登入)
DenyUsers alice bob@corporation
# 禁用密码登录,禁用口令认证
PasswordAuthentication:no
# 启用密钥身份验证(默认开启)
PubkeyAuthentication yes
# 不允许DNS解析,登录速度更快
UseDNS:no
# 限制最大身份验证尝试次数
MaxAuthTries 3
# 输出最后一次登录日期和时间(默认就是开启的),可以意识到未经授权的账户登录事件,这将对进一步调查无法识别的访问提供帮助
PrintLastLog yes
# 结束空闲的SSH会话,在短时间内终止空闲的SSH会话,不给他人留机会
# 十五分钟(900秒)后关闭不活动的会话
ClientAliveInterval 900
ClientAliveCountMax 0
# 禁用X11Forwarding
X11Forwarding no
# 禁用基于基于主机的身份认证(默认就是no)
HostBasedAuthentication no
# 在身份验证时忽略已知主机
IgnoreUserKnownHosts yes
# 确保SSH不允许受信主机连接,这是一个老旧的配置,应当在SSH配置中明确禁用。
# hosts文件是一种控制系统间信任的关系的方法,如果一个系统信任另一个系统,则这个系统不需要密码就允许来自受信认系统的登录。
IgnoreRhosts yes
# 在身份验证时忽略已知主机
IgnoreUserKnownHosts yes
# 默认情况下,SSH会监听本机上配置的所有IP地址,但是你应该指定SSH绑定在特定的IP,最好是在专用VLAN中的地址。
# 指定绑定地址,请修改配置文件如下
# ListenAddress 10.0.0.5
# 确保启用严格模式,检查用户特定的配置文件
StrictModes yes
# 防止特权升级
UsePrivilegeSeparation sandbox
# 禁用 GSSAPI 认证
GSSAPIAuthentication no
# 禁用Kerberos认证
KerberosAuthentication no
2.1.3 保护主机的公钥与私钥
# 使用ls命令列出/etc/ssh/目录下所有的公钥文件:
ls -l /etc/ssh/*pub
# 使用chmod命令修改公钥文件权限:
chmod 0644 /etc/ssh/*pub
# 使用ls命令列出/etc/ssh/文件夹下所有的私钥文件:
ls -l /etc/ssh/*key
# 使用chmod命令设置私钥文件权限:
chmod 0600 /etc/ssh/*key
# 大多数情况下,私钥文件存储在/etc/ssh/文件夹下,但是也有可能存储在其他目录中,通过以下命令可以检索配置文件中设置的存储位置:
grep -i hostkey /etc/ssh/sshd_config
2.1.4 增加防火墙规则
iptables
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5000 -j ACCEPT
# 执行以下命令查看iptables现有规则是否已包含5000端口。
iptables -L -n
# 允许特定IP连接:
iptables -I INPUT -p tcp -s <指定的IP> --dport 22 -j ACCEPT
# 允许特定的子网:
iptables -I INPUT -p tcp -s <指定子网> --dport 22 -j ACCEPT
fireawlld
# 允许特定IP连接SSH:
firewall-cmd --permanent --zone=public --add-rich-rule=' rule family="ipv4" source address="<指定IP>" port protocol="tcp" port="22" accept'
# 允许特定子网:
firewall-cmd --permanent --zone=public --add-rich-rule=' rule family="ipv4" source address="<指定子网>" port protocol="tcp" port="22" accept'
ufw
# 允许特定IP连接SSH:
sudo ufw allow from <指定IP> to any port 22
# 允许特定子网:
sudo ufw allow from <指定子网> to any port 22
2.1.5 添加安全组规则
如果是云服务器,还需要在上面ssh端口允许通过的安全组规则
2.2 终端操作
2.2.1 配置快捷登录
# 生成密钥
ssh-keygen -t ed25519
# 将公钥传到服务器,从而实现密钥登录
ssh-copy-id xxx@x.x.x.x
# 配置~/.ssh/config,快捷登录
Host short_name
HostName x.x.x.x
User xxx
Port xxx
IdentityFile ~/.ssh/id_ed25519
# 这样就可以这样快捷登录了
ssh short_name
# 没有配置时的登录命令
ssh -p xxs xx@x.x.x.x
参考文章