Linux VPS 安全策略记录

现在网络安全闹得沸沸扬扬,而且前两天发现之前部门的服务器被入侵而后用来攻击别人。所以花了点儿时间对我的 VPS 安全做了些研究。下面是配置记录。

嗯,因为 Linux 发行版比较多,不同的发行版很多设置不太一样,有必要先说说我的 Linode VPS 的环境:CentOS + LAMP + phpMyAdmin

使用强密码

不管采取了多少其它的安全措施,如果使用的密码不够强健,恐怕一切都是白搭,所以首先需要设定足够强健的密码。包括系统用户登录密码,特别是 root 帐户的;还有 MySQL 用户的密码;以及其它一切可以获取读取系统任何内容的权限的密码。总之,一切密码好了。同时还要注意,不要使用相同的密码

不要怕记不住。编写一个强健的密码,然后在自己的日记本上写下来,同时在电脑上找个地方保存下来(Windows 7 的便笺就是个不错的选择)。需要通过网页登录,或者使用 SSH 登录的时候,只需要复制粘贴就可以了(在 Putty 的窗口单击鼠标右键就可以完成粘贴)。

对VPS上所有的密码都是用强密码,并且要互不相关,避免泄露一个密码后其它密码随之泄露。

清理不需要的系统用户和组

虽然 Linode VPS 提供的 CentOS 系统已经优化得挺不错的了,可还是有不少系统内建用户和组是不需要的。清理掉这些用户和组也有助于系统安全。当然,安全起见,还是需要先备份。

CentOS 中用户信息存储在 /etc/passwd 文件中。下面的命令可以显示出所有用户。

cat /etc/passwd

使用 root 帐户运行下面的命令来清理不需要的用户和组:

cp /etc/passwd /etc/passwd.sav
cp /etc/group /etc/group.sav
for a in adm lp sync news uucp operator games gopher mailnull nscd rpc;
do /usr/sbin/userdel $a -f; done
for a in lp news uucp games gopher users floopy nscd rpc rpcuser nfsnobody;
do /usr/sbin/groupdel $a -f; done

清理用户和组的方法参考自 128M VPS 上优化 CentOS 5 一文。用户和组完全是按照该文来清理的。也许还有别的用户和组也可以禁用,留待以后测试。

加强 SSH 安全

这一部分主要通过修改 SSH 的配置文件来实现:

vim /etc/ssh/sshd_config

重点是下面 3 项。所有几个关键配置都列在这一节的后面,以供参考。

  1. 禁止 root 帐户远程登录Linux 系统里最知名的用户名就是 root 了,也就最容易遭到暴力破解攻击。禁止 root 用户通过 SSH 登录就可以避免这种悲剧。另外增加一个自己用的用户名,可以稍微复杂一点,让别人不容易猜。这样可以增加一些难度。不是跟你有仇的人,恐怕就不会花力气来猜你的用户名了。于是通过 SSH 来攻击也就不存在了。
    PermitRootLogin no
  2. 限定可以登录 SSH 的用户名除了 root 帐户之外,Linux 中还有其它一些默认的帐户,有些还不能轻易删除。所以只是禁止 root 帐户 SSH 登录还不行,最好限定可以登录 SSH 的用户名。
  3. 更改 SSH 端口默认的 SSH 端口是 22。现在网上有无数的机器在扫描 22 端口,寻找攻击机会。在我的 VPS 刚上线的那几天里,收到了大量针对 22 端口的扫描,也就是暴利破解 SSH 密码。攻击的用户名主要是 root,也有其它一些常见的简单用户名,如 test123 之类的。上面提到的一些默认帐户也在攻击者的列表中。将 SSH 端口改为一个不常见的,例如
    Port 1234
  4. 也可以使用证书来登录 SSH,减少密码使用的次数。这里先不讨论了。还没有配置成功。
  5. 配置完成后重起 SSH 服务使之生效:
    service sshd restart

参考资料:

  1. CentOS Wiki:Securing OpenSSH
  2. Preventing brute force attacks using iptables recent matching

附:SSH 配置文件样本(一些用 # 注释掉的行没有列上)

Port 1234

Protocol 2

SyslogFacility AUTHPRIV

PermitRootLogin no
AllowUsers user1 user2

/etc/ssh/ssh_known_hosts

PermitEmptyPasswords no
PasswordAuthentication yes

ChallengeResponseAuthentication no

GSSAPIAuthentication yes
GSSAPICleanupCredentials yes

UsePAM no

# Accept locale-related environment variables

AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

X11Forwarding no

# override default of no subsystems
Subsystem   sftp /usr/libexec/openssh/sftp-server

UseDNS no
Banner /etc/issue

使用 iptables 对连接进行限制

因为 iptables 中的规则对顺序很敏感,下面先提几个方面,然后给出全部配置文件内容(以 # 注释来进行说明)。

  1. 限制 SSH 端口的连接错误次数(参考:Preventing brute force attacks using iptables recent matching);
  2. 限制单个 IP 对 80 端口的并发连接数;
  3. 限制 80 端口以及其它如邮件、SMTP等端口的连接速率(参考:Prevent DOS with iptables);
  4. 其它不符合标准的一律 DROP 掉。

我发现编辑 iptables 条目实际上不需要使用如下的命令行慢慢来操作,

iptables -A INPUT .........

而是可以将 iptables 文件下载下来,使用记事本之类的编辑器编辑(当然格式还是得参照已有的规则)来编写,然后再上传过去覆盖掉原来的,再使用下面的命令行来加载新规则即可,

service iptables restart

下面是我目前用的iptables 文件:

# Generated by iptables-save v1.4.7 on Fri Mar  9 23:08:51 2012
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [1301:2201856]
# 下面两个 chain 是用来记录 ssh 尝试登录次数的
:blacklist - [0:0]
:sshscan - [0:0]
# 2012.03.16 新增一个 CHAIN
:syn_flood - [0:0]

# rule 1 允许所有本机发出的通讯
-A INPUT -s 127.0.0.1/32 -j ACCEPT
# rule 2 限制 RELATED,ESTABLISHED 一类的连接速率为每秒钟 50 个,峰值 50;超过限制的则不接受
# 似乎不需要这么做,清除这一部分 2012.03.16
#-A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 50/sec --limit-burst 50 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# 跳转到 syn_flood CHAIN 来判断是否有“洪水”攻击,2012.03.16
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood 
# 有限接受 icmp 包,2012.03.16
-A INPUT -p icmp -m limit --limit 10/sec -j ACCEPT 
-A INPUT -p icmp -m limit --limit 10/sec -j LOG --log-prefix "PING-DROP: " --log-level 6 
# rule 3 限制 80 端口新建连接的速度为 50 个每分钟,峰值 200;超过限制的不接受
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -m limit --limit 50/min --limit-burst 200 -j ACCEPT
# 邮件服务基本上全部由 Google 企业邮局完成,删除下面有关 465 和 25 端口的条目,禁用这 2 个端口 2012.03.16
# rule 4 类似 rule 3 来限制 465 端口 #-A INPUT -p tcp -m tcp --dport 465 -m state --state NEW -m limit --limit 30/min --limit-burst 100 -j ACCEPT # rule 5 类似 rule 3 来限制 25 端口 #-A INPUT -p tcp -m tcp --dport 25 -m state --state NEW -m limit --limit 30/min --limit-burst 100 -j ACCEPT
# rule 6 类似 rule 3 来限制 5678 端口(这是我特殊使用的一个端口)
-A INPUT -p tcp -m tcp --dport 5678 -m state --state NEW -m limit --limit 10/min --limit-burst 20 -j ACCEPT
# rule 7 限制 80 端口并发连接数不超过 20,否则发送 tcp reset 来拒绝连接
-A INPUT -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 20 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
# rule 8,9 开放 53 端口(DNS 服务) # 似乎不开放这个端口也没有问题,禁用掉 2012.03.16 #-A INPUT -p tcp -m tcp --sport 53 -j ACCEPT #-A INPUT -p udp -m udp --sport 53 -j ACCEPT
# rule 10 配合前面提到的两个 chain 来限制 ssh 新建连接,并对超过尝试次数的连接封锁指定时间
-A INPUT -p tcp -m tcp --dport 1234 -m state --state NEW -j sshscan
# rule 11 丢弃其它不满足前述规则的连接
-A INPUT -j DROP

# 以下是前面提到的 2 个检查 ssh 连接的 chain,blacklist 和 sshscan
-A blacklist -m recent --set --name blacklist --rsource
-A blacklist -j DROP
-A sshscan -m recent --update --seconds 600 --hitcount 1 --name blacklist --rsource -j DROP
-A sshscan -m recent --set --name counter1 --rsource
-A sshscan -m recent --set --name counter2 --rsource
-A sshscan -m recent --set --name counter3 --rsource
-A sshscan -m recent --update --seconds 20 --hitcount 3 --name counter1 --rsource -j blacklist
-A sshscan -m recent --update --seconds 200 --hitcount 15 --name counter2 --rsource -j blacklist
-A sshscan -m recent --update --seconds 2000 --hitcount 20 --name counter3 --rsource -j blacklist
-A sshscan -j ACCEPT
# 判断 syn_flood 攻击与否,不是则 RETURN(返回),否则 DROP 3012.03.16
-A syn_flood -m limit --limit 10/sec -j RETURN 
-A syn_flood -j DROP 

COMMIT
# Completed on Fri Mar  9 23:08:51 2012

另外,也有在 iptables 中限制 ICMP 连接的,我是统统丢弃了。需要的话请参考:

http://serverfault.com/questions/287998/is-my-linux-firewall-secure

其它参考资料:

  1. ShoreWall Iptables Firewall
  2. Using iptables to Block Brute Force Attacks
  3. 25 Most Frequently Used Linux IPTables Rules Examples
  4. Arno’s iptables firewall
  5. iptables 官方网站
  6. Iptables 指南 1.1.19
  7. Using iptables to Enhance Security of your VPS
  8. iptables 语法重点
  9. iptables防火墙的基本应用教程

修订记录

2012.03.16

  1. 增加清理不需要的系统用户和组一节。
  2. 修改部分 iptables 设置(未修改本文中 rule 编号):
    1. 因为邮件服务仅仅使用其发出功能,不接收,故而不开放 465 和 25 两个端口;
    2. 53 端口禁用也不影响 VPS 查询 DNS,禁用;
    3. 增加判断 SYN flood 攻击;
    4. 增加对 ICMP 的有限接受(现在可以 ping cnzhx.net 了)。

©

本文发表于水景一页。永久链接:<http://cnzhx.net/blog/secure-my-vps/>。转载请保留此信息及相应链接。

14 条关于 “Linux VPS 安全策略记录” 的评论

  1. 兄弟,你的这个iptables看起来好有深度呀。又限制速率,又限制连接数的,同时还直接在iptables上,做起了SSH限制,相当伟大。

    不过再我看来,你的这个iptables规则有点绕,呵呵,从前面三句看出来,你的iptables默认规则都是accept,而在你写的规则里头又是只有你想开放的那些,他人可以连接,其余的都过滤掉。

    还有每条规则为何都要设定一个状态呢?不是很理解,还希望兄弟指点下。还有就是规则里头关于output的80和443端口这两条,如果去掉,真的就不能上了吗?

    • 嗯,经过你的提醒,我看了看,OUTPUT 里的那两条的确不需要,因为 INPUT 中的第一条已经保证可以访问外网了。
      设定状态是为了针对所设定的状态啊。比如对 RELATED 和 ESTABLISHED 限连接速率那一条,如果也应用在 NEW 上面的话,那就太宽松了,跟没设定规则没什么两样。
      另外,我的 INPUT chain 里头最后是 DROP 所有的。

      • 能理解点了。但对于为何要对速率做这样一个设定,是基于怎样一个场景,现在还不是很清楚,日后也要好好考虑下这问题。

  2. 引用通告: Linode VPS 上 CentOS 6 安装 LAMP + phpMyAdmin 记录 | 水景一页

  3. 引用通告: 服务器遭到攻击,不知道是否误伤 | 水景一页

  4. 用了你iptables规则,发现直接卡在commit上。service iptables restart
    Flushing firewall rules: [ OK ]
    Setting chains to policy ACCEPT: security raw nat mangle fi[FAILED]
    Unloading iptables modules: [ OK ]
    Applying iptables firewall rules: iptables-restore: line 52 failed
    [FAILED]
    不知道你的iptables是如何设置的。

  5. 一番修改以后,现在重启iptables问题出现在commit上。
    Flushing firewall rules: [ OK ]
    Setting chains to policy ACCEPT: security raw nat mangle fi[ OK ]
    Unloading iptables modules: [ OK ]
    Applying iptables firewall rules: iptables-restore v1.3.5: no command specified
    Error occurred at line: 52
    Try `iptables-restore -h’ or ‘iptables-restore –help’ for more information.
    [FAILED]
    无奈中。。。

    • 我的这个规则只是个样例,一般情况下你需要结合自己的实际情况权衡,也许还要做一点点调整。但是如果直接全部使用应该是可用的。
      既然提示说第 52 行有问题,你的 52 行是什么?

  6. 引用通告: 在 Redhat / CentOS Linux 中安装 iptables 防火墙 | 水景一页

  7. 引用通告: CentOS / Redhat 上的 Iptables 防火墙配置简介 | 水景一页

  8. 引用通告: 博客搬迁 Linode VPS 配置笔记

  9. 引用通告: CentOS / RHEL IPv6 ip6tables 防火墙配置简介 | 水景一页

  10. 引用通告: CentOS 7 / RHEL 7 上安装 LAMP + phpMyAdmin | 水景一页

时间过去太久,评论已关闭。
如果您有话要说,请到讨论区留言并给出此文章链接。
谢谢您的理解 :-)