iptables
主要的防火墙有数据包过滤型的netfilter
和依据服务软件程序作为分析的TCP Wrapper
两种。
所谓包过滤,就是分析进入主机的网络数据包,将数据包的头部数据提取出来进行分析,以决定该连接为放行或抵挡的机制。
firewall:隔离工具;工作于主机或网络的边缘,对经由的报文根据预先定义的规则进行检测,对于能够被规则匹配到的报文实行某预定义的处理机制的一套组件。
硬件防火墙
:在硬件级别能实现部分防火功能;另一部分功能基于软件实现。
软件防火墙
:应用软件处理逻辑运行于通用硬件实现的防火墙。
主机防火墙
:服务范围为当前主机。
网络防火墙
:服务范围为局域网。
可以将信任网络(LAN)与不信任网络(Internet)完全分开,建议在Linux主机上安装两块网卡,分别接在不同的网络,这样可以避免很多问题。
iptables/netfilter:软件实现的主机或网络防火墙;带状态检测的包过滤型防火墙;连接追踪(conntrack)。
ipfw --> ipchains --> iptables
iptables:规则编写工具,编写规则并传递给内核中的netfilter,工作于用户空间。
五链chains:
PREROUTING(路由前)
INPUT(进入本机)
FORWARD(转发)
OUTPUT(本机流出)
POSTROUTING(路由后)
(1)内建链;
(2)自定义链;
netfilter:内核中的过滤框架(hook function)
prerouting
input
output
forward
postrouting
四表tables:根据功能不同,netfilter内置有四张表;
filter:过滤,防火墙;在编写规则时,如果不指定表类型,则默认是filter;包含三条内置链:
INPUT
FORWARD
OUTPUT
nat:network address translation;网络地址转换;用于修改报文的源地址或目标地址,以及端口;包含三条内置链:
这个表主要用来进行源地址和目标地址的IP或PORT的转换,与linux本机无关,主要与linux主机后的局域网内的计算机相关;
PREROUTING
OUTPUT
POSTROUTING
mangle:拆解报文,对地址和端口之外的信息做出修改,并重新封装起来;包含四条内置链:
PREROUTING
INPUT
OUTPUT
POSTROUTING
raw:关闭nat表上启用的连接追踪机制;包含两条内置链:
PREROUTING
OUTPUT
生效优先级次序(由高到低):
raw-->mangle-->nat-->filter
动作(target):
ACCEPT:接受,允许数据包通过;
DROP:丢弃数据包;
REJECT:拒绝数据包,并返回错误信息;
报文流向:
到本机某进程的报文: PREROUTING --> INPUT
有本机转发的报文: PREROUTING --> FORWARD --> POSTROUTING
由本机某进程发出的: OUTPUT --> POSTROUTING
iptables package info:
# rpm -qi iptables
Tools for managing Linux kernel packet filtering capabilities.
If you need to set up firewalls and/or IP masquerading, you should install this package.
# rpm -ql iptables
/usr/sbin/iptables
/usr/sbin/iptables-restore
/usr/sbin/iptables-save
iptables命令
匹配条件:
基本匹配:简单检查IP,TCP,UDP等报文的某属性进行匹配;
扩展匹配:需要借助于扩展模块进行的匹配条件;
添加规则的时候需要考量的问题:
(1)报文的流经路径,判断添加规则至哪个链上;
(2)确定要实现的功能,判断添加规则至哪个表上;
(3)要指定的匹配条件,用于匹配目标报文;
规则是有顺序的,从上到下匹配;一但匹配到某一条规则,就不会继续往下匹配了
# man iptables
# man iptables-extensions
iptables [-t table] {-A|-C|-D} chain rule-specification
iptables [-t table] -I chain [rulenum] rule-specification
iptables [-t table] -R chain rulenum rule-specification
iptables [-t table] -D chain rulenum
iptables [-t table] -S [chain [rulenum]]
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
iptables [-t table] -N chain
iptables [-t table] -X [chain]
iptables [-t table] -P chain target
iptables [-t table] -E old-chain-name new-chain-name
iptables [-m name [module-options...]] [-j target-name [target-options...]
rule-specification = [matches...] [target]
match = -m matchname [per-match-options]
target = -j targetname [per-target-options]
TABLES
-t,--table:指定表类型;默认为filter;
COMMANDS
链:
-P,--policy chain target:策略,定义默认策略;一般有两种选择,ACCEPT和DROP;
Set the policy for the chain to the given target.Only built-in (non-user-defined) chains can have policies.
-N,--new-chain chain:创建一条自定义链;被内建链上的规则调用时才能生效;
Create a new user-defined chain by the given name.
-X,--delete-chain [chain]:删除一条自定义链;链上没有规则,而且没有被引用时,才能被删除;
Delete the optional user-defined chain specified. The chain must be empty.
-F,--flush [chain]:清除指定链或所有链上的规则;注意清空规则之前要确认默认策略为ACCEPT,不然会将自己拒之门外;
Flush the selected chain (all the chains in the table if none is given).
-E,--rename-chain old-chain new-chain:重命名自定义链;已经调用旧链的规则会失效;
Rename the user specified chain to the user supplied name.
规则:
-A, --append chain rule-specification:追加,在指定链的尾部追加一条规则;
Append one or more rules to the end of the selected chain.
-I, --insert chain [rulenum] rule-specification:在指定的链中插入规则,并指定规则的序号;默认插入在最前面,也就是第一条;
Insert one or more rules in the selected chain as the given rule number.
the rule or rules are inserted at the head of the chain. This is also the default if no rule number is specified.
-D, --delete chain rule-specification; 删除指定规则。
-D, --delete chain rulenum:删除规则;(根据规则编号)
Delete one or more rules from the selected chain.
-R, --replace chain rulenum rule-specification:替换一条规则;
Replace a rule in the selected chain. Rules are numbered starting at 1.
查看:
-L, --list [chain]:列出指定链上的所有规则;
List all rules in the selected chain. If no chain is selected, all chains are listed. Filter is the default table.
# iptables -t nat -vnL 列出nat表上的所有规则;
-n, --numeric:以数值格式显示;
-v, --verbose:详细信息;
--line-numbers:查看规则时,显示规则编号;
When listing rules, add line numbers to the beginning of each rule.
-x, --exact:显示计数器的精确结果;
Expand numbers. Display the exact value of the packet and byte counters; This option is only relevant for the -L command.
-Z, --zero [chain [rulenum]]:置零;重置计数器;
Zero the packet and byte counters in all chains, or only the given chain, or only the given rule in a chain.
# iptables -Z
计数器:
记录被当前规则所匹配的:
(1)报文个数;
(2)字节总数;
PARAMETERS
-m, --match match:指定要使用的扩展模块;
Specifies a match to use.
-j, --jump target:处理动作;
This specifies the target of the rule. The target can be a user-defined chain.
多条规则之间的逻辑关系为"与"。
基本匹配条件
[!] -s, --source address[/mask]:指定源地址;
Source specification. Address can be either a network name, a hostname, a network IP address (with /mask), or a plain IP address.
An iptables mask of 24 is equivalent to 255.255.255.0.
[!] -d, --destination address[/mask]:指定目标地址;
允许172.16整个网络访问100.67这台主机:
# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.67 -j ACCEPT
# iptables -A ONPUT -d 172.16.0.0/16 -s 172.16.100.67 -j ACCEPT
拒绝100.68这台主机:
# iptables -A INPUT -s 172.16.100.68 -d 172.16.100.67 -j REJECT
# iptables -vnL --line-numbers
# iptables -D INPUT 2
# iptables -I INPUT -s 172.16.100.68 -d 172.16.100.67 -j REJECT
# iptables -vnL --line-numbers
把上面第一条规则替换为DROP:
# iptables -R 1 -s 172.16.100.68 -d 172.16.100.67 -j DROP
[!] -p, --protocol protocol:指定规则要检测的协议类型;
The protocol of the rule or of the packet to check.
The specified protocol can be one of tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh or the special keyword "all";
[!] -i, --in-interface name:数据报文的流入接口;
Name of an interface via which a packet was received (only for packets entering the INPUT, FORWARD and PREROUTING chains).
[!] -o, --out-interface name:数据报文的流出接口;
Name of an interface via which a packet is going to be sent (for packets entering the FORWARD, OUTPUT and POSTROUTING chains).
扩展匹配条件
隐式扩展:不用-m选项指出match name即可使用此match的专用选项进行匹配;
-p tcp: 隐含了-m tcp;These extensions can be used if '--protocol tcp' is specified.
[!] --source-port,--sport port[:port]:指定源端口;
Source port or port range specification.using the format first:last.
If the first port is omitted, "0" is assumed; if the last is omitted, "65535" is assumed.
If the first port is greater than the second one they will be swapped.
[!] --destination-port,--dport port[:port]:指定目标端口;
Destination port or port range specification.
[!] --tcp-flags mask comp:指定控制标志码;第一个参数表示要检测的flags,第二个参数表示其中为1的flag;
Flags are: SYN ACK FIN RST URG PSH ALL NONE.
Match when the TCP flags are as specified.
The first argument mask is the flags which we should examine, written as a comma-separated list;
the second argument comp is a comma-separated list of flags which must be set.
# iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST SYN
[!] --syn: Only match TCP packets with the SYN bit set and the ACK,RST and FIN bits cleared.
It is equivalent to --tcp-flags SYN,RST,ACK,FIN SYN.
Such packets are used to request TCP connection initiation;
-p udp: 隐含了-m udp;
[!] --source-port,--sport port[:port]
[!] --destination-port,--dport port[:port]
-p icmp: 隐含了-m icmp;
[!] --icmp-type {type[/code]|typename}
This allows specification of the ICMP type, which can be a numeric ICMP type, type/code pair;
8:echo-request;
0:echo-reply;
开启本机的ssh服务给172.16网段:
# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.100.67 -p tcp --dport 22 -j ACCEPT
# iptables -A ONPUT -d 172.16.0.0/16 -s 172.16.100.67 -p tcp --sport 22 -j ACCEPT
设置默认策略:
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
# iptables -P FORWARD DROP
允许本机ping操作:
# iptables -A OUTPUT -s 172.16.100.67 -p icmp --icmp-type 8 -j ACCEPT
# iptables -A INPUT -d 172.16.100.67 -p icmp --icmp-type 0 -j ACCEPT
显式扩展:必须使用-m选项指出match name。
multiport
以离散或连续的方式定义多端口匹配条件。
This module matches a set of source or destination ports. Up to 15 ports can be specified.
[!] --source-ports,--sports port[,port|,port:port]... 指定多个源端口
[!] --destination-ports,--dports port[,port|,port:port]... 指定多个目标端口
[!] --ports port[,port|,port:port]... 指定多个端口
开启本机ssh,telnet,httpd服务:
# iptables -A INPUT -d 172.16.100.67 -p tcp -m multiport --dports 22:23,80 -j ACCEPT
# iptables -A OUTPUT -s 172.16.100.67 -p tcp -m multiport --sports 22:23,80 -j ACCEPT
# iptables -A INPUT -d 172.16.100.67 -j DROP
# iptables -A OUTPUT -s 172.16.100.67 -j DROP
iprange
以连续的IP地址范围指明连续的多地址匹配条件
This matches on a given arbitrary range of IP addresses.
[!] --src-range from[-to]
Match source IP in the specified range.
[!] --dst-range from[-to]
Match destination IP in the specified range.
# iptables -I INPUT 2 -d 172.16.100.67 -p tcp --dport 3306 -m iprange --src-range 172.16.100.61-172.16.100.70 -j ACCEPT
# iptables -I OUTPUT 2 -s 172.16.100.67 -p tcp --sport 3306 -m iprange --dst-range 172.16.100.61-172.16.100.70 -j ACCEPT
string
对报文中的应用层数据做字符串匹配检测;
This modules matches a given string by using some pattern matching strategy.
[!] --string pattern 要检测的字符串模式
Matches the given pattern.
[!] --hex-string pattern 要检测的字符串模式,16进制编码
Matches the given pattern in hex notation.
--algo {bm|kmp} 指定模式匹配的策略
Select the pattern matching strategy.
# iptables -I OUTPUT -s 172.16.100.67 -p tcp --sport 80 -m iprange ! --dst-range 172.16.100.61-172.16.100.70 -m string --string "admin" --algo kmp -j REJECT
time
根据报文到达的时间与指定的时间范围进行匹配检测
This matches if the packet arrival time/date is within a given range.
All times are interpreted as UTC by default.
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:起始日期时间
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:结束日期时间
If --datestart or --datestop are not specified, it will default to 1970-01-01 and 2038-01-19, respectively.
--timestart hh:mm[:ss]:起始时间
--timestop hh:mm[:ss]:结束时间
The possible time range is 00:00:00 to 23:59:59.
Leading zeroes are allowed (e.g. "06:03") and correctly interpreted as base-10.
[!] --monthdays day[,day...]:只匹配每月中指定的天
Only match on the given days of the month. Possible values are 1 to 31.
[!] --weekdays day[,day...]:只匹配每周中指定的周几
Only match on the given weekdays. Possible values are Mon, Tue, Wed, Thu, Fri, Sat, Sun, or values from 1 to 7;
只允许telnet服务周二四六工作时间访问:
# iptables -I INPUT -d 172.16.100.67 -p tcp --dport 23 -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays Tue,Thu,Sat -j ACCEPT
connlimit
根据每个客户端IP做并发连接数限制。
Allows you to restrict the number of parallel connections to a server per client IP address.
--connlimit-upto n:连接数量小于等于n,则被匹配;此处一般为允许
Match if the number of existing connections is below or equal n.
--connlimit-above n:连接数量大于n,则被匹配;此处一般为拒绝
Match if the number of existing connections is above n.
# iptables -A INPUT -d 172.16.100.67 -p tcp --dport 23 -m connlimit --connlimit-upto 2 -j ACCEPT
# iptables -A INPUT -d 172.16.100.67 -p tcp --dport 22 -j ACCEPT
# iptables -A INPUT -d 172.16.100.67 -j DROP
limit
基于收发报文的速率进行匹配,令牌桶。
This module matches at a limited rate using a token bucket filter.
A rule using this extension will match until this limit is reached.
--limit rate[/second|/minute|/hour|/day]:Maximum average matching rate: specified as a number, with an optional '/second','/minute','/hour',or '/day' suffix;The default is 3/hour. 平均速率
--limit-burst number:Maximum initial number of packets to match; The default is 5. 峰值速率
# iptables -A INPUT -d 172.16.100.67 -p icmp --icmp-type 8 -m limit --limit-burst 5 --limit 20/minute
state
状态检测;连接追踪机制(conntrack);
The "state" extension is a subset of the "conntrack" module.
[!] --state state
Where state is a comma separated list of the connection states to match.
INVALID:无法识别的连接;
ESTABLISHED:已经追踪到的连接;
NEW:新连接;
RELATED:相关联的连接;
UNTRACKED:未追踪的连接;
# find /lib/modules/3.10.0-327.el7.x86_64/ -iname *conntrack* # 查找连接追踪的内核模块;
/lib/modules/3.10.0-327.el7.x86_64/kernel/net/netfilter/nf_conntrack.ko # 核心模块;
/lib/modules/3.10.0-327.el7.x86_64/kernel/net/netfilter/nf_conntrack_ftp.ko # 追踪ftp连接的模块;
# lsmod | grep conntrack
nf_conntrack 105745 5 nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4
# cat /proc/net/nf_conntrack # 连接追踪表,已经追踪到的连接
# cat /proc/sys/net/nf_conntrack_max # 能追踪的连接的最大数量;此值可自定义,建议必要时调整到足够大
Size of connection tracking table. Default value is nf_conntrack_buckets value * 4.
# vim /etc/sysctl.conf # 加大nf_conntrack_max的值;
net.ipv4.nf_conntrack_max = 393216
net.ipv4.netfilter.nf_conntrack_max = 393216
# ls /proc/sys/net/netfilter/ # 不同的协议的连接追踪的超时时长和其它参数;连接追踪超时后会从追踪表中删除;
# vim /etc/sysctl.conf # 减小nf_conntrack timeout的时间;
net.ipv4.netfilter.nf_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
放行ESTABLISHED:
# iptables -A INPUT -d 172.16.100.67 -m state --state ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -s 172.16.100.67 -m state --state ESTABLISHED -j ACCEPT
开放本机的ssh,telnet,httpd,mysql服务:
# iptables -A -INPUT -d 172.16.100.67 -p tcp -m multiport --dports 22,23,80,3306 -m state --state NEW -j ACCEPT
# iptables -A INPUT -d 172.16.100.67 -j DROP
# iptables -A INPUT -s 172.16.100.67 -j DROP
允许本机ping操作:
# iptables -I INPUT -d 172.16.100.67 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT
开放被动模式的ftp服务:
(1)装载追踪ftp协议的模块:
# modprobe nf_conntrack_ftp
(2)放行命令连接:
# iptables -R -INPUT 2 -d 172.16.100.67 -p tcp -m multiport --dports 21,22,23,80,3306 -m state --state NEW -j ACCEPT
(3)放行数据连接:
# iptables -R -INPUT 1 -d 172.16.100.67 -m state --state ESTABLISHED,RELATED -j ACCEPT
在CentOS6中:
保存规则,自动保存至/etc/sysconfig/iptables文件中:
# service iptables save
重载规则:
# service iptables restore
在CentOS7中:
保存规则:
# iptables-save > /path/to/file
重载规则:
# iptables-restore < /path/from/file
如果要开机装载规则,可以将命令写入/etc/rc.d/rc/local;
# man iptables-save
dump iptables rules to stdout. # 可以用来查看所有防火墙规则;
规则优化
(1)可安全放行所有入站及出站且状态为ESTABLISHED的连接;
(2)服务于同一类功能的规则,匹配条件严格的放前面,宽松的放后面;
(3)服务于不同类功能的规则,匹配报文可能性较大的放前面,较小的放后面;
(4)将那些可由一条规则描述的多个规则合并为一;
(4)设置默认策略;
默认策略设定;
最后一条规则设定;
网络防火墙
在FORWARD链上定义规则,注意以下几个问题:
(1)请求-响应均经由FORWARD链,要注意规则的方向性;
(2)如果可以启用conntrack机制,建议将双方向的状态为ESTABLISHED的报文直接放行;
# iptables -A FORWARD -j DROP
# iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # 开放所有ESTABLISHED和RELATED;
# iptables -I FORWARD 2 -s 192.168.11.0/24 -m state --state NEW -j ACCEPT # 开放所有由内而外的包;
# iptables -I FORWARD 3 -d 192.168.11.2 -p tcp -m multiport --dports 21:23,80 -m state --state NEW -j ACCEPT # 开放ftp,ssh,telnet,http;
# modprobe nf_conntrack_ftp # 装载追踪ftp协议的模块;
自定义链
# iptables -N icmp_rules # 创建一条自定义链;
# iptables -vnL
# iptables -I FORWARD 2 -p icmp -j icmp_rules # icmp协议的包都跳转到icmp_rules链上;
# iptables -A icmp_rules -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT # 放行ping包;
# iptables -vnL
# iptables -A icmp_rules -j RETURN # 如果没有匹配到,则返回主链;
# iptables -D FORWARD 2 # 删除引用自定义链的规则;引用计数变为0;
# iptables -F icmp_rules # 清空自定义链上的规则;
# iptables -X icmp_rules # 删除自定义链;
RETURN:返回,结束匹配当前链并返回原链的下一条规则。
REDIRECT:端口重定向。
This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains.
--to-ports port[-port]:映射至哪个目标端口;
This specifies a destination port or range of ports to use.
# iptables -t nat -A PREROUTING -d 172.16.100.67 -p tcp --dport 80 -j REDIRECT --to-ports 8088
# iptables -t nat -vnL
SNAT:源地址转换。
This target is only valid in the nat table, in the POSTROUTING and INPUT chains.
--to-source [ipaddr[-ipaddr]][:port[-port]]
which can specify a single new source IP address, an inclusive range of IP addresses. Optionally a port range.
# iptables -F
# iptables -t nat -F
# iptables -t nat -A POSTROUTING -s 192.168.11.0/24 -j SNAT --to-source 172.16.100.6
MASQUERADE:源地址伪装。
This target is only valid in the nat table, in the POSTROUTING chain.
It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.
--to-ports port[-port]
This specifies a range of source ports to use, overriding the default SNAT source port-selection heuristics.
DNAT:目标地址转换,把内网服务器公开给外网使用。
This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains.
--to-destination [ipaddr[-ipaddr]][:port[-port]]
which can specify a single new destination IP address, an inclusive range of IP addresses. Optionally a port range.
# iptables -t nat -A PREROUTING -d 172.16.100.7 -p tcp --dport 80 -j DNAT --to-destination 192.168.11.2:8088
LOG
Turn on kernel logging of matching packets.
When this option is set for a rule, the Linux kernel will print some information on all matching packets via the kernel log. /var/log/messages.
--log-prefix prefix: 为日志信息指定前缀; 最长29个字母;
Prefix log messages with the specified prefix; up to 29 letters long.
--log-ip-options
Log options from the IP/IPv6 packet header.
# iptables -A INPUT -d 172.16.100.67 -p tcp --dport 8088 -j LOG --log-prefix "(8088)" --log-options
# tail /var/log/messages