以下为和Netfilter相关的内核配置. 如何配置内核的详细信息可以参看http://www.linuxdoc.org/HOWTO/Kernel-HOWTO.html.
推荐 (non-netfilter related) - 这些选项可以在Linux内核中实现不同的网络功能,但它们可以在运行时允许/禁止
CONFIG_PROC_FS - 允许虚拟 /proc 文件系统
CONFIG_INET_ECN - 支持TCP 直接拥塞通知(Explicit Congestion Notification (ECN))
CONFIG_SYN_COOKIES - SYN cookies保护,可以用来保护不受syn洪水攻击 (synfloods)
CONFIG_IP_ADVANCED_ROUTER - 允许以下选项 (别的未列在此)
CONFIG_IP_ROUTE_VERBOSE - 允许详细的路由监控
CONFIG_IP_ROUTE_LARGE_TABLES - 改进的路由区域中的路由性能到超过64条实体
要求 - Kernel v2.4.x (推荐v2.4.5)
CONFIG_PACKET - 同packet socket
CONFIG_NETFILTER - 允许以下的所有的与netfilter相关的选项
Netfilter 相关- 星号表示推荐
CONFIG_IP_NF_CONNTRACK*
CONFIG_IP_NF_FTP*
CONFIG_IP_NF_QUEUE
CONFIG_IP_NF_IPTABLES*
CONFIG_IP_NF_MATCH_LIMIT*
CONFIG_IP_NF_MATCH_MAC
CONFIG_IP_NF_MATCH_MARK
CONFIG_IP_NF_MATCH_MULTIPORT*
CONFIG_IP_NF_MATCH_TOS
CONFIG_IP_NF_MATCH_TCPMSS
CONFIG_IP_NF_MATCH_STATE*
CONFIG_IP_NF_MATCH_UNCLEAN*
CONFIG_IP_NF_MATCH_OWNER
CONFIG_IP_NF_FILTER*
CONFIG_IP_NF_TARGET_REJECT*
CONFIG_IP_NF_TARGET_MIRROR
CONFIG_IP_NF_NAT*
CONFIG_IP_NF_NAT_NEEDED*
CONFIG_IP_NF_TARGET_MASQUERADE*
CONFIG_IP_NF_TARGET_REDIRECT
CONFIG_IP_NF_NAT_FTP*
CONFIG_IP_NF_MANGLE*
CONFIG_IP_NF_TARGET_TOS
CONFIG_IP_NF_TARGET_MARK
CONFIG_IP_NF_TARGET_LOG*
CONFIG_IP_NF_TARGET_TCPMSS
CONFIG_IP_NF_COMPAT_IPCHAINS
CONFIG_IP_NF_COMPAT_IPFWADM
举例- 以上编译iptables中,只有在给内核打上相应补丁后(可通过pending-patches 或patch-o-matic)
CONFIG_IP_NF_DROPTABLE
CONFIG_IP_NF_EGG
CONFIG_IP_NF_IRC
CONFIG_IP_NF_MATCH_AH_ESP
CONFIG_IP_NF_MATCH_IPLIMIT
CONFIG_IP_NF_MATCH_LENGTH
CONFIG_IP_NF_MATCH_PSD
CONFIG_IP_NF_MATCH_RPC
CONFIG_IP_NF_MATCH_TTL
CONFIG_IP_NF_NAT_SNMP_BASIC
CONFIG_IP_NF_POOL
CONFIG_IP_NF_TALK
CONFIG_IP_NF_TARGET_BALANCE
CONFIG_IP_NF_TARGET_FTOS
CONFIG_IP_NF_TARGET_NETLINK
CONFIG_IP_NF_TARGET_SAME
CONFIG_IP_NF_TARGET_TTL
CONFIG_IP_NF_TARGET_ULOG
CONFIG_IP6_NF_TARGET_LOG
CONFIG_IP6_NF_TARGET_REJECT
配置& 语法
约定
eth0 - 与Internet网的连接接口
eth1 - 内网接口
ip_address_of_eth0 - eth0的IP地址
ip_address_of_eth1 - eth1的IP地址
表、链和规则(Tables, chains, and rules)
当用Iptables来构造防火墙规则时,认清表、链和规则的区别很重要。
表提供特定的功能. 缺省表是filter, nat, 和mangle (除非你打了实验性的drop 表的补丁).
链是包传播的路径. 不同的表包含了不同的内置链. 用户自定义链能指向内置链. 如果一个包通过用户链中没有匹配,它将返回调用的链。如果一个包通过内置链中没有匹配,那么将由此链的缺省方针来确定是丢弃或接受
?/font>规则就是在链中用来实现某个特定匹配
包传播
在实施规则之前,必须知道包是如何在Netfilter的表和链中传播的。
可在以下连接中看到有关Netfilter中包的传播过程的更多细节,http://ods.dyndns.org/ipt_flow.html.
链的语法
创建新的链
iptables -N name_of_chain
删除空链 - 仅对自定义链
iptables -X name_of_chain*
*如果省略name_of_chain,将删除所有的自定义链
改变内置链的缺省方针Change the default policy
iptables -P name_of_chain name_of_policy*
*丢弃或接受
列出链的规则
iptables -L name_of_chain
清空链中的规则
iptables -F name_of_chain*
*如果省略name_of_chain,它将清空所有的链
将链中所有的规则的包和字节计数器归零
iptables -Z name_of_chain
规则的语法
典型的Iptables规则将指定:
A table (-t table_name). 省略情况下,为filter表.另外的内置表是nat和mangle表.
A rule action 链中的规则动作有: 添加(-A) , 删除(-D) 或替换(-R) 或插入(-I),后面跟表中链名
filter表中的内置规则:INPUT, FORWARD 和OUTPUT
nat表中的内置规则:PREROUTING, POSTROUTING 和OUTPUT
mangle表中的内置规则:PREROUTING 和OUTPUT
What to match - 可用的匹配(此列表不全):
!反符号,表示相反的意思
-p (协议: TCP, UDP, ICMP, 也可用数字- 见/etc/protocols)
-s (源地址)
-d (目的地址)
-i (入站的接口)
-o (出站的接口- 注意此说明发送包的接口)
--fragment (当源、目的端口无法区别时,将试图去匹配第二个和以后的碎片包,或者包的 ICMP类型)
--dport (目的端口)
--sport (源端口) 要么用数字,用么用/etc/services文件中的名字。可以用m:n来表示一组端口
--port (特殊的指定值的源和目的端口)
--mark (nfmark value)
--tcp-flags (允许基于匹配的TCP 标记) 此选项有两个参数:第一个表示要检查哪些标志;第二个表示哪些标志是1(其他则为0)
如: iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DENY
表示ALL(SYN,ACK,FIN,RST,URG,PSH)的标志都要被检查,但是只有设置了SYN和ACK的才匹配。
--syn (等同 --tcp-flags SYN,RST,ACK SYN)
--tcp-option (检测TCP头中TCP项的数字值 - 如果TCP报头不全则丢弃)
TCP标记的一个解释
有时候只允许一个单向的TCP连接。例如,你只需要访问外部的WWW的服务器,而不允许外部访问你内部的WWW服务器。朴素的方法是阻塞所有从你的服务器发出的包,但是TCP连接需要一个双向的交流。解决的方法是只需要阻塞请求连接的包。这些包叫做SYN包。通过阻塞这些包,我们可以达到上面的目的。
--state (用来匹配特定状态下的数据包(由连接跟踪子系统来决定状态))
NEW - 发起新的连接
ESTABLISHED - 属于某个已经建立的连接的数据包
RELATED - 一个包与某个连接有关,但是不属于这个连接。例如一个ICMP错误消息或FTP数据连接
INVALID - 不匹配于任何连接,通常这些包会被drop
例子:
iptables -A state_chk -m state --state ESTABLISHED,RELATED -j ACCEPT - 在state_chk链中添加一条规则,接受所有的TCP回应包
iptables -A state_chk -m state --state NEW -i ! eth0 -j ACCEPT - 在state_chk链中添加一条规则,接受所有从非eth0接口来的连接请求包
--mac-source (源MAC地址) 例如:--mac-source 00:60:08:91:CC:B7
-m unclean (实际上装载一个模块,尝试匹配不寻常的或不健全的包 - 处于实验阶段) 提供随机的安全检查
--tos (用来匹配IP包头TOS字段的值)
--ttl (包里的ttl值)
一般的速率限制
--limit (匹配速率限制 - 可以按秒、分、时、日来给),缺省值是3/hour
--limit-burst (达到速率限制的最大的爆发数目(阀值)),缺省值是5。
(maximum burst number before the imposing the set rate limit)
例如?/span>?sbin/iptables -A FORWARD -f -m limit --limit 100/s --limit-burst 100 -j ACCEPT
说明:对不管来自哪里的ip碎片都进行限制,允许每秒通过100个ip碎片,该限制触发的条件是100个ip碎片
例如: /sbin/iptables -A FORWARD -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT
说明:对不管来自哪里的icmp包都进行限制,允许每秒通过一个包,该限制触发的条件是10个包
例如: iptables -A INPUT -p icmp -m limit --limit 6/m --limit-burst 5 -j ACCEPT
iptables -P INPUT DROP
然后从另一部主机上ping这部主机,就会发生如下的现象:
首先我们可以看到前四个包的回应都很正常,然后从第五个包开始,我们每10秒可以收到一个正常的回应。这是因为我们设定了单位时间(在这里是每分钟)内允许通过的数据包的个数是每分钟6个,也即每10秒钟一个;其次我们又设定了事件触发阀值为5,所以我们的前四个包都是正常的,只是从第五个包开始,限制规则开始生效,故只能每10秒收到一个正常回应。
假设我们停止ping,30秒后又开始ping,这时的现象是:
前两个包是正常的,从第三个包开始丢包,这是因为在这里我的允许一个包通过的周期是10秒,如果在一个周期内系统没有收到符合条件的包,系统的触发值就会恢复1,所以假如我们30秒内没有符合条件的包通过,系统的触发值就会恢复到3,假如5个周期内都没有符合条件的包通过,系统都触发值就会完全恢复?/span>?/span>
基于IP的速率限制(TCP) - experiemental
--iplimit-above - 允许按照IP地址来限制并发的TCP连接数
所有者匹配(Owner matching section)
--uid-owner userid (匹配由特定的用户进程所产生的包)
--gid-owner groupid (匹配由特定的用户组进程产生的包)
--pid-owner processid (匹配由特定的进程产生的包)
--sid-owner sessionid (匹配由特定的会话组进程产生的包)
端口扫描检测 - experimental
--psd-weight-threshold (极限threshold)
--psd-delay-threshold (延迟delay)
--psd-lo-ports-weight (优先级weight)
--psd-hi-ports-weight (优先级weight)
对于SNAT,还有一个特殊的匹配
--to-source <ipaddr>[-<ipaddr>][:port-port] 仅在nat表中的POSTROUTING链中使用
可指定单一源地址或一地址范围,端口范围(仅在指定协议-p tcp or -p udp)。
对于DNAT,还有一个特殊的匹配
--to-destination <ipaddr>[-<ipaddr>][:port-port] 仅在nat表中的PREROUTING链和OUTPUT链中使用
iptables -t nat -A PREROUTING -j DNAT --to-destination 1.2.3.4:8080 -p tcp --dport 80 -i eth1
对于MASQUERADE,还有一个特殊的匹配
--to-ports <port>[-<port>] 仅在nat表中的POSTROUTING链中使用
对于REDIRECT,还有一个特殊的匹配
--to-ports <port>[-<port>] 仅在nat表中的PREROUTING链和OUTPUT链中使用
iptables -t nat -A PREROUTING -j REDIRECT --to-port 3128 -i eth1 -p tcp --dport 80
如果匹配包的目的地 . 可能的目标有:
ACCEPT - 接受此报
DROP - 丢弃此报,并且不做记录
REJECT -丢弃此包并发送错误信息给发送者
这个模块基本等同于DROP,但是有一点不同。发送方将送出一个ICMP报文:“port unreachable”。注意以下情况不发送:
被过滤的包本身是一个ICMP差错控制或未知报文;
第二块及以后的分片
最近已经送出了许多ICMP差错控制报文到那个目标
LOG - 用syslogd记录此报并继续传播
ULOG - 把包发往一个用户日志进程(experimental)
MIRROR - 将包的源/目的IP地址互换并重发包(experimental)
QUEUE - 将包发往用户进程的队列中 - 如果没有匹配,最终包将被丢弃
QUENE是一个特殊的目标。他将包放到用户空间等待处理。需要两个额外的部件:
1 队列处理器(处理包在内核和用户空间的流通)
2 用户空间的应用程序(接受包、操作包)
标准的队列处理器模块ip_queue。
下面是一个例子:
# modprobe iptable_filter
# modprobe ip_queue
# iptables -A OUTPUT -p icmp -j QUEUE
有了这条规则,本地产生的外出ICMP包将流到ip_queue模块,然后他再将包送到用户空间的应用程序。如果没有用户空间的应用程序等待这个包,DROP。
怎么写用户空间的应用程序呢?用libipq API。他是和iptables一起发布的。程序例子在CVS中的testsuide工具里。
ip_queue的状态可以通过下面的命令查看:
/proc/net/ip_queue
队列的最大长度可以用下面的命令来控制:
/proc/sys/net/ipv4/ip_queue_maxlen
缺省值是1024。
RETURN - 返回先前的调用的链;RETURN相当于到达chain的末尾。
对于一个内建的chain来说,执行相应的策略。对于自定义的,返回前一条chain
Name_of_a_custom chain - 用户定义, 一般都小写,但大写也可
mangle表提供了修改数据报各个字段的值的方法,这些在QoS中是很有用的
MARK
设置nfmark字段的值。我们可以修改nfmark字段的值。nfmark仅仅是一个用户定义的数据报的标记(可以是无符号长整数范围内的任何值)。该标记值用于基于策略的路由,通知ipqmpd (运行在用户空间的队列分捡器守护进程)将该数据报排队给哪个哪个进程等信息。
例: iptables -t mangle -A PREROUTING -j MARK --set-mark 0x0a -p tcp
TOS
设置数据报的IP头的TOS字段值。若希望适用基于TOS的数据报调度及路由,这个功能是非常有用处的。
例: iptables -t mangle -A PREROUTING -j TOS --set-tos 0x10 -p tcp --dport ssh
举例: iptables -t mangle -A PREROUTING -m state --state NEW -d 255.255.255.255 -i eth0 -j DROP
(此命令能够添加一条规则到mangle表的PREROUTING链,装载state 模块, 匹配发往eth0接口的目的地址为255.255.255.255的新连接,丢弃这些包并不记录)
下面是一个简单的IP伪装应用的Iptables规则(没有提供对外服务)
Bootstrapping Iptables
插入连接跟踪模块 (仅当没有编译进内核的情况下).
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp (如果你想用FTP)
设置缺省策略 - 设置内置链的缺省动作.
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
阻塞所有的新连接 除非连接是由内网(受保护的网络)发起的,此例中eth0接口接外网.
iptables -N state_chk - 在缺省的filter表中创建用户链state_chk
iptables -A state_chk -m state --state ESTABLISHED,RELATED -j ACCEPT - 在state_chk链中添加一条规则,接受所有的TCP回应包
iptables -A state_chk -m state --state NEW -i ! eth0 -j ACCEPT - 在state_chk链中添加一条规则,接受所有从非eth0接口来的连接请求包
iptables -A state_chk -j DROP - 在state_chk链中添加一条规则,其余的包丢弃
从INPUT和FORWARD链跳到 state_chk 链
iptables -A INPUT -j state_chk - 在INPUT链中添加一条规则,跳到state_chk链
iptables -A FORWARD -j state_chk - 在FORWARD链中添加一条规则,跳到state_chk链
伪装连接 - 仅当你需要与Internet连接.
允许IP转发 - 如果你要卸载Iptables规则,记得禁止IP转发.
echo "1" > /proc/sys/net/ipv4/ip_forward
装载NAT模块 - 仅当你已把它们当做模块编译了
modprobe iptable_nat
modprobe ip_nat_ftp (仅当你需要用FTP时)
允许IP伪装 - 当eth0为动态地址时用以下命令. 对于静态IP, 推荐使用源地址翻译(SNAT)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
(iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to ip_address_of_eth0)
允许源地址翻译(SNAT) - 仅当eth0有静态IP地址
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to ip_address_of_eth0
端口转发
Netfilter中端口转发是由Iptables来实现的. 你不再需要别的工具 (而在Ipchains中需要ipmasqadmin来实现). 仅当你需要在不同机器之间做通信转发时才需要端口转发。请注意这和转向(redirecting)不同.
Netfilter下做端口转发分两步骤.
目的地址翻译(Destination NAT the packets) (修改IP包头的目的IP地址和TC/UDP头的目的端口)
iptables -t nat -A PREROUTING -i eth0 -p protocol -d ip_address_of_eth0 --dport original_port_number -j DNAT --to destination_ip_address:destination_port_number
转发经过翻译的包(Forward the natted packets) (允许转发翻译过的包)
iptables -A FORWARD -i eth0 -o eth1 -p protocol -d destination_ip_address --dport destination_port_number -j ACCEPT
注意端口转发也要求允许IP转发和IP伪装或SNAT(返回的包需要修改源IP地址).
地址翻译(NAT Network Address Translation)
由于经常需要做IP伪装和对外开放内网的某些服务,因此这里把地址翻译单独拿出来讲。所谓的地址翻译一般来讲就是将内网地址翻译为外网地址,NAT有两种类型:Source NAT(SNAT)和Destination NAT(DNAT)。源NAT是指改变包的源地
址。很明显,这是在路由之后做。IP伪装是源NAT的特例。目的NAT是指改变包的目的地址,是在路由之前做。端口转
发是DNAT的特例。在ipchains中,端口转发需要其他的工具,如:ipmasqadm等,而现在Netfilter/Iptables本身就可解决!
NAT表中包括3个链(chain):PREROUTING(用于目的NAT)、POSTROUTING(用于源NAT)、OUTPUT(用于本地产生的包的目的
NAT)。下面给出两个典型应用
源NAT(SNAT)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 1.2.3.4
(可指定端口范围 --to 1.2.3.4:1-1023 或地址范围 --to 1.2.3.4-1.2.3.6)
IP伪装(SNAT的特例)
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
目的NAT(DNAT)
iptables -t nat -A PREROUTING -i eth1 -s 192.168.1.0/24 -j DNAT --to 1.2.3.4:3128
端口重定向(DNAT的特例) ,可用来和代理服务器联合起来做“透明代理”
iptables -t nat -A PREROUTING -i eth1 -p tcp -s 192.168.1.0/24 --dport 80 -j REDIRECT --to-ports 3128
Squid需要做的相应设置,在squid.conf中设置
http_port 3128
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
对于squid 2.4版本,还需要一个附加设置
httpd_accel_single_host off
分片处理(Fragment)
当一个包在传输过程中由于大于所经过的网络的最大传输单元(包的长度太大),将会分片,分成很多小的分片发出。在另一端再进行重组。关于分段的问题的是第一个分片可以很好的检查(IP + TCP/UDP/ICMP),但是后续的分片只有IP,没有上一层的信息。这对于过滤规则是不可能的。 因而,让我们看看过滤规则怎么处理分片。第一个分片跟普通的包处理没有任何区别,但是第二个以及以后的分片将由于缺少信息而不会与规则匹配。例如: 规则-p TCP --sport www将不会匹配任何分片(除了第一个分片)。同样规则-p TCP --sport ! www也不会匹配任何分片(除了第一个)。 但是可以使用-f 选项来描述规则,以适用于第二个和以后的分片。通常是让第二个和以后的分片通过,因为过滤规则适用于第一个分片,如果第一个分片没有通过,他的分片最终将不会重组。但是要小心大量的分片会崩掉你的网络或机器。
例如,下面的规则将会drop所有到192.168.1.1的分片:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
iptables的可扩展性
iptables是可以扩展的,这就意味着内核和iptables工具都可以扩展以提供新的特性。
内核扩展位于内核的模块子目录,例如/lib/modules/2.3.15/net。需要你手工加入这些模块。
Iptables程序扩展位于目录/usr/local/lib/iptables/。
为了获得扩展的帮助,用选项(-p、-m、-j)来装载他并且后跟-h,
例如: # iptables -p tcp --help
iptables与ipchains的区别
·iptables的缺省链的名称从小写换成大写,并且意义不再相同:INPUT和OUTPUT分别放置对目的地址是本机以及本机发出的数据包的过虑规则。
·-i选项现在只代表输入网络接口,输入网络接口则使用-o选项。
·TCP和UDP端口现在需要用--source-port或--sport(或--destination-port/--dport)选项拼写出来并且必须置于"-p tcp"或"-p udp"选项之后,因为它们分别是载入TCP和UDP扩展的。
·以前TCP的"-y"标志现在改为"--syn",并且必须置于"-p tcp"之后。
·原来的DENY目标最后改为了DROP。
·可以在列表显示单个链的同时将其清空。
·可以在清空内建链的同时将策略计数器清零。
·列表显示链时可显示计数器的当前瞬时值。
·REJECT和LOG现在变成了扩展目标,即意味着它们成为独立的内核模块。
·链名可以长达31个字符。
·MASQ现在改为MASQUERADE,并且使用不同的语法。REDIRECT保留原名称,但也改变了所使用的语法
总结(rc files and such)
好了,现在你有了一个基本的防火墙, 你可能希望它们能在系统启动时就起作用. 有两个基本的选项. 首先把所有的规则写到rc shell脚本中.然后使用命令 iptables-save 和iptables-restore.
你可以在系统网络初始化完成之后立即启动rc中的防火墙设置.
Iptables 帮助
目标的简要说明
iptables -j name_of_TARGET --help
匹配的简要说明
iptables -m name_of_match --help
列出ICMP消息类型
iptables -p icmp --help
以下是 iptables -h的简单输出文本. 列出的选项不全. 要更多的细节,可以看mn iptables 8.
iptables v1.2.2
Usage: iptables -[ADC] chain rule-specification [options]
iptables -[RI] chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LFZ] [chain] [options]
iptables -[NX] chain
iptables -E old-chain-name new-chain-name
iptables -P chain target [options]
iptables -h (print this help information)
Commands:
Either long or short options are allowed.
--append -A chain Append to chain
--delete -D chain Delete matching rule from chain
--delete -D chain rulenum
Delete rule rulenum (1 = first) from chain
--insert -I chain [rulenum]
Insert in chain as rulenum (default 1=first)
--replace -R chain rulenum
Replace rule rulenum (1 = first) in chain
--list -L [chain] List the rules in a chain or all chains
--flush -F [chain] Delete all rules in chain or all chains
--zero -Z [chain] Zero counters in chain or all chains
--check -C chain Test this packet on chain
--new -N chain Create a new user-defined chain
--delete-chain
-X [chain] Delete a user-defined chain
--policy -P chain target
Change policy on chain to target
--rename-chain
-E old-chain new-chain
Change chain name, (moving any references)
Options:
--proto -p [!] proto protocol: by number or name, eg. `tcp
--source -s [!] address[/mask]
source specification
--destination -d [!] address[/mask]
destination specification
--in-interface -i [!] input name[+]
network interface name ([+] for wildcard)
--jump -j target
target for rule (may load target extension)
--match -m match
extended match (may load extension)
--numeric -n numeric output of addresses and ports
--out-interface -o [!] output name[+]
network interface name ([+] for wildcard)
--table -t table table to manipulate (default: `filter)
--verbose -v verbose mode
--line-numbers print line numbers when listing
--exact -x expand numbers (display exact values)
[!] --fragment -f match second or further fragments only
--modprobe= try to insert modules using this command
--set-counters PKTS BYTES set the counter during insert/append
[!] --version -V print package version.