If you don\\\\\\\\\\\\\\\'t wanna do it, you find an EXCUSE; if you do, you\\\\\\\\\\\\\\\'ll find a WAY :-)
全部博文(235)
分类: LINUX
2011-01-17 17:46:34
关闭 IP6Tables 服务才能使用 IPTables 服务:
[root@example ~]# chkconfig ip6tables off
[root@example ~]# chkconfig iptables --level 345 on
——————————————————————————————————————————
[root@example ~]# service iptables save
[root@example ~]# service iptables restart
[root@example ~]# iptables-save > iptables.sh
[root@example ~]# iptables-restore iptables.sh
——————————————————————————————————————————
【With the sysctl application】:
The sysctl application can be used to either set variables through the command line, or to set a larger set of variables through a configuration file as previously described. sysctl may also set several variables through the command line at once if need be, and it may also be used to list all variables and their respective values.
1.1. First of all, to list all variables possible you could issue the following command:
[root@rhel5 ~]# sysctl -a →→ to list all variables
[root@rhel5 ~]# sysctl net.ipv4.tcp_sack →→ to read a specific variable
[root@rhel5 ~]# sysctl -w net.ipv4.tcp_sack=0 →→ to set a value
1.2. Reload /etc/sysctl.conf
[root@rhel5 ~]# sysctl -p →→ to load all of the settings we have in the /etc/sysctl.conf file
[root@rhel5 ~]# sysctl -p /etc/testsysctl.conf →→ load the testsysctl.conf configuration options instead of our default file
【With /proc】:
1.1. It may be a very bad idea to turn on ip_forward before we have all the firewall rules and routes up and running.
[root@rhel5 ~]# echo "1" > /proc/sys/net/ipv4/tcp_sysncookies →→ 默认值是1,开启防御SYN Flood攻击
[root@rhel5 ~]# echo "1" > /proc/sys/net/ipv4/ip_forward →→ 默认值是0,开启ip_forward
1.2.icmp_echo_ignore_all
If this is variable is turned on, you and others will be unable to ping the machine in question which is generally a bad thing. Of course, everyone has different opinions about this,
some say it is good because people will be unable to ping you and hence know you are there, some say it is bad because you want people to know you are available on the internet.
A lot of tools and applications rely upon ICMP Echo requests, some good, some bad as always.
[root@rhel5 ~]# echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all →→默认值是0,所谓的(Disable death of PING);
——————————————————————————————————————————
当packets到达防火墙,如果MAC地址符合,就会由内核里相应的驱动程序接收,然后会经过一系列操作,从而决定是发送给本地的程序,还是转发给其他机子,还是其他的什么。
1.目标是本地的包
Internet →→ 进入NIC →→ mangle packets(PREROUTING) →→ DNAT(PREROUTING) →→
→→Routing decision→→ mangle packets(INPUT) →→ filter(INPUT) →→ 进入本机
2.源出于本地的包
本机程序 →→ Routing decision→→ mangle packets(OUTPUT)→→DNAT(OUTPUT) →→
→→filter(OUTPUT) →→ mangle packets(POSTROUTING) →→SNAT(OUTPUT)→→离开NIC→→
→→Internet
3.被转发的包
Internet →→ 进入NIC →→ mangle packets(PREROUTING) →→ DNAT(PREROUTING) →→
→→ Routing decision→→ mangle packets(FORWARD) →→filter(FORWARD) →→
→→ mangle packets(POSTROUTING)→→SNAT(POSTROUTING) )→→离开NIC→→ Internet
流程图:
——————————————————————————————————————————
Tables:
mangle 操作:TOS TTL MARK
nat 操作:DNAT SNAT MASQUERADE
filter 操作:DROP ACCEPT REJECT LOG →→ 过滤数据包
在iptables里,包是和被跟踪连接的四种不同状态有关的。它们是NEW,ESTABLISHED,RELATED和INVALID。
TCP:
一个TCP连接是经过三次握手协商连接信息才建立起来的。整个会话由一个SYN包开始,然后是一个 SYN/ACK包,最后是一个ACK包,此时,会话才建立成功,能够发送数据。(conntrack = connection tracking)
UDP:
UDP连接是无状态的,因为它没有任何的连接建立和关闭过程,而且大部分是无序列号的。以某个顺序收到的两个数据包是无法确定它们的发出顺序的。但内核仍然可以对UDP连接设置状态。
ICMP:
ICMP也是一种无状态协议,它只是用来控制而不是建立连接。
告诉UDP、TCP连接或正在努力建立的连接发生了什么,这时ICMP应答被认为是RELATED的。
ICMP包有很多类型,但只有四种类型有应答包,它们是回显请求和应答(Echo request and reply),时间戳请求和应答(Timestamp request and reply),信息请求和应答(Information request and reply),还有地址掩码请求和应答(Address mask request and reply),这些包有两种状态,NEW和ESTABLISHED 。时间戳请求和信息请求已经废除不用了,回显请求还是常用的,比如ping命令就用的到,地址掩码请求不太常用,但是可能有时很有用并且值得使用。
——————————————————————————————————————————
Syntax: iptables [-t table] command [match] [target/jump]
——————————————————————————————————————————
Commands:
-A, --append
iptables -A INPUT ...
-D, --delete
iptables -D INPUT --dport 80 -j DROP或iptables -D INPUT 1
-R, --replace
iptables -R INPUT 1 -s 192.168.0.1 -j DROP
-I, --insert
iptables -I INPUT 1 --dport 80 -j ACCEPT
-L, --list
iptables -L INPUT
-F, --flush
iptables -F INPUT
-Z, --zero
iptables -Z INPUT
-N, --new-chain
iptables -N allowed
-X, --delete-chain
iptables -X allowed
-P, --policy
iptables -P INPUT DROP
-E, --rename-chain
iptables -E allowed disallowed
——————————————————————————————————————————
Options:
-v, --verbose(详细的)
used with: --list, --append, --insert, --delete, --replace
-x, --exact(精确的)
used with: --list
-n, --numeric(数值)
used with: --list
--line-numbers
used with: --list
-c, --set-counters
used with: --insert, --append, --replace
--modprobe
used with: ALL
——————————————————————————————————————————
Generic matches:
-p, --protocol
iptables -A INPUT -p tcp
-s, --src, --source
iptables -A INPUT -s 192.168.1.1
-d, --dst, --destination
iptables -A INPUT -d 192.168.1.1
-i, --in-interface
iptables -A INPUT -i eth0
-o, --out-interface
iptables -A FORWARD -o eth0
-f, --fragment
iptables -A INPUT -f
——————————————————————————————————————————
TCP matches:
--sport, --source-port
iptables -A INPUT -p tcp --sport 22
--dport, --destination-port
iptables -A INPUT -p tcp --dport 22
--tcp-flags
iptables -p tcp --tcp-flags SYN,FIN,ACK SYN表示匹配那些SYN标记被设置而FIN和ACK标记没有设置的包
--tcp-flags ALL NONE匹配所有标记都未置1的包
iptables -p tcp --tcp-flags ! SYN,FIN,ACK SYN表示匹配那些FIN和ACK标记被设置而SYN标记没有设置的包
--syn
iptables -p tcp --syn
iptables -p tcp --tcp-flags SYN,RST,ACK SYN
! --syn用来匹配那些 RST或ACK被置位的包,换句话说,就是状态为已建立的连接的包。
--tcp-option
iptables -p tcp --tcp-option 16
——————————————————————————————————————————
UDP是一种无连接协议,所以在它打开、关闭连接以及在发送数据时没有多少标记要设置,它也不需要任何类型的确认。数据丢失了,就丢失了(不会发送ICMP错误信息的)。
UDP matches:
--sport, --source-port
iptables -A INPUT -p udp --sport 53
--dport, --destination-port
iptables -A INPUT -p udp --dport 53
——————————————————————————————————————————
ICMP协议也是无连接协议,ICMP包更是短命鬼,比UDP的还短。ICMP协议不是IP协议的下属协议,而是它的辅助者,其主要作用是报告错误和连接控制。
ICMP matches:
--icmp-type
iptables -A INPUT -p icmp --icmp-type 8
——————————————————————————————————————————
Limit match options:
--limit
iptables -A INPUT -m limit --limit 3/hour
--limit-burst
iptables -A INPUT -m limit --limit-burst 5
——————————————————————————————————————————
MAC match options:
--mac-source
iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01
——————————————————————————————————————————
Mark match options:
--mark
iptables -t mangle -A INPUT -m mark --mark 1
——————————————————————————————————————————
Multiport match options:
--source-port
iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
--destination-port
iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110
--port
iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
——————————————————————————————————————————
Owner match options:
--uid-owner
iptables -A OUTPUT -m owner --uid-owner 500
--gid-owner
iptables -A OUTPUT -m owner --gid-owner 0
--pid-owner
iptables -A OUTPUT -m owner --pid-owner 78
--sid-owner
iptables -A OUTPUT -m owner --sid-owner 100
——————————————————————————————————————————
State matches:
--state
iptables -A INPUT -m state --state RELATED,ESTABLISHED
——————————————————————————————————————————
TOS matches:
--tos
iptables -A INPUT -p tcp -m tos --tos 0x16
Minimize-Delay 16 (0x10),要求找一条路径使延时最小,如telnet、SSH、FTP-control 需要这个选项。
Maximize-Throughput 8 (0x08),要求找一条路径能使吞吐量最大,标准服务FTP-data能用到这个。
Maximize-Reliability 4 (0x04),要求找一条路径能使可靠性最高,使用它的有BOOTP和TFTP。
Minimize-Cost 2 (0x02),要求找一条路径能使费用最低,一般情况下使用这个选项的是一些视频音频流协议,如RTSP(Real Time Stream Control Protocol)。
Normal-Service 0 (0x00),一般服务,没有什么特殊要求。
——————————————————————————————————————————
TTL matches:
--ttl
iptables -A OUTPUT -m ttl --ttl 60
——————————————————————————————————————————
DNAT target:
--to-destination
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT \
--to-destination 192.168.1.1-192.168.1.10
iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \ --to-source $LAN_IP
要记住,按运行的顺序POSTROUTING链是所有链中最后一个,因此包到 达这条链时,已经被做过DNAT操作了,所以我们在规则里要基于内网的地址$HTTP_IP(包的目的地)来匹配 包。
iptables -t nat -A OUTPUT --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP
有了最后这条规则,一切都正常了。和HTTP服务器不在同一个网的机子能正常访问服务了,和它在一个 网内的机子也可以正常访问服务了,防火墙本身也能正常访问服务了,没有什么问题了。
——————————————————————————————————————————
SNAT target:
--to-source
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000
——————————————————————————————————————————
MASQUERADE target:
--to-ports
iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000
——————————————————————————————————————————
LOG target options:
--log-level
iptables -A FORWARD -p tcp -j LOG --log-level debug
--log-prefix
iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets"
--log-tcp-sequence
iptables -A INPUT -p tcp -j LOG --log-tcp-sequence
--log-tcp-options
iptables -A FORWARD -p tcp -j LOG --log-tcp-options
--log-ip-options
iptables -A FORWARD -p tcp -j LOG --log-ip-options
——————————————————————————————————————————
MARK target options:
--set-mark
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2
——————————————————————————————————————————
REDIRECT target:
--to-ports
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080-8090
——————————————————————————————————————————
REJECT target:
--reject-with
iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
——————————————————————————————————————————
RETURN target:
假设一个包进入了INPUT链,匹配了某条target为--jump EXAMPLE_CHAIN规则,然后进入了子链EXAMPLE_CHAIN。在子链中又匹配了某条规则,恰巧target是--jump RETURN,那包就返回INPUT链了。
如果在INPUT链里又遇到了--jump RETURN,那这个包就要交由缺省的策略来处理了。
——————————————————————————————————————————
TOS target:
--set-tos
iptables -t mangle -A PREROUTING -p TCP --dport 22 -j TOS --set-tos 0x10
Minimize-Delay 16 (0x10),要求找一条路径使延时最小,如telnet、SSH、FTP-control 需要这个选项。
Maximize-Throughput 8 (0x08),要求找一条路径能使吞吐量最大,标准服务FTP-data能用到这个。
Maximize-Reliability 4 (0x04),要求找一条路径能使可靠性最高,使用它的有BOOTP和TFTP。
Minimize-Cost 2 (0x02),要求找一条路径能使费用最低,一般情况下使用这个选项的是一些视频音频流协议,如RTSP(Real Time Stream Control Protocol)。
Normal-Service 0 (0x00),一般服务,没有什么特殊要求。
完整的列表可以通过命令iptables -j TOS -h
——————————————————————————————————————————
TTL target:
--ttl-set
iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-set 64
--ttl-dec
iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-dec 1
--ttl-inc
iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1
——————————————————————————————————————————
ULOG target:
--ulog-nlgroup
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-nlgroup 2
--ulog-prefix
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-prefix "SSH connection attempt: "
--ulog-cprange
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-cprange 100
--ulog-qthreshold
iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-qthreshold 10
——————————————————————————————————————————
未设置SYN的NEW状态包:
iptables有个“特点”没有被很好地给以说明,所以很多人都忽视了它。这个“特点”就是:如果你使用状态NEW,那么未设置SYN的包也会通过防火墙。之所以有这个特点,是因为在某些情况下,我们想把那样的包看作某个(比如是和另一个防火墙有关的)已处于ESTABLISHED状态的连接的一部分。这个特点使拥有两个或更多的防火墙协同工作成为可能,而且可使数据在服务器间无丢失的传输,如辅助防火墙可以接受子网的防火墙的操作。但它也会导致这样的事情:状态 NEW会允许几乎所有的TCP连接进入,而不管是否有3次握手。为了处理这个问题,我们需要在防火墙的 INPUT链、OUTPUT链和FORWARD链加入如下规则(译者注:此规则作者称为“NEW not SYN rules”,下一小节还会提到):
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG \ --log-prefix "New not syn:"$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
警告,在Netfilter/iptables项目中,这个特点所拥有的行为缺少文档说明,更明确的说,在你的防火墙上,它是一个很不安全的因素。 |
注意,这个规则用于microsoft的TCP/IP(微软实现的TCP/IP就是不行,至少现在不行)产生的包时还是有些问题。如果包是由microsoft的产品生成的,且被标为状态NEW,那么就会被此规则记录然后丢弃。看起来规则工作很正常啊,是吧。但问题就出在这儿了,因为连接无法中断了。这个问题出现在关闭连接时,在最后一个包即FIN/ACK包发出后,Netfilter的状态机制就会关闭连接、删除连接跟踪表里的相应记录。但就在这时,Microsoft那不完善的程序会发送另外一个包,这个包就是那种未设置SYN且被认为是NEW状态的包,因此它就会被上面的规则匹配。换句话说,就是对这个规则不需要过于关注,如果你很在意它,就在规则里加入选项--log-headers吧。这样,你就可以把包头记录下来,从而可以更好地了解相应的包。
对于这个规则,还有一些已知的问题。比如,某个连接(比如是从LAN发出的)已经连接到防火墙,而且有个脚本要在启动PPP时激活。当你启动PPP连接时,刚才提到的那个连接可能就会被干掉(be killed)。当然,这只会在特定的情况下才能发生,就是你把conntrack和nat作为模块运行,并且每次运行那个脚本时这两个模块都要被装入和卸载。如果你在防火墙之外的机子上运行telnet,而且又通过这个telnet连接运行脚本rc.firewall.txt,也会导致上面的问题。为了能简单地表达这个问题,你先准备一个telnet连接,或其他的流连接,再运行连接跟踪模块,然后装入上面的规则,最后,试着用telnet client或daemon发送一些数据。效果应该出来了,连接跟踪代码会认为这个连接是非法的,因为在此之前,它没有看到任何方向有包发出,更为严重的是现在连接上有了未设置SYN的包,因为刚才由telnet client或daemon发出的包肯定不是这个连接的第一个包。因此,上面的规则就起作用了,也就是说,这个包会被记录下来,然后被无情地扔掉,从而连接就会中断。
—————————————————————————————————————————
NEW状态的SYN/ACK包:
某些,TCP欺骗攻击所用的技术叫做序列号预测(Sequence Number Prediction)。在这类攻击中,攻击者利用另一台机子的IP访问攻击对象(译者注:这就是为什么叫欺骗的原因了,攻击者是想假冒另一台被攻击对象信任的机子,以达到欺骗攻击对象的目的),然后再试着预测攻击对象使用什么序列号。
我们来看看典型的使用序列号预测技术的欺骗是如何实现的,参与者:攻击者[A](attacker)试图假装另一台机子[O](other host)向受害者[V](victim)发送数据。
[A]以[O]的IP为源地址向[V]发SYN。
[V]向[O]回应SYN/ACK。
现在,若[O]以RST回应这个未知的SYN/ACK,攻击就失败了,但如果[O]已经没有这个能力了呢?比如它早已被另外的攻击(如SYN flood)降服,或者被关闭,或者它的RST包被防火墙拒绝。
如果[O]没能破坏这条连接,而且[A]猜对了序列号,那它就能以[O]的身份和[V]交谈了。
只要我们没能在第三步以RST回应那个未知的SYN/ACK包,[V]就会被攻击,而且我们还会被连累(译者注:因为我们本身也被攻击了,而且还可能会成为攻击者的替罪羊被起诉,呜呜,好惨)。所以,为安全起见,我们应该以正确的方式向[V]发送一个RST包。如果我们使用类似“NEW not SYN rules”(译者注:在上一小节中)的规则,SYN/ACK包就可以被丢弃了。因此,我们在bad_tcp_packets链中加入了如下规则:
iptables -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \ -m state --state NEW -j REJECT --reject-with tcp-reset这样,你想成为上面那个[O]的机会就很少了(译者注:作者好幽默啊,我们可不想成为被别人利用的对象),而且这条规则在绝大部分情况下是安全的,不会有什么副作用,但多个防火墙要协同工作的情况要除外。那种情况下,防火墙之间会经常传递、接受包或流,有了这条规则,有些连接可能会被阻塞,即使是合法的连接。这条规则的存在还产生了另外一问题,就是有几个portscan(端口扫描器)会看到我们的防火墙,但好在仅此而已。
——————————————————————————————————————————
使用私有IP地址的ISP:
上网时连接的网络是 ISP提供的,但某些愚蠢的ISP在那个网络里使用的是私有地址,而那是IANA专门分配给局域网使用的。Swedish Internet Service Provider和电话垄断企业Telia就是这样做的,例如在DNS服务器上,他们使用的IP地址段就是10.x.x.x。我们最容易遇到的问题是,在这个脚本里,为了防止被欺骗,不允许从10.x.x.x发出的连接来访问我们。不幸的是,对于上面的例子,为了DNS能正常地被访问,我们不得不把规则的放宽松一些。也就是说,我们或者在刚才提到的那条防止欺骗的规则上面增加一条规则(如下),或者是把那条规则注释掉:
/sbin/iptables -t nat -I PREROUTING -i eth1 -s 10.0.0.1/32 -j ACCEPT ——————————————————————————————————————————放行DHCP数据:
首先,我们要明白DHCP是工作在UDP协议之上的,所以,UDP协议是我们期望的第一个条件。其次,我们应该检查是从那个接口接收和发送请求的。例如,如果我们设置了DHCP使用接口eth0,那就要阻塞 eth1上的DHCP请求。为了让规则再详细些,我们只需打开(allow)DHCP实际使用的UDP端口,一般都是67和 68。这两个端口是标准定义,我们就用它们来匹配被允许的包。现在,规则应该是这个样子的:
$IPTABLES -I INPUT -i $LAN_IFACE -p udp --dport 67:68 --sport \ 67:68 -j ACCEPT注意,现在我们能够接受所有来自和发往UDP端口67、68的数据,好像不太安全,但这并不是多大的问题,因为这条规则只允许从67或68端口连接的主机才能访问。当然,此规则还可以更严谨一些,但也应该足够接受所有的DHCP请求和更新,而不至于需要在防火墙上开一个大洞。如果你很在意现在的规则是否很宽松,你当然可以写一个限制条件更紧的。