用iptables让SSH服务对陌生人说不

今晚老师跟我说服务器的Web挂了,但是FTP可以用。我登录了这个OpenVZ的VPS,发现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的进程会变得很多!至于sshd自身有没有对这个数量进行限制,我不是很清楚!


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账户密码登录,采用证书认证的,之前写过一篇文章免口令登录远程SSH服务就是使用证书登录的。但是我觉得最有效的方法就是在防火墙里设置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

 

So, 希望nginx不会再崩了 🙂

用iptables让SSH服务对陌生人说不》有35个想法

    1. Xiaoxia 文章作者

      是体积很小的debian。现在不是很担心密码会那么容易被别人破解到,而是怕ssh进程太多了,让VPS挂了 🙂

      回复
        1. Xiaoxia 文章作者

          你已经安装tornado了没?
          你是指如何跑hello world吗?
          装好之后,按照官网的示例,大概20行代码吧。写到一个py文件里。然后运行,用浏览器访问即可!

          学习tornado可以看tornado的代码,原因很简单,它的代码很少。。。

          回复
          1. Dianso

            看了下文档,原来这个本身就有websever功能,我原来的意思是怎么和nginx整合。

            发现你的那个http://gallery.xiaoxia.org/打不开了

            回复
            1. Xiaoxia 文章作者

              可以试试 http://gallery.xiaoxia.org:8888/
              这个apache2的反向代理没有nginx做的那么好。

              nginx可以用来做服务器前端,然后使用反向代理访问torando的服务器。
              因为torndaoweb本身不是使用多线程的,所以如果你不是用异步又不想因为用户一个请求阻塞占用太长时间,你就可以开多多几个tornadoweb的进程,不同可以使用不同端口,这样就可以在nginx的upstream里设置调度策略了。
              像我现在用tornado做的项目,一般开一个主的和一个备份的。有时候更新网站的时候,就会关掉主的,备份那个进程会自动被使用。避免网站服务中断。。

              回复
  1. Pingback引用通告: 写了个Python脚本监控nginx进程 « Xiaoxia[PG]

    1. Xiaoxia 文章作者

      恩,我之前也这么做过,但是很不方便,有些东西很难兼容。
      不如SVN的时候,就不知道怎么设置ssh的端口了。。。

      回复
  2. halfbloodrock

    还有种方法,就是用pam模块限制登录次数

    vi /etc/pam.d/sshd

    設定

    auth required pam_tally.so deny=3 unlock_time=120

    # deny=3 代表可接受的錯誤嘗試次數

    # unlock_time=120 代表超過可接受次數後,該帳號要鎖定多久時間,以秒為單位

    回复
        1. Xiaoxia 文章作者

          有攻击者有很多IP,轮流攻击,还是能够让你打开多个进程来验证吧!

          如果不是针对ip限制的,难道是针对用户名限制的?

          回复
  3. 艳文

    我的vp也是512m的。。之前时不时的会出现502错误,重启lnmp之后又好了。。。。。直到前几天用着用着。。无端端整个系统stop了。。。。害得我还得到控制面板重新启动vps。。。真郁闷。。。

    回复
  4. Pingback引用通告: 写了个Python脚本监控nginx进程

    1. Xiaoxia 文章作者

      没有用过,有待了解!!!
      如果容易配置又不给系统资源带来额外开销,还是挺不错的

      回复
    1. Xiaoxia 文章作者

      这工具需要额外安装吗?还要安装内核模块吗?
      iptables在一般系统上都有自带,嵌入式上也有,路由也有,还是挺方便的。

      回复
  5. willy

    估计绝大多数只是被机器人扫描了默认的ssh端口,然后尝试暴力猜解。
    其实,只要没被盯上,把默认的ssh端口改掉就可以让那些机器人嗝屁了。。

    回复
  6. 81难

    修改SSH默认的端口,然后再修改root用户名,绝对安全。
    至于如何修改root用户名,可以直接修改/etc/passwd和/etc/shadow两个文件,将里面的“root”直接替换为admin或任何一个名字。

    回复
      1. ET

        会有可能导致登录不进去,所以你觉得两者结合会不会更好呢?

        仅仅白名单的话,因为白名单的范围很大,如果坏人正好在白名单的话,还是会有可能出现大量sshd进程,万一又把重要进程给挤死了那就悲剧了。183.0.0.0/8貌似在大学城这边的电信都是在这个网段。

        sshd_config MaxStartups的默认值是10:30:60。

        回复

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据