在使用腾讯云或者阿里云时,每次登录都会看到成千上万次的SSH登录失败提示;
由于我们的服务器是暴露在公网IP之下的,每天都会被恶意扫描,本文分析了这些恶意扫描,并尽可能给出解决方案;
对抗SSH恶意访问
几乎每次登录的时候都能看到SSH的提示:
1 | Last failed login: Tue Dec 8 10:44:59 CST 2020 from 54.38.188.231 on ssh:notty |
最近偶尔在V2EX上看到了一些关于这个的帖子:
除了选择云厂商提供的收费防护服务之外,我们这些口袋不富裕的人有什么简单的解决方案呢?
配置SSH
更改SSH配置可以:
- 更换SSH端口;
- 安装fail2ban:使用 fail2ban 去屏蔽多次尝试密码的 IP;
- 禁止root登录;
- 使用密码加 Google Authenticator 2步验证进行登录;
- 禁止使用密码登录:只使用密钥登录;
下面一一来讲述:
① 更换SSH端口
修改ssh端口需要修改ssh配置、修改firewall配置、修改SElinux配置三个文件;
以下均是使用root权限执行;
1.修改/etc/ssh/sshd_config文件
使用vi编辑配置文件:
1 | vi /etc/ssh/sshd_config |
进入该文件,找到Port 22这一行,然后在下面添加一行:如Port 43作为新的端口;
注意:在确定可以使用新端口登录前,不要注释
Port 22这一行,以免无法登录;
2.修改firewall配置
1 | # firewall添加你选择的ssh端口,--permanent是保存设置,否则下次重启后不生效 |
将上面的{port}改为你对应的端口即可;
3.修改SELinux配置
这一步有的云服务器可能是关闭SELinux的,就不需要修改;
但是默认应该是打开了SELinux的,因此推荐修改;
1 | # 查看当前SELinux允许的ssh端口 |
如果显示semanage command not found,则:
1 | yum provides semanage # 或 yum whatprovides semanage |
若未开启,则vi /etc/selinux/config,将SELINUX=disabled修改为SELINUX=enforcing,需要重启;
1 | semanage port -a -t ssh_port_t -p tcp {port} # 添加ssh端口 |
4.重启服务并测试
1 | systemctl restart sshd |
重启后使用新端口进行ssh登录,测试是否添加成功;
1 | ssh usrname@server -p {port} # 使用-p指定端口 |
登录成功后vi /etc/ssh/sshd_config将Port 22这一行注释,并继续重启服务以生效;
② 使用fail2ban去屏蔽多次尝试密码的IP
修改默认ssh端口后已经可以防御很多只扫描特定端口的脚本,但是还是有被密码爆破的风险,因此我们安装fail2ban来屏蔽多次尝试密码的坏人;
1 | yum -y install epel-release # CentOS内置源并未包含fail2ban,需要先安装epel源 |
vi /etc/fail2ban/jail.local来新建fail2ban的配置,复制以下配置作为默认规则:
1 | [DEFAULT] |
上面的配置为十分钟内,如果连续错误超过5次,就ban掉这个IP;
输入systemctl start fail2ban启动fail2ban;
fail2ban-client status sshd可以显示fail2ban的状态,查看是否有被攻击的记录;
③ 禁止root用户直接登录
前面由于要修改、安装各种服务,因此使用root账户比较方便;
但在VPS的实际使用中,首先我们要避免被坏人攻陷,直接root登录;其次我们要避免使用root用户执行危险的操作,发生意外,所以我们禁止root用户直接登录,新建一个拥有sudo权限的用户,平时使用其来登录和执行操作,减低风险;
1 | useradd newone # 新建名为newone的用户 |
注意!!!下面这步非常重要,否则新用户可能无法登录。
输入
vi /etc/ssh/sshd_config,使用AllowUsers newone添加可以ssh登录的用户;
systemctl restart sshd重启ssh服务;
修改上一步后,保留一个终端窗口,测试新用户是否能成功登录,如果能成功登录,则禁用root用户登录;
vi /etc/ssh/sshd_config修改其中PermitRootLogin yes为PermitRootLogin no。systemctl restart sshd重启ssh服务;
此时root账户已经无法登录;
④ 使用密码加 Google Authenticator 2步验证进行登录
比较安全的SSH登录方式,一种是禁止密码且只允许密钥登录,只要保证密钥的安全,就能保证登录的安全;而另外一种2步验证的方法了;
这里我们会用到Google Authentication,其实很多网站/App已经运用到2步验证了;
1.安装Google Authenticator
1 | yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm |
切换到要使用Google Authenticator的用户,然后输入google-authenticator,屏幕会显示一个超大的二维码,你需要使用支持Google Authenticator的软件,扫描该二维码或者输入“secret key”以生成动态的验证码;
2.修改配置
修改pam配置文件:vi /etc/pam.d/sshd;
在首行加入auth required pam_google_authenticator.so,这样子在输入密码登录之前,会先要求输入Google Authentication的验证码,如果是希望反过来,则将这行代码写入到pam配置文件的最后则可;
修改ssh配置文件:vi /etc/ssh/sshd_config;
将ChallengeResponseAuthentication no修改为ChallengeResponseAuthentication yes;
检查系统时间:
1 | #查看下服务器时间 |
最后,在保留一个活动的终端窗口的前提下,重启ssh服务,systemctl restart sshd,然后重新登录该用户测试是否成功(登录失败也有可能是因为终端软件的问题,比如,尝试更换软件);
⑤ 使用有密码的SSH密钥进行登录
其实,使用密钥进行登录已经算非常安全了,但是为了更加安全,我们还可以给密钥文件添加密码;
建议在自己的常用工作电脑上使用密钥登录服务器,而在其他电脑上则保留使用密码登录的方式;
使用密钥登录,我们会生成非对称加密的一对密钥,分别称之为“私钥”和“公钥”;
如果公钥加密的信息只有私钥才能解开,那么只要私钥不泄露,通信就是安全的;
不清楚非对称加密是什么?看看阮一峰老师的:
1.生成密钥对
在终端输入ssh-keygen来生成密钥,默认会保存在~/.ssh/id_rsa,可以自定义该文件的地址和名称,例如~/.ssh/remote_server;
然后会询问是否添加密钥,默认是不设置密码的,这里可以设定密码;
然后会生成密钥文件,其中你指定的路径就是私钥文件,而.pub结尾的就是公钥文件;
然后在本地的~/.ssh/config中添加以下代码,用于指定密钥:
1 | Host RemoteServer # 随意自己起,但是要用到 |
2.将公钥存放到目标服务器上
打开目标服务器的目标用户的~/.ssh路径,然后将.ssh/remote_server.pub文件的内容复制到~/.ssh/authorized_keys里,如果没有~/.ssh文件夹则参考以下代码,先localhost登录一次;
1 | $ ssh localhost # 输入密码登录 |
登录过后就会生成~/.ssh文件夹了;
注意
~/.ssh目录权限必须为700,~/.ssh/authorized_keys权限必须为600;
3.修改配置文件
输入vi /etc/ssh/sshd_config,将该文件添加以下3行,如果已有则改成一样的:
1 | RSAAuthentication yes |
然后systemctl restart sshd重启ssh服务;
在本地使用类似ssh newone@RemoteServer的命令进行登录,如果登录成功则说明设置生效了;
配置云服务器白名单
在云厂商后台管理中配置白名单,只允许自己的IP登录,也可以解决问题;