Total Pageviews

Sunday 29 April 2012

装iptables和fail2ban提高安全性

1. 安装iptables

1)apt-get install iptables
因为iptable不需要启动脚本,规则一旦设置,立即生效,关机后有自动清零。所以远程登录时,更改设置要小心,切勿将默认值全都改为Drop,以免丢失SSH连接。编写以下脚本可以便于修改,调试。
2)然后可以在用户目录下编写如下脚本 ~/iptables-init.sh (假设服务器对外网卡的设备号是eth0

iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT #保证已经打开的Session都有效,对于远程调试登录的情况下起保护作用,因为iptables的改动是实时生效的
iptables -A INPUT -i lo -j ACCEPT #打开Loopback, 及localhost, 127.0.0.1
iptables -A INPUT -p tcp -i eth0 –dport ssh -j ACCEPT #允许SSH远程登录
iptables -A INPUT -p tcp -i eth0 –dport 80 -j ACCEPT #允许外界访问www服务器
iptables -A INPUT -p tcp -i eth0 –dport 21 -j ACCEPT #允许外界访问ftp服务器
iptables -A INPUT -j DROP
iptables-save > /etc/iptables.rules
然后赋予脚本执行权限 chmod +x ./iptables-init.sh
运行脚本 ./iptables-init.sh
3)设置网卡启动时加载防火墙规则 (这步要很小心,否则网卡加载失败,系统就无法登录了)
最好先用
iptables-restore </etc/iptables.rules
iptables -L -v 仔细检查下数据,必要时,重新开一个putty窗口,验证以下是否还能登录。
然后修改脚本/etc/network/interfaces,使系统能自动应用这些规则,最后一行就是要添加的,加载文件应该和上面脚本中保存规则的文件名一致,并且要用绝对路径。
auto eth0
iface eth0 inet dhcp
pre-up iptables-restore < /etc/iptables.rules
注意:之所以在加载网卡设备后,刷新iptables列表,
而不是象有些地方建议的在/etc/rc.local或是其他地方放置iptables-init这样的脚本,是因为自网卡启动后到系统执行rc.local仍然有一段时间,会使防火墙无效,所以以上的方法是最好的。
本来为了是FTP能够支持PASV模式,方便防火墙后面的客户端连接服务器,可以在何时的启动脚本里执行
modprobe ip_conntrack_ftp
但是Linnode上的Ubuntu内核编译时,并没有带上这个模块,所以只得放弃,好在PASV模式的安全性也不如Active模式(Port模式)
参考文章
1. Ubuntu 服务器版 Iptables 基本设置指南

2. 安装fail2ban

1) apt-get install fail2ban
2) 查看/etc/fail2ban/jail.conf,核对一下logpath = /var/log/auth.log或/var/log/vsftpd.log的路径是否正确。然后编辑/etc/fail2ban /jail.local, 打开以下开关: (这样可以避免升级时,开关被关闭)
[DEFAULT]
bantime=7200 #至少封2小时IP
[ssh]
enabled = true
filter = sshd
[vsftpd]
enabled = true
filter = vsftpd
查看/etc/vsftpd.conf, 确保以下配置正确,如果修改了,需要重启ftp服务,/etc/init.d/vsftpd restart。fail2ban虽然也可以和Wu-FTP配合,然考虑到思维一致性,我们上边只配了vsftpd的过滤,只能识别vsftpd的日志, 所以vsftpd的日志也要采取其自身的格式:
xferlog_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
确保以下两行被注释掉,否则log的格式是wu-ftpd 不能被fail2ban识别!!
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
然后/etc/init.d/fail2ban start 启动服务就可以了。
fail2ban每次都会在iptables的INPUT Chain中添加一条记录,专门指向fail2ban的一条Chain, 用来存放封禁ip的记录。 所以/etc/iptables.rules只要独自管理静态规则就可以了

3. FTP客户端的设置

FTP的客户端要复杂一些,因为PORT模式下需要客户端来告诉FTP服务器自己的公网IP,如果用户自己也在防火墙后面的局域网里,一般的客户端 是做不到的。很有可能会告诉FTP服务器,Port 192.168.0.x 这样的指令。结果得到550 illegal port command的信息。但是FileZilla最新版可以选择利用http://ip.filezilla-project.org/ip.php获知 IP,这个问题就迎刃而解了

4. 查看被封禁的IP

fail2ban-client status ssh -iptables
fail2ban-client status vsftpd  -iptables
-------------------------------------------------

服务器暴力入侵防护


找了个小软件fail2ban来防暴力入侵.可以防护的东西可多啦,如下.

fail2ban的安装
Centos5上面安装很容易.yum安装就可以了,当然前提是安装了我讲的那个Centos的扩展包.
1
$ yum install fail2ban
也可以到他们的官方网站看看
http://www.fail2ban.org/wiki/index.php/Main_Page
fail2ban 可以阻挡的暴力入侵服务很多如apache,postfix,exim,named,qmail,sasl,ssh,webmin,wuftpd,大多了.
在 filter.d 目录可以看到所有的部分
1
$ ls -l /etc/fail2ban/filter.d/
-rw-r–r– 1 root root  704 Feb 28  2008 apache-auth.conf
-rw-r–r– 1 root root 2396 Mar  6  2008 apache-badbots.conf
-rw-r–r– 1 root root  650 Mar  5  2008 apache-noscript.conf
-rw-r–r– 1 root root  444 Mar  6  2008 apache-overflows.conf
-rw-r–r– 1 root root 1036 Mar  1  2008 common.conf
-rw-r–r– 1 root root  609 Feb 28  2008 courierlogin.conf
-rw-r–r– 1 root root  584 Feb 28  2008 couriersmtp.conf
-rw-r–r– 1 root root  606 Feb 28  2008 exim.conf
-rw-r–r– 1 root root  447 May 22  2008 gssftpd.conf
-rw-r–r– 1 root root 1014 May 22  2008 named-refused.conf
-rw-r–r– 1 root root  870 May 22  2008 pam-generic.conf
-rw-r–r– 1 root root  584 Feb 28  2008 postfix.conf
-rw-r–r– 1 root root  871 Mar 11  2008 proftpd.conf
-rw-r–r– 1 root root  794 Feb 28  2008 pure-ftpd.conf
-rw-r–r– 1 root root  599 Feb 28  2008 qmail.conf
-rw-r–r– 1 root root  643 Feb 28  2008 sasl.conf
-rw-r–r– 1 root root 1379 May 12  2008 sshd.conf
-rw-r–r– 1 root root  620 Feb 28  2008 sshd-ddos.conf
-rw-r–r– 1 root root  693 Mar  5  2008 vsftpd.conf
-rw-r–r– 1 root root  820 Feb 28  2008 webmin-auth.conf
-rw-r–r– 1 root root  437 May 22  2008 wuftpd.conf
-rw-r–r– 1 root root  841 Mar  6  2008 xinetd-fail.conf

fail2ban的配置
在fail2ban安装好后.主要的设置文件是/etc/fail2ban/jail.conf和 fail2ban.conf.fail2ban.conf.对不过我们用默认的值就好了. 好了,我们平时的设置啦,他设置太容易了,修改设定档jail可以控制上面的所有的服务.
1
$ vim /etc/fail2ban/jail.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[DEFAULT]
#全局设置
# 不列入的 IP 范围,如果有二组以上以空白做为间隔 192.168.250.0/24
ignoreip = 127.0.0.1
# 设定 IP 被封锁的时间(秒),如果值为 -1,代表永远封锁
bantime  = 600
# 设定在多少时间内达到 maxretry 的次数就封锁
findtime  = 600
# 允许尝试的次数
maxretry = 3
#分类设置
#针对sshd暴力入侵防护
[ssh-iptables]
enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
           mail-whois[name=SSH, dest=root]
logpath  = /var/log/secure
# 如果有个别的次数设定就设在这里
maxretry = 5
#针对vsftpd暴力入侵防护
[vsftpd-iptables]
enabled  = true
filter   = vsftpd
action   = iptables[name=VSFTPD, port=ftp, protocol=tcp]
           sendmail-whois[name=VSFTPD, dest=you@mail.com]
logpath  = /var/log/secure
maxretry = 3
bantime  = 1800
新的 fail2ban 默认就开启了 ssh 的防护,不用配置,直接启动就行了.
建议设置成maxretry为 3 表示3次错误就封锁,另外logpath(Centos5和Rhel5中)要改成/var/log/secure. 然后我们设置启动服务:
1
2
$ chkconfig --level 2345 fail2ban  on
$ service  fail2ban start
fail2ban测试和查看
过滤检查语法测试命令,你可以用这个命令看看哦.
1
$ fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/vsftpd.conf
安装完fail2ban后.运行iptables的命令,会看到多了如下的iptables 的规则
1
2
3
4
5
6
7
8
9
$ iptables -L -nv
Chain INPUT (policy ACCEPT 231M packets, 51G bytes)
 pkts bytes target     prot opt in     out     source               destination
   97  5294 fail2ban-VSFTPD  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:21
Chain fail2ban-VSFTPD (1 references)
 pkts bytes target     prot opt in     out     source               destination
   20   998 DROP       all  --  *      *       220.249.41.163       0.0.0.0/0
   77  4296 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0
当然,fail2ban本身还提供一个命令来查
1
2
3
4
5
6
7
8
9
10
11
$ fail2ban-client status vsftpd-iptables
Status for the jail: vsftpd-iptables
|- filter
|  |- File list:    /var/log/secure
|  |- Currently failed:    0
|  `- Total failed:    6
`- action
   |- Currently banned:    1
   |  `- IP list:    220.249.41.163
   `- Total banned:    1
注:如果重起iptables 记的一定还要重起fail2ban,不然他就不能生效,fail2ban的过滤表是在iptables 启动后再加入的.
-----------------------------------------------------------------------
Centos下fail2ban的安装


[root@localhost ~]# wget http://cdnetworks-kr-1.dl.sourceforge.net/project/fail2ban/fail2ban-stable/fail2ban-0.8.4/fail2ban-0.8.4.tar.bz2
[root@localhost ~]# tar xvjf fail2ban-0.8.4.tar.bz2
[root@localhost ~]# cd fail2ban-0.8.4
[root@localhost fail2ban-0.8.4]# ls

    ChangeLog config fail2ban-regex files README setup.py
    client COPYING fail2ban-server man server testcases
    common fail2ban-client fail2ban-testcases PKG-INFO setup.cfg TODO

[root@localhost fail2ban-0.8.4]# python setup.py install
[root@localhost fail2ban-0.8.4]# cd files
[root@localhost files]# cp ./redhat-initd /etc/init.d/fail2ban
[root@localhost files]# chkconfig --add fail2ban
[root@localhost files]# service fail2ban start
Starting fail2ban: [ OK ]
-----------------------------------

Fail2ban

从yum源安装好,然后修改一些配置.

yum -y install fail2ban

# cat /etc/fail2ban/fail2ban.conf |grep -v ^#

[Definition]

loglevel = 2

logtarget = /var/log/fail2ban.log

socket = /var/run/fail2ban/fail2ban.sock

pidfile = /var/run/fail2ban/fail2ban.pid

/etc/fail2ban/jail.conf里面有几个重点:

[DEFAULT]                                 #全局设置
ignoreip = 127.0.0.1                      #忽略的IP列表,不受设置限制(白名单)
bantime  = 600                            #屏蔽时间,单位:秒
findtime  = 600                           #这个时间段内超过规定次数会被ban掉
maxretry = 3                              #最大尝试次数
backend = auto                            #日志修改检测机制(gamin、polling和auto这三种)
 
[ssh-iptables]                            #针对各服务的检查配置,如设置bantime、findtime、maxretry和全局冲突,服务优先级大于全局设置
enabled  = true                           #是否激活此项(true/false)
filter   = sshd                           #过滤规则filter的名字,对应filter.d目录下的sshd.conf
action   = iptables[name=SSH, port=ssh, protocol=tcp]                                                                        #动作的相关参数,这里port的值等于ssh的端口号,如改过ssh端口要相应修改。
           sendmail-whois[name=SSH, dest=root, sender=fail2ban@example.com]   #触发报警的收件人
logpath  = /var/log/secure                #检测的系统的登陆日志文件

[ssh-ddos]

enabled  = true
filter   = sshd-ddos
action   = iptables[name=SSHDDOS, port=3389, protocol=tcp]
logpath  = /var/log/secure


[nginx-http-40x]
enabled = true
filter  = nginx-401  #这个是自定义的filter,对应filter.d目录下的nginx-401.conf,下面类似
action  = iptables-multiport[name=nginx-401,port="443"]
logpath = /var/log/nginx/access.log

[ss-fail]
enabled = true
filter  = ss-fail
action  = iptables-multiport[name=ss-fail,port="80,443,4869"]
logpath = /var/log/messages


[anyconnect-fail]
enabled = true
filter  = anyconnect-fail
action  = iptables-multiport[name=anyconnect-fail,port="80,443,4869"]
logpath = /var/log/messages
修改/etc/fail2ban/filter.d/sshd.conf,在规则里添加一项^%(__prefix_line)sBad protocol version identification .* from <HOST>\s*$,因为我把ssh端口改成了3389,扫描器会用错误的协议尝试访问,通过这个提示也ban掉扫描器。


#cat nginx-401.conf

[Definition]

failregex = <HOST> -.*- .*HTTP/1.* 401 .*$
 <HOST> -.*- .*HTTP/1.* 404 .*$

ignoreregex =


# cat anyconnect-fail.conf

[Definition]

failregex = worker: <host>(:\d+)? tlslib.c:372: error verifying client certificate: No certificate was found.

ignoreregex =



#cat ss-fail.conf

[Definition]

failregex =  failed to handshake with <host>$
ignoreregex =


</host></host>

全部搞定之后,service fail2ban restart,然后iptables -L -n -v看看是否生效。 6、其他配置 无论用sshd还是dropbear,改端口和禁止root登陆是必须的,新建一个普通帐号然后加入sudo里是良好的习惯。如果上网设备固定可以考虑证书登陆和禁用PAM,UseDNS no可以加快ssh登陆
/etc/sysctl.conf


# Controls IP packet forwarding
net.ipv4.ip_forward = 1

# Controls source route verification
net.ipv4.conf.default.rp_filter = 1

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0

# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1

# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1

# Disable netfilter on bridges.
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

# Controls the default maxmimum size of a mesage queue
kernel.msgmnb = 65536

# Controls the maximum size of a message, in bytes
kernel.msgmax = 65536

# Controls the maximum shared segment size, in bytes
kernel.shmmax = 4294967295

# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 268435456

#This is for shadowsocks
fs.file-max = 51200

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_max_syn_backlog = 10240
net.ipv4.tcp_max_tw_buckets = 5000


# increase TCP max buffer size settable using setsockopt()
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
# increase Linux autotuning TCP buffer limit
#net.ipv4.tcp_mem = 25600 51200 102400
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
# increase the length of the processor input queue
net.core.netdev_max_backlog = 30000
# recommended for hosts with jumbo frames enabled
net.ipv4.tcp_mtu_probing=1

net.ipv4.tcp_fastopen=3
net.ipv4.tcp_congestion_control=htcp
#net.ipv4.tcp_congestion_control = hybla

sysctl -p立即生效,这里可以分别做一个hybla和一个htcp的配置文件,放在crontab里根据时间来切换.