iptables指令及示例介绍
常用指令列表:指令 -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
说明 修改某自订规则炼的名称。
常用封包比对参数:
参数 -p, --protocol
范例 iptables -A INPUT -p tcp
说明 比对通讯协议类型是否相符,可以使用 ! 运算子进行反向比对,例如:-p ! tcp ,意思是指除 tcp 以外的其它类型,包含 udp、icmp ...等。如果要比对所有类型,则可以使用 all 关键词,例如:-p all。
参数 -s, --src, --source
范例 iptables -A INPUT -s 192.168.1.1
说明 用来比对封包的来源 IP,可以比对单机或网络,比对网络时请用数字来表示屏蔽,例如:-s 192.168.0.0/24,比对 IP 时也可以使用 ! 运算子进行反向比对,例如:-s ! 192.168.0.0/24。
参数 -d, --dst, --destination
范例 iptables -A INPUT -d 192.168.1.1
说明 用来比对封包的目的地 IP,设定方式同上。
参数 -i, --in-interface
范例 iptables -A INPUT -i eth0
说明 用来比对封包是从哪片网卡进入,可以使用通配字符 + 来做大范围比对,例如:-i eth+ 表示所有的 ethernet 网卡,也可以使用 ! 运算子进行反向比对,例如:-i ! eth0。
参数 -o, --out-interface
范例 iptables -A FORWARD -o eth0
说明 用来比对封包要从哪片网卡送出,设定方式同上。
参数 --sport, --source-port
范例 iptables -A INPUT -p tcp --sport 22
说明 用来比对封包的来源埠号,可以比对单一埠,或是一个范围,例如:--sport 22:80,表示从 22 到 80
埠之间都算是符合条件,如果要比对不连续的多个埠,则必须使用 --multiport 参数,详见后文。比对埠号时,可以使用 !运算子进行反向比对。
参数 --dport, --destination-port
范例 iptables -A INPUT -p tcp --dport 22
说明 用来比对封包的目的地埠号,设定方式同上。
参数 --tcp-flags
范例 iptables -p tcp --tcp-flags SYN,FIN,ACK SYN
说明 比对 TCP封包的状态旗号,参数分为两个部分,第一个部分列举出想比对的旗号,第二部分则列举前述旗号中哪些有被设定,未被列举的旗号必须是空的。TCP状态旗号包括:SYN(同步)、ACK(应答)、FIN(结束)、RST(重设)、URG(紧急)、PSH(强迫推送)等均可使用于参数中,除此之外还可以使用关键词 ALL 和 NONE 进行比对。比对旗号时,可以使用!运算进行反向比对。
参数 --syn
范例 iptables -p tcp --syn
说明 用来比对是否为要求联机之 TCP 封包,与 iptables -p tcp --tcp-flags SYN,FIN,ACK SYN 的作用完全相同,如果使用!运算,可用来比对非要求联机封包。
参数 -m multiport --source-port
范例 iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
说明 用来比对不连续的多个来源埠号,一次最多可以比对 15 个埠,可以使用!运算子进行反向比对。
参数 -m multiport --destination-port
范例 iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110
说明 用来比对不连续的多个目的地埠号,设定方式同上。
参数 -m multiport --port
范例 iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
说明 这个参数比较特殊,用来比对来源埠号和目的埠号相同的封包,设定方式同上。注意:在本范例中,如果来源端口号为 80 但目的地埠号为 110,这种封包并不算符合条件。
参数 --icmp-type
范例 iptables -A INPUT -p icmp --icmp-type 8
说明 用来比对 ICMP 的类型编号,可以使用代码或数字编号来进行比对。请打 iptables -p icmp --help 来查看有哪些代码可以用。
参数 -m limit --limit
范例 iptables -A INPUT -m limit --limit 3/hour
说明 用来比对某段时间内封包的平均流量,上面的例子是用来比对:每小时平均流量是否超过一次 3 个封包。
除了每小时平均一次外,也可以每秒钟、每分钟或每天平均一次,默认值为每小时平均一次,参数如后: /second、/minute、/day。除了进行封包数量的比对外,设定这个参数也会在条件达成时,暂停封包的比对动作,以避免因骇客使用洪泛攻击法,导致服务被阻断。
参数 --limit-burst
范例 iptables -A INPUT -m limit --limit-burst 5
说明 用来比对瞬间大量封包的数量,上面的例子是用来比对一次同时涌入的封包是否超过 5 个(这是默认值),超过此上限的封包将被直接丢弃,使用效果同上。
参数 -m mac --mac-source
范例 iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01
说明 用来比对封包来源网络接口的硬件地址,这个参数不能用在 OUTPUT 和 Postrouting
规则炼上,这是因为封包要送出到网卡后,才能由网卡驱动程序透过 ARP 通讯协议查出目的地的 MAC 地址,所以 iptables在进行封包比对时,并不知道封包会送到哪个网络接口去。
参数 --mark
范例 iptables -t mangle -A INPUT -m mark --mark 1
说明 用来比对封包是否被表示某个号码,当封包被比对成功时,我们可以透过 MARK 处理动作,将该封包标示一个号码,号码最大不可以超过 4294967296。
参数 -m owner --uid-owner
范例 iptables -A OUTPUT -m owner --uid-owner 500
说明 用来比对来自本机的封包,是否为某特定使用者所产生的,这样可以避免服务器使用 root 或其它身分将敏感数据传送出去,可以降低系统被骇的损失。可惜这个功能无法比对出来自其它主机的封包。
参数 -m owner --gid-owner
范例 iptables -A OUTPUT -m owner --gid-owner 0
说明 用来比对来自本机的封包,是否为某特定使用者群组所产生的,使用时机同上。
参数 -m owner --pid-owner
范例 iptables -A OUTPUT -m owner --pid-owner 78
说明 用来比对来自本机的封包,是否为某特定行程所产生的,使用时机同上。
参数 -m owner --sid-owner
范例 iptables -A OUTPUT -m owner --sid-owner 100
说明 用来比对来自本机的封包,是否为某特定联机(Session ID)的响应封包,使用时机同上。
参数 -m state --state
范例 iptables -A INPUT -m state --state RELATED,ESTABLISHED
说明 用来比对联机状态,联机状态共有四种:INVALID、ESTABLISHED、NEW 和 RELATED。
INVALID 表示该封包的联机编号(Session ID)无法辨识或编号不正确。
ESTABLISHED 表示该封包属于某个已经建立的联机。
NEW 表示该封包想要起始一个联机(重设联机或将联机重导向)。
RELATED 表示该封包是属于某个已经建立的联机,所建立的新联机。例如:FTP-DATA 联机必定是源自某个 FTP 联机。
常用的处理动作:
-j 参数用来指定要进行的处理动作,常用的处理动作包括:ACCEPT、REJECT、DROP、REDIRECT、MASQUERADE、LOG、DNAT、SNAT、MIRROR、QUEUE、RETURN、MARK,分别说明如下:
ACCEPT 将封包放行,进行完此处理动作后,将不再比对其它规则,直接跳往下一个规则炼(nat:postrouting)。
REJECT 拦阻该封包,并传送封包通知对方,可以传送的封包有几个选择:ICMP port-unreachable、ICMP echo-reply 或是 tcp-reset(这个封包会要求对方关闭联机),进行完此处理动作后,将不再比对其它规则,直接 中断过滤程序。
范例如下:
iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
DROP 丢弃封包不予处理,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。
REDIRECT 将封包重新导向到另一个端口(PNAT),进行完此处理动作后,将会继续比对其它规则。这个功能可以用来实作通透式 porxy或用来保护 web 服务器。例如:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
MASQUERADE 改写封包来源 IP 为防火墙 NIC IP,可以指定 port对应的范围,进行完此处理动作后,直接跳往下一个规则炼(mangle:postrouting)。这个功能与 SNAT 略有不同,当进行 IP伪装时,不需指定要伪装成哪个 IP,IP 会从网卡直接读取,当使用拨接连线时,IP 通常是由 ISP 公司的 DHCP 服务器指派的,这个时候MASQUERADE 特别有用。范例如下:
iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000
LOG 将封包相关讯息纪录在 /var/log 中,详细位置请查阅 /etc/syslog.conf 组态档,进行完此处理动作后,将会继续比对其它规则。例如:
iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets"
SNAT 改写封包来源 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将直接跳往下一个规则链(mangle:postrouting)。范例如下:
iptables -t nat -A POSTROUTING -p tcp-o eth0 -j SNAT --to-source 194.236.80.155-194.236.80.160:1024-32000
DNAT 改写封包目的地 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将会直接跳往下一个规则链(filter:input 或 filter:forward)。范例如下:
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.0.1-192.168.0.10:80-100
MIRROR 镜射封包,也就是将来源 IP 与目的地 IP 对调后,将封包送回,进行完此处理动作后,将会中断过滤程序。
QUEUE 中断过滤程序,将封包放入队列,交给其它程序处理。透过自行开发的处理程序,可以进行其它应用,例如:计算联机费用等。
RETURN 结束在目前规则炼中的过滤程序,返回主规则炼继续过滤,如果把自订规则炼看成是一个子程序,那么这个动作,就相当于提早结束子程序并返回到主程序中。
MARK 将封包标上某个代号,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续比对其它规则。范例如下:
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2
排除条件
即只允许从本机ip地址过来的请求才放行或非本机来源一概拒绝。
如下的语句开启保护本机上的hbase。
/sbin/iptables -A INPUT ! -s 172.16.8.3 -p tcp -m multiport --dports 2181,60010,43063 -j DROP
有三种需要处理的情况
Source or dest ip address
Interface name
Protocol name etc
除开udp协议都允许通过
iptables -A INPUT -p ! UDP
The following match allows IP address range matching and it can be inverted using the ! sign:
iptables -A INPUT -d 192.168.0.0/24 -j DROP
iptables -A OUTPUT -d ! 192.168.1.2 -J ACCEPT
# we trust 192.168.1.5 so skip it
iptables -A OUTPUT -s ! 192.168.1.5 -J DROP
The exclamation mark inverts the match so this will result is a match if the IP is anything except one in the given range 192.168.1.0/24:
iptables -A INPUT -s ! 192.168.1.0/24 -p tcp --dport 80 -J DROP
You can skip your own ip from string test:
iptables -A FORWARD -i eth0 -p tcp ! -s 192.168.1.2 --sport 80 -m string --string '|Nofree|ELF' -j DROP
Accept port 22 traffic on all interfaces except for eth1 which is connected to the Internet:
iptables -A INPUT -i !eth1 -p tcp --dport 22 -j ACCEPT
可以使用'iptables -L -n -vv'查看具体的情况,包括"-i !eth1" and "! -i eth1"这两种写法。
Iptables set range of IP addresses -- 使用iptables设置ip地址区间段的操作
You need to use following options with match extensions (-m Ext).首先要调入iprange模块。
iprange : This matches on a given arbitrary range of IPv4 addresses.
[!]–src-range ip-ip: Match source IP in the specified range.
[!]–dst-range ip-ip: Match destination IP in the specified range.
Syntax:
-m iprange –src-range IP-IP -j ACTION
-m iprange –dst-range IP-IP -j ACTION
For example, allow incoming request on a port 22 for source IP in the 192.168.1.100-192.168.1.200 range only. You need to add something as follows to your iptables script:
iptables -A INPUT -p tcp --destination-port 22 -m iprange --src-range 192.168.1.100-192.168.1.200 -j ACCEPT
Port range(端口范围)
if –protocol tcp (-p tcp) is specified, you can specify source port range with following syntax:
–source-port port:port
–sport port:port
And destination port range specification with following option :
–destination-port port:port
–dport port:port
For example block lock all incoming ssh access at port 22, for source port range 513:65535:
iptables -A INPUT -p tcp -s 0/0 --sport 513:65535 -d 195.55.55.78 --dport 22 -m state --state NEW,ESTABLISHED -j DROP
On the other hand, just allow incoming ssh request with following port range:
iptables -A INPUT -p tcp -s 0/0 -d 195.55.55.78 --sport 513:65535 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -s 195.55.55.78 -d 0/0 --sport 22 --dport 513:65535 -m state --state ESTABLISHED -j ACCEPT
NAT table – range option
NAT表相关的范围选项
If you are using NAT table use options –to-source and –to-destination. For example IP address range:
iptables -t nat -A POSTROUTING -j SNAT --to-source 192.168.1.100-192.168.1.200
ALTERNATIVELY, try range of ports:
iptables -t nat -A POSTROUTING -j SNAT --to-source 192.168.1.100:2000-3000
应用示例
----------------------------------------------------------------
使用iptables做常见的ip port转发设置
将对dns、web服务的请求重定向其它ip上。
iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination 192.168.5.10
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.5.5
服务器有内外网地址,可对该服务器时行设置让所有的内网通过该机器出外网。
#内网访问公网设置
echo '1' > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
/sbin/iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
访问192.168.18.8:1706时,实际上访问另外一台机器上的3306端口。
#内网数据库端口转发
echo '1' > /proc/sys/net/ipv4/conf/eth0/forwarding
iptables -t nat -A PREROUTING -d 192.168.18.8 -p tcp -m tcp --dport 1706 -j DNAT --to-destination 192.168.18.4:3306
iptables -t nat -A POSTROUTING -s 0/0 -d 192.168.18.4 -p tcp -m tcp --dport 3306 -j SNAT --to-source 192.168.18.8:1706
iptables -A INPUT -p tcp -m state --state NEW --dport 1706 -i eth1 -j ACCEPT
通过拨号设备带动局域网上网,然后再做端口转发。
I want connections coming in on ppp0 on port 8001 to route to 192.168.1.200 on eth0 on port 8080
First of all - you should check if forwarding is allowed at all:
cat /proc/sys/net/ipv4/conf/ppp0/forwarding
cat /proc/sys/net/ipv4/conf/eth0/forwarding
If both returns 1 it's ok. If not do the following:
echo '1' > /proc/sys/net/ipv4/conf/ppp0/forwarding
echo '1' > /proc/sys/net/ipv4/conf/eth0/forwarding
Second thing - DNAT could be applied on nat table only. So, your rule should be extended by adding table specification as well (-t nat):
iptables -t nat -A PREROUTING -p tcp -i ppp0 --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
iptables -A FORWARD -p tcp -d 192.168.1.200 --dport 8080 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
Both rules are applied only to TCP traffic (if you want to alter UDP as well, you need to provide similar rules but with -p udp option set).
Last, but not least is routing configuration,Type: ip route
and check if 192.168.1.0/24 is among returned routing entries.
You forget postrouting source address SNAT:
sysctl net.ipv4.ip_forward=1
your_wan_ip=101.23.3.1
-A PREROUTING -p tcp -m tcp -d $yours_wan_ip --dport 8001 -j DNAT --to-destination 192.168.1.200:8080
-A POSTROUTING -p tcp -m tcp -s 192.168.1.200 --sport 8080 -j SNAT --to-source $yours_wan_ip
-A FORWARD -m state -p tcp -d 192.168.1.200 --dport 8080 --state NEW,ESTABLISHED,RELATED -j ACCEPT
And don't forget to set your linux firewall as default gateway on computer with 192.168.1.200 address.
端口重定向示例1
iptables的重要功能之一是用于端口和/或地址的转换。如下示例展示了将默认HTTP端口的数据包由80转向8080端口。这样HTTP的daemon可以允许由一般用户权限引导,而不需要对一般用户无法将端口号绑在1024端口以下的限制的问题多加考虑。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
注意:如果在电脑上面运行了这个指令,它只会对连到你的机器上的外部的IP发生效果。从本地端发起的连线不会遵循NAT表上PREROUTING链的设置。如果想让本地端也遵循规则,可以另外键入下面的指令:
iptables -t nat -A OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
这条规则会将lo接口上的数据包输出由80端口转向到8080端口上面。
----------------------------------------------------------------
使用iptables来阻止特定来源的访问
Block an ip address(全面阻止对特定的访问)
iptables -A INPUT -s IP-ADDRESS -j DROP
阻止特定ip对本机特定端口的访问
iptables -A INPUT -s ip_addr -p tcp --destination-port 25 -j DROP
阻止对本机的特定端口的访问
Block Incoming Port
The syntax is as follows to block incoming port using IPtables:
/sbin/iptables -A INPUT -p tcp --destination-port {PORT-NUMBER-HERE} -j DROP
### interface section use eth1 ###
/sbin/iptables -A INPUT -i eth1 -p tcp --destination-port {PORT-NUMBER-HERE} -j DROP
### only drop port for given IP or Subnet ##
/sbin/iptables -A INPUT -i eth0 -p tcp --destination-port {PORT-NUMBER-HERE} -s {IP-ADDRESS-HERE} -j DROP
/sbin/iptables -A INPUT -i eth0 -p tcp --destination-port {PORT-NUMBER-HERE} -s {IP/SUBNET-HERE} -j DROP
To block port 80 (HTTP server), enter (or add to your iptables shell script):
/sbin/iptables -A INPUT -p tcp --destination-port 80 -j DROP
/sbin/service iptables save
Block Incomming Port 80 except for IP Address 1.2.3.4
/sbin/iptables -A INPUT -p tcp -i eth1 -s ! 1.2.3.4 --dport 80 -j DROP
Block Outgoing Port
对出链的连接进行阻止,多用于网关NAT的机器上。
The syntax is as follows:
/sbin/iptables -A OUTPUT -p tcp --dport {PORT-NUMBER-HERE} -j DROP
### interface section use eth1 ###
/sbin/iptables -A OUTPUT -i eth1 -p tcp --dport {PORT-NUMBER-HERE} -j DROP
### only drop port for given IP or Subnet ##
/sbin/iptables -A OUTPUT -i eth0 -p tcp --destination-port {PORT-NUMBER-HERE} -s {IP-ADDRESS-HERE} -j DROP
/sbin/iptables -A OUTPUT -i eth0 -p tcp --destination-port {PORT-NUMBER-HERE} -s {IP/SUBNET-HERE} -j DROP
To block outgoing port # 25, enter:
/sbin/iptables -A OUTPUT -p tcp --dport 25 -j DROP
You can block port # 1234 for IP address 192.168.1.2 only:
/sbin/iptables -A OUTPUT -p tcp -d 192.168.1.2 --dport 1234 -j DROP
/sbin/service iptables save
列出已经加入到链表的记录
iptables -L -n
iptables -L -n -v
iptables -L mychain-name -n -v
iptables -L -t nat
将列出的的记录加上序号
iptables -L INPUT -n --line-numbers
iptables -L OUTPUT -n --line-numbers
iptables -L OUTPUT -n --line-numbers | less
iptables -L mychain-name -n -v --line-numbers
iptables -L mychain-name -n -v --line-numbers | grep 202.54.1.2
应用一:记录下特定行为--Log Dropped Port Details
# Logging #
### If you would like to log dropped packets to syslog, first log it ###
/sbin/iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "PORT 80 DROP: " --log-level 7
### now drop it ###
/sbin/iptables -A INPUT -p tcp --destination-port 80 -j DROP
应用二:阻止特定ip(段)对特定端口的访问
How Do I Block Cracker (IP: 123.1.2.3) Access To UDP Port # 161?
/sbin/iptables -A INPUT -s 123.1.2.3 -i eth1 -p udp -m state --state NEW -m udp --dport 161 -j DROP
# drop students 192.168.1.0/24 subnet to port 80
/sbin/iptables -A INPUT -s 192.168.1.0/24 -i eth1 -p tcp -m state --state NEW -m tcp --dport 80 -j DROP
应用三:解除已被阻止的地址
# iptables -D INPUT -s xx.xxx.xx.xx -j DROP
# iptables -D INPUT -s ip_addr -j DROP
# service iptables save
应用四:阻止那些恶意或伪造HTTP - REFERER
统计一下相应的页面:
grep 865.html www.freeoa.net.access.log|perl -anle 'chomp($F[0]),$s{$F[0]}++;END{ for(keys %s){if($s{$_}>10) {print "$_:$s{$_}"}}}'
生成'iptable'语句,对该页面超过10次的ip进行阻止:
grep 865.html www.freeoa.net.access.log|perl -anle 'chomp($F[0]),$s{$F[0]}++;END{ for(keys %s){if($s{$_}>10) {print "/sbin/iptables -A INPUT -p tcp -s "."$_"." --dport 80 -j DROP"}}}'
阻止那些来自俄罗斯的垃圾访问
perl -anle 'chomp($F[0]),$s{$F[0]}++, if($F[10] =~ /ru\//);END{ for(keys %s){if($s{$_}>2) {print "$_:$s{$_}"}}}' www.freeoa.net.access.log
perl -anle 'chomp($F[0]),$s{$F[0]}++, if($F[10] =~ /ru\//);END{ for(keys %s){if($s{$_}>2) {print "/sbin/iptables -A INPUT -p tcp -s "."$_"." --dport 80 -j DROP"}}}' www.freeoa.net.access.log
----------------------------------------------------------------