web服务器挂掉了,原因不明,要好好查查了,竟然发现是ssh的问题。
查看nginx的日志,在/var/log/nginx中,没有发现任何出错信息。
也可能是系统内存超了,被OpenVZ内核KILL了吧?
查了一下,果然发现:
uid resource held maxheld barrier limit failcnt
3004536: kmemsize 3626521 4652581 51200000 51200000 0
lockedpages 0 0 2048 2048 0
privvmpages 34041 131231 131200 262200 3
shmpages 1281 1297 128000 128000 0
私有虚拟页面privvmpages的数值超了,有3次失败请求。一个页面4KB,所以这个VPS的内存是512M.
我在这个VPS上只开启了nginx,vsftpd,mysqld,php-cgi,xxfpm等服务,不可能占用那么多内存吧。
php的进程数量是用自己写的xxfpm限制死了,只能有3个进程。这些所有的服务一共才占用100多MB内存,怎么可能超了512M呢?
而nginx占用的内存真的很小呀,
复制代码 代码示例:
root 22333 0.0 0.1 4988 716 ? Ss Apr29 0:00 nginx: master process /usr/sbin/nginx
www-data 22334 0.0 0.3 5524 1740 ? S Apr29 0:00 nginx: worker process
再次查看/var/log下的日志文件,发现auth.log文件体积很大,难道枚举root密码了。
因为sshd会给每个连接fork一个进程,所以当被大量攻击时,ssh的进程会变得很多。
...
Apr 29 11:39:02 293621 CRON[21809]: pam_unix(cron:session): session clo
sed for user root
Apr 29 12:09:01 293621 CRON[21843]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 29 12:09:01 293621 CRON[21843]: pam_unix(cron:session): session closed for user root
Apr 29 12:25:01 293621 CRON[21861]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 29 12:25:01 293621 CRON[21861]: pam_unix(cron:session): session closed for user root
Apr 29 12:28:58 293621 sshd[21867]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=208.115.207.253 user=root
Apr 29 12:28:58 293621 sshd[21866]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=208.115.207.253 user=root
Apr 29 12:29:01 293621 sshd[21867]: Failed password for root from 208.115.207.253 port 58931 ssh2
Apr 29 12:29:01 293621 sshd[21866]: Failed password for root from 208.115.207.253 port 56639 ssh2
Apr 29 12:39:01 293621 CRON[21879]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 29 12:39:01 293621 CRON[21879]: pam_unix(cron:session): session closed for user root
Apr 29 13:09:01 293621 CRON[21913]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 29 13:09:01 293621 CRON[21913]: pam_unix(cron:session): session closed for user root
Apr 29 13:25:01 293621 CRON[21931]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 29 13:25:01 293621 CRON[21931]: pam_unix(cron:session): session closed for user root
Apr 29 13:39:01 293621 CRON[21947]: pam_unix(cron:session): session opened for user root
...
对付这种攻击,可以限制IP、用户连接数,也可以取消root账户密码登录,采用证书认证。
之前脚本学堂,发过一篇文章:免口令登录远程SSH服务,就是使用证书登录的。
个人觉得,最有效的方法,还是使用iptables防火墙,在防火墙里设置IP白名单。
即避免了产生大量的流量,也不会产生sshd的连接进程。
在iptables中,添加两个常用的IP段,其他网段的数据包都DROP了,而不是REJECT(REJECT还要发送ICMP回应包给连接方)。
复制代码 代码示例:
# iptables -A INPUT -p tcp --dport 22 -s 120.0.0.0/8 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -s 183.0.0.0/8 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j DROP
测试:
在另外一个机子连接这个VPS,数据包被成功DROP了。
复制代码 代码示例:
root@293621:~# iptables -vL
Chain INPUT (policy ACCEPT 36 packets, 6257 bytes)
pkts bytes target prot opt in out source destination
222 16280 ACCEPT tcp -- any any 120.0.0.0/8 anywhere tcp dpt:ssh
0 0 ACCEPT tcp -- any any 183.0.0.0/8 anywhere tcp dpt:ssh
4 240 DROP tcp -- any any anywhere anywhere tcp dpt:ssh
又一次体会到iptables的威力,看来这块的内容,得找个时间好好加强下,好用啊。