本文介绍下,在linux中通过使用iptables防火墙,禁止某些IP或IP段访问ssh服务的方法,有需要的朋友,参考下吧。



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 closed 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账户密码登录,采用证书认证。

个人觉得,最有效的方法,还是使用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的威力,看来这块的内容,得找个时间好好加强下,好用啊。