iptables防火墙本身是不防火的,是靠其中的规则判断数据是丢弃还是放行,而这些规则就存放在iptables的四表五链中。
iptables四表五链
四表
filter(过滤数据包):INPUT,OUTPUT,FORWARD
nat(地址转换):PREROUTING,POSTOUTING,OUTPUT
mangle表(拆开,修改,封装数据):五个链全部包含
raw(状态追踪):PREROUTING,OUTPUT
五链(根据数据报文的流向,判断报文放在那里)
INPUT:到本机内部来的数据
OUTPUT:本机出去的数据
FORWARD:转发的数据
PREROUTING:刚刚到达本机,还没有路由的
POSTROUTING:马上发出本机的,还没有做路由
还可以使用自定义链,但只在被调用时才能发挥作用,而且如果没有自定义链中的任何规则匹配,还应该有返回机制,自定义链只有为空时才可以被删除,默认链无法删除。
优先次序:
prerouting:raw高于mangle高于nat
input:mangle高于filter
output:raw高于mangle高于nat高于filter
forward:mangle高于filter
postrouting:mangle高于nat
如果在一个位置有多条规则,那么匹配的数据是自上而下生效,如果上面有允许规则,就算是下面有拒绝,那么处理数据包是允许通过
推荐规则顺序:
1.如果规则有关联性:范围小的规则放到上面,范围大的规则放到下面
比如,允许192.168.1.1访问但是拒绝192.168.1.0访问,那么这个时候就需要把192.168.1.1这条规则放到上面
2.如果规则没有关联性:范围大的规则放到上面,范围小的规则放到下面
比如,同时允许192.168.1.0和172.16.0.0网段访问,那么就需要把172.16.0.0这条规则放到最上面
3.访问最频繁的规则放到最上面
比如这台服务器提供web和FTP服务,如果web的访问量大过FTP服务,那么把web的规则放到最上面,FTP放到下面;如果FTP的规则在上面的话,那么数据包到达服务器的时候,会先和FTP的规则做比较,然后在和web做比较这样就浪费了时间。
iptables 语法:
iptables 表名 管理选项 链名 匹配条件 -j 控制条件
命令:管理命令
管理规则:
-A:在链的尾部添加一条规则,如果不写表,默认是filter表
-I 链 [行号]:插入一条规则,插入为对应链上的指定行,如果省略了行,那么为第一条。
-D 链 [行号]:删除指定链中的指定规则。
-R 链 [行号]:替换指定的规则。
管理链:
-F 链:清空指定规则链,如果省略链,则可以实现删除对应表中的所有链。
-P 链:设置指定链的默认策略。
-N:自定义一个新的空链。
-X:删除一个自定义的空链(链比如为空,如果不为空使用-F清空)
-Z:置零指定链中所有规则的计数器。
-E:重命名自定义的链。
查看类:
-L:显示指定表中的所有规则。默认显示的规则和主机,是以协议和主机名出现,如果没有配置dns,查看的速度会非常的慢。
-n:以数字形式显示端口和主机名
-v:显示链及规则的详细信息
-vv:显示更加详细
-x:显示计数器的精确值
--line-numbers:显示规则号码
匹配条件:
通用匹配:
-s:源地址
-d:目的地址
-p:协议{tcp|udp|icmp}
-i:数据报文流入的接口
-o:数据报文流出的接口
扩展匹配:
隐含扩展:
-p tcp :可以使用特定协议拥有的属性扩展
--sport:源端口
--dport:目标端口
--tcp-flags:只检查mask指定的标志位,是逗号分隔的标志位列表:comp:此列表中出现的标记必须为1,comp中没出现,而mask中出现的,必须为0;
--tcp-flags SYN,FIN,ACK,RST SYN,ACK
--syn:三次握手的第一次
第一次握手:SYN=1,ACK=0,FIN=0,RST=0;
第二次握手:SYN=1,ACK=1,FIN=0,RST=0;
第三次握手:SYN=0,ACK=1,RST=0,FIN=0;(连接建立完成)
-p icmp
--icmp-type{0|8|3}
0:回应报文,响应自己ping请求
8:请求报文,自己发出的ping请求
3:目标不可达
-p udp:
--sport:源端口
--dport:目标端口
显式扩展:使用额外的匹配机制
-m EXTESTION --sep-opt
start:状态连接
结合ip_conntrack追踪会话的状态
NEW:新连接请求
ESTABLISHED:已建立的连接
INVALID:非法连接(如:SYN=1,FIN=1)
RELATED:相关联的(命令连接和数据连接)
例如:-m state --state ESTABLISHED -j ACCEPT (放行数据包状态ESTABLISHED,也就是说只要通过三次握手建立连接的数据全部放行)
nultiport:离散的多端口匹配扩展
--source-ports
--destination-ports
--ports
例如:-m multiport --destination-port 21,22,80 -j ACCEPT 合并三个端口
-m iprange 匹配一段Ip地址范围
--src-range
--dst-range
-s ip,new
匹配一组ip地址192.168.0.100-192.168.0.105
[root@localhost ~]# iptables -A INPUT -p tcp -m iprange --src-range 192.168.0.100-192.168.0.105 --dport 22 -j ACCEPT
-m connlimit:连接数限制
! --connlimit-above n (一般情况下必须加叹号,加叹号表示如果连接数不到n咋办)
设置每人访问web服务器只能有两个连接数,(生产环境根据实际需求)
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p tcp --dport 80 -m connlimit --connlimit-above 2 -j ACCEPT
-m limit 设置
--limit 设置指定时间内允许多少个连接
--limit-burst 设置第一次允许有多少连接同时进来
-m string
--alog {bm|kmp} bm算法和kmp算法功能一样
--string "匹配字符"
拒绝访问的网页连接中出现h7n9连接名的文件,但是不会检查文件内容
[root@localhost ~]# iptables -I INPUT -d 192.168.0.108 -m string --algo kmp --string "***" -j REJECT
拒绝页面内容中出现h7n9,在出站链接做设置不允许页面文件中带有h7n9字样
[root@localhost ~]# iptables -I OUTPUT -s 192.168.0.108 -m string --algo kmp --string "h7n9" -j REJECT
几乎每一个条件都支持!取反
执行的动作:
ACCEPR:允许数据包通过
DROP:拒绝数据包通过,直接丢弃数据包
REJECT:拒绝数据包通过,并且告诉发送端,此路不通
DNAT:目标地址转换
SNAT:源地址转换
REDIRECT:端口重定向
MASQUERADE:地址伪装,源地址转换
LOG:记录日志的
KARK:加标记
使用:
如果服务器是一台web服务器,需要设置允许访问web的流量出站和入站,允许ssh远程连接。然后设置默认策略为阻止,这样本机的只能由管理员远程连接和进出web流量。提高了安全性。
[root@localhost ~]# iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.108 -p tcp --dport 22 -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -s 192.168.0.108 -d 192.168.0.0/24 -p tcp --dport 22 -j ACCEPT
[root@localhost ~]# iptables -P INPUT DROP
[root@localhost ~]# iptables -P OUTPUT DROP
[root@localhost ~]# iptables -P FORWARD DROP
[root@localhost ~]# iptables -I INPUT -d 192.168.0.108 -p tcp --dport 80 -j ACCEPT
[root@localhost ~]# iptables -I OUTPUT -s 192.168.0.108 -p tcp --sport 80 -j ACCEPT
访问web服务器,这个时候查看iptables的策略,就可以看到http和ssh都有流量通过,说明策略设置成功
[root@localhost ~]# iptables -L -n -vv
Chain INPUT (policy DROP 12 packets, 1062 bytes)
pkts bytes target prot opt in out source destination
67 7776 ACCEPT tcp -- * * 0.0.0.0/0 192.168.0.108 tcp dpt:80
857 56588 ACCEPT tcp -- * * 192.168.0.0/24 192.168.0.108 tcp dpt:22
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
76 29960 ACCEPT tcp -- * * 192.168.0.108 0.0.0.0/0 tcp spt:80
412 40288 ACCEPT tcp -- * * 192.168.0.108 192.168.0.0/24 tcp spt:22
由于只允许ssh和web,这个时候自己ping自己也是不同的,如果希望自己可以ping自己
[root@localhost ~]# iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -o lo -j ACCEPT
允许自己ping别人,但是不允许别人ping自己
[root@localhost ~]# iptables -A INPUT -s 192.168.0.108 -p icmp --icmp-type 8 -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -d 192.168.0.108 -p icmp --icmp-type 0 -j ACCEPT
允许新的连接和已建立的链接通信,不允许自己对别人新建立连接
ssh:
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -s 192.168.0.108 -p tcp --sport 22 -m state --state ESTABLISHE -j ACCEPT
web
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -s 192.168.0.108 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
如果把第一条规则设置成已建立的连接运行通过,那么就会提高查询规则的效率,比如ssh连接之后还会有数据报文通过,但是再次匹配规则的时候就会被第一条规则匹配到,不再往下查询,从而提高了效率,一条规则顶了上面的两条规则。
[root@localhost ~]# iptables -I OUTPUT -s 192.168.0.108 -m state --state ESTABLISHED -j ACCEPT
设置ftp允许出站,由于ftp的数据连接端口是随机的所以需要使用RELATED将管理连接和数据连接关联起来
首先要装载ip_conntrack_ftp和ip_nat_ftp模块
[root@localhost ~]# vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="ip_nat_ftp ip_conntrack_ftp"
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -s 192.168.0.108 -m state --state RELATED,ESTABLISHED -j ACCEPT
速率限定
设置每分钟只允许5个ping请求可以进来,设置完成后如果客户端再去ping就会发现一会通一会不通了
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p icmp --icmp-type 8 -m limit --limit 5/minute -j ACCEPT
设置第一次可以有四个连接进来(--limit-burst),后面进来的就是每分钟5个连接(--limit)
[root@localhost ~]# iptables -R INPUT 3 -d 192.168.0.108 -p icmp --icmp-type 8 -m limit --limit 5/minute --limit-burst 4 -j ACCEPT
记录ping日志,记录日志最好设置为几分钟记录一条,不然会产生磁盘io导致性能下降
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p icmp --icmp-type 8 -j LOG --log-prefix "--iptables log for icmp--"
查看日志
[root@localhost ~]# tail /var/log/messages
Nov 10 12:36:55 localhost kernel: --iptables log for icmp--IN=eth0 OUT= MAC=00:0c:29:a2:0b:db:34:23:87:fc:ae:89:08:00 SRC=192.168.0.101 DST=192.168.0.108 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=30851 PROTO=ICMP TYPE=8 CODE=0 ID=256 SEQ=4199
主机型防火墙推荐设置
如果服务器开放了http和ftp而且有需要远程管理。那么可以这样设置,第一条规则允许ESTABLISHED(响应请求或已建立连接)和RELATED(与已有连接相关联性)的数据出站,第二条则是设置允许新连接连接服务器的21,22,80端口。出站设置ESTABLISHED和RELATED。默认策略全部为DROP。这样就提高了查询效率
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@localhost ~]# iptables -A INPUT -d 192.168.0.108 -p tcp -m multiport --destination-ports 21,22,80 -m state --state NEW -j ACCEPT
[root@localhost ~]# iptables -A OUTPUT -s 192.168.0.108 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables NAT设置
基本语法
DNAT:目标地址转换(PREROUTING)
-j DNAT
--to-destination 指定目标地址
SNAT:源地址转换(POSTROUTING)
-j SNAT
--to-source 指定的源地址
--to-source 192.168.1.1-192.168.1.4 可以指定多个源地址
-j MASQUERADS 动态获取上网地址是使用
环境拓扑
设置内网用户通过SNAT防火互联网
开启防火墙的路由功能
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@localhost ~]# sysctl -w net.ipv4.ip_forward=1
设置之前需要先设置默认策略和主机策略
[root@localhost ~]# iptables -P INPUT DROP
[root@localhost ~]# iptables -P OUTPUT DROP
设置已经建立的连接和于已建立连接有关联性的数据入站
root@localhost ~]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
设置地址转换,将内网地址转换为公网地址
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 1.1.1.1
设置允许内网所有访问内网的流量出去,外网和内网流量已建立连接和有关联性的进来的进来。
[root@localhost ~]# iptables -A FORWARD -d 192.168.1.0/24 -i eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@localhost ~]# iptables -A FORWARD -s 192.168.1.0/24 -o eth1 -j ACCEPT
发布web服务器使公网用户能够访问
[root@localhost ~]# iptables -t nat -A PREROUTING -i eth1 -d 1.1.1.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2
设置允许转发80端口的流量
[root@localhost ~]# iptables -A FORWARD -d 192.168.1.2 -p tcp --dport 80 -j ACCEPT
[root@localhost ~]# iptables -A FORWARD -s 192.168.1.2 -p tcp --sport 80 -j ACCEPT