如题,前两天刚弄完Vuepress自动部署到云服务上,并顺手撸了篇文章:《吃灰的云主机不要忘,部署个人博客,隔壁开发都馋哭了》,今天提交新文章的时候,发现有好几次都没有更新成功。 老规矩打开ssh连一波,然后看到这个:
早料到挂在公网上的服务器容易被搞的,没想到来得这么快;
很多人估计跟我一样是安全小白,本文专门用于记录服务器运行过程中遇到的 安全问题及应对之法。
欢迎读者在评论区补充,蟹蟹~
0x1、SSH 暴力破解攻击
描述:
攻击者通过
密码字典或随机组合密码的方式尝试登陆服务器。 一般不会有明确攻击目标,针对的是全网机器,通过扫描软件直接扫描整个广播域或网段。
问了位安全大佬,回复如下:
不用过分担心,设置一个
复杂密码完事,被搞的基本是用 弱口令(简单数字和字母) 的。
em,设置个复杂密码就好,如果你对谁来撬门感兴趣的话,可以键入下述命令:
grep "Failed password for invalid user" /var/log/secure | awk '{print $13}' | sort | uniq -c | sort -nr | more
输出结果:
牛批啊,1503次,百度查下ip
2333,国外的,基本上就是代理IP了,接着说下几种常见的应对之法:
① 更换ssh端口(推荐)
把ssh端口换成一个不容易被猜解的端口号(最大不能超过65535),一般默认是 22端口,也可以键入下述命令查看:
netstat -anp|grep ssh
输出结果:
然后键入下述命令修改sshd配置文件:
vim /etc/ssh/sshd_config
找到Port 22所在的那一行,去掉前面的 #,然后回车输入 Port 自定义端口号,比如:
这里保留22端口是为了避免配置失败,还能使用22端口进行ssh登录,等配置成功后再来删它!
接着 防火墙放行下设置的端口:
firewall-cmd --zone=public --add-port=1024/tcp --permanent
firewall-cmd --reload
# 如果出现:FirewallD is not running 说明防火墙还没开启,使用下述命令开启:
systemctl start firewalld
# 通过下述命令确认防火墙状态,显示 active(running) 代表运行中
systemctl status firewalld
# 附:关闭防火墙命令
systemctl stop firewalld
# 附:移除端口
firewall-cmd --zone=public --remove-port=1024/tcp --permanent
再接着 向SELinux添加和修改ssh端口号,semanage是SELinux的管理工具,输入sem然后按下 Tab看下有没有自动补全,没有的话需要自行安装一波:
yum install policycoreutils-python
yum provides semanage
安装完,通过下述命令向SELinux添加自定义的SSH端口:
semanage port -a -t ssh_port_t -p tcp 1024
# 附:删除端口
emanage port -d -t ssh_port_t -p tcp 端口号
然后,通过下述命令查看是否添加成功
semanage port -l | grep ssh
可以,重启下ssh服务:
systemctl restart sshd.service
接着,ssh新端口试试看能否登陆:
ssh root@xxx.xxx.xxx.xxx -p 1024
如果能连上,可以把 /etc/ssh/sshd_config 中的22端口号删掉了,然后重启下ssh服务。此时再使用22端口访问:
完美,更改端口无法在根本上抵御 端口扫描,但总比没有好~
② 禁止root账号直接登录(推荐)
Linux默认管理员名为 root,只需知道root密码即可直接登录SSH,我们这样:
新建一个用户 → 禁用root用户登录 → 使用新账户登录 → su root → 输入root密码切换到root权限
知道流程,然后走一波设置命令:
# 新建用来登录的账户,比如这里的julia
useradd julia
# 设置密码,回车后输入两次密码
passwd julia
# 修改SSHD配置,禁用root登录
vim /etc/ssh/sshd_config
找到 PermitRootLogin yes,把 yes 改为 no,然后保存:
继续:
# 重启SSHD服务
service sshd restart
此时使用root账户尝试登录,即使密码正确也会提示权限被拒绝~
此时用前面建的账号登录:
ssh julia@xxx.xxx.xxx.xxx -p 1024
# 输入密码正常登录后,键入下述命令,回车后输入原先root账号
# 的密码即可获取root权限
su root
③ 设置SSH秘钥登录
如果你用过 Git的SSH免密登录,那这个对你来说就很简单了,SSH的连接 原理及过程如下:
- A → B 发送连接请求;
- B 收到请求,将
自己的公钥发给 → A;- A 收到
公钥,用公钥加密B的登录密码,生成加密密文发给 → B;- B 收到
加密密文,用自己的私钥解密信息,然后与B的登录密码做比较,正确 → 允许A登录;
然后此处用到的是 SSH免密登录,原理及过程如下:
- A → B 发送连接请求,并带上
自己的公钥;- B 收到
A的公钥,检查机器上的授权列表是否包含A的公钥,存在,
生成一个随机数,用公钥加密,生成加密密文发送 → A;- A 收到
加密密文,用私钥解密,得到的解密结果发送 → B- B 收到
A发来的结果,与之前生成的随机数作比较,一致 → 允许A连接;
了解清楚原理与过程,就很easy了,云服务器先设置下 允许秘钥认证,打开 /etc/ssh/sshd_config,找到如下内容,去掉前面的 #:
# 允许密钥认证
PubkeyAuthentication yes
# 默认公钥存放位置
AuthorizedKeysFile .ssh/authorized_keys
保存后,重启sshd服务:
# 重启ssh服务
systemctl restart sshd
# 附:其他ssh服务相关命令
rpm -qa|grep -E "openssh" # 查看是否安装了全部的ssh服务
systemctl status sshd # 查看ssh服务状态
systemctl start sshd # 启动ssh服务
systemctl stop sshd # 停止ssh服务
接着 本地PC 用 Git Bash 命令行生成 一对密钥
# 创建.ssh目录并进入
mkdir ~/.ssh
cd ~/.ssh
# 生成密钥,回车两次分别跳过 (密钥保存位置、认证密码)
ssh-keygen -t rsa -b 2048
接着可以在 ~/.ssh 目录下看到生成的 公钥(id_rsa.pub) 及 私钥(id_rsa) 。
再接着通过 ssh-copy-id 命令把公钥复制到远程主机 对应账户下 的 authorized_keys 文件上.
ssh-copy-id julia@xxx.xxx.xxx.xxx -p 1024
配置成功后,此时使用ssh即可直接登录:
ssh julia@xxx.xxx.xxx.xxx -p 1024
来到.ssh路径下可以看到 authorized_keys 文件,内容也是本地PC的公钥。
如果删除信任公钥,删除文件里对应内容即可,秘钥测试登录成功后,可以禁用密码登录,提高服务器的安全性,依然是修改 /etc/ssh/sshd_config:
PasswordAuthentication no
重启下sshd服务,然后就不能使用密码登录了~
附:WinSCP SSH 秘钥登录服务器配置,点
高级,然后选择SSH → 验证 → 密钥文件
然后选中自己的私钥,会提示转换格式,确定,保存就好
接着,直接登录,弹出下述对话框,点是,后续登录就不用输入密码了。
④ 安装DenyHosts
描述:(官网:denyhosts.sourceforge.net/)
基于Python编写,用于防止SSH暴力破解的开源软件,通过对SSH的日志文件
/var/log/secure进行分析,查找所有尝试登录,过滤出成功与失败的尝试。
记录所有尝试登录失败的用户名与主机,如果超过阈值,则记录主机。
保持对每个登录失败用户的跟踪,保持对每个可疑的登录进行跟踪(虽登录成功,
但存在很多次失败记录),将可疑地址的主机加入到etc/hosts.deny文件中。
下载安装:
# 下载
wget http://jaist.dl.sourceforge.net/project/denyhosts/denyhosts/2.6/DenyHosts-2.6.tar.gz
# 解压
tar -zxvf DenyHosts-2.6.tar.gz -C /usr/local/bin
# 进入解压文件夹
cd /usr/local/bin/DenyHosts-2.6
# 安装Python2
yum install python2 -y
# 编译安装setup.py
python2 setup.py install
cd /usr/share/denyhosts/
# 配置文件
cp denyhosts.cfg-dist denyhosts.cfg
# 启动文件
cp daemon-control-dist daemon-control
# 添加root权限
chown root daemon-control
# 修改为可执行文件
chmod 700 daemon-control
# 接着就可以直接启动
./daemon-control start
# 注:如启动报错/usr/bin/env: python: No such file or directory
# 可通过下述命令设置系统默认的Python版本
alternatives --set python /usr/bin/python2
# 还可以设置为开机自启动
cd /etc/rc.d/init.d/
ln -s /usr/share/denyhosts/daemon-control denyhosts
chkconfig --add denyhosts
chkconfig denyhosts on
chkconfig --list denyhosts
部分配置文件内容说明 (vim /usr/share/denyhosts/denyhosts.cfg):
Tips:w代表周,d代表天,h代表小时,s代表秒,m代表分钟
| 配置 | 描述 |
|---|---|
| SECURE_LOG = /var/log/secure | ssh日志文件 |
| HOSTS_DENY = /etc/hosts.deny | 禁止访问主机IP文件 |
| PURGE_DENY = 4w | 过多久后清除已阻止IP |
| BLOCK_SERVICE = sshd | denyhosts要阻止的服务名 |
| DENY_THRESHOLD_INVALID = 3 | 允许无效用户登录失败的次数 |
| DENY_THRESHOLD_VALID = 10 | 允许普通用户登录失败的次数 |
| DENY_THRESHOLD_ROOT = 6 | 允许ROOT用户登录失败的次数 |
| PURGE_THRESHOLD = | 某个IP最多被解封几次,永久封禁 |
以后查看host.deny文件就可以找到攻击ip的记录了:
cat /etc/hosts.deny
cat /etc/hosts.deny | wc -l
2333,立马就有981条记录了:
一个建议:添加信任IP,把自己常用的IP加到 /etc/hosts.allow 文件中
sshd: xxx.xxx.*.*: allow
以防自己哪天手贱,多次输错密码,访问不了服务器~
待补充...
参考文献: