iptables的基础学习
1、前言
在早期的 Linux 系统中,默认使用的是 iptables 配置防火墙。尽管新型 的 firewalld 防火墙已经被投入使用多年,但是大量的企业在生产环境中依然出于各种原因而继续使用 iptables。
iptables服务会把配置好的防火墙策略交由内核层面的netfilter网络过滤器来处理,而firewalld服务则是把配置好的防火墙策略交由内核层面的nftables包过滤框架来处理。
2、iptables 简介
什么是iptables?
iptables 是 Linux 防火墙工作在用户空间的管理工具,是 netfilter/iptablesIP 信息包过滤系统是一部分,用来设置、维护和检查 Linux 内核的 IP 数据包过滤规则。
iptables:基于命令行的防火墙策略管理工具
iptables属于OSI七层模型中数据链路层的服务,可以根据流量的源地址、目的地址、传输协议、服务类型等信息进行匹配,一旦匹配成功,iptables就会根据策略规则所预设的动作来处理这些流量。
iptables服务的概念
其实在这里我们可能已经见过了,在tplink、H3C、华为等带有web界面的路由器中,防火墙的菜单中就有两个选项“拒绝和允许”,有些浏览器是“放行或阻止”,运营商把他称之为“动作”,在这里我们也可以理解成动作。
ACCEPT(允许流量通过)
REJECT(拒绝流量通过)
DROP(拒绝流量通过)
LOG(记录日志信息)
红帽考式中必须用REJECT进行柜绝,明确上判分脚本得到反应才有分值。而L作中更多建议用DROP进行拒绝,对隐藏服务器运行状态有好处.
iptables特点
iptables是基于内核的防火墙,功能非常强大;iptables 内置了filter,nat和mangle三张表。所有规则配置后,立即生效,不需要重启服务。
iptables 组成
iptables的结构是由表(tables)组成,而tables是由链组成,链又是由具体的规则组成。因此我们在编写iptables规则时,要先指定表,再指定链。tables的作用是区分不同功能的规则,并且存储这些规则。
注意:raw表:用于处理异常,包括的规则链有:prerouting,output;一般使用不到。
总体说来,iptables是由“三表五链”组成。
三张表介绍
- filter:负责过滤数据包,包括的规则链有:input,output和forward
- nat:用于网络地址转换(IP、端口),包括的规则链有:prerouting,postrouting 和 output
- mangle:主要应用在修改数据包、流量整形、给数据包打标识
优先级:mangle > nat > filter
五条链的介绍
iptables服务把用于处理或过滤流量的策略条目称之为规则,多条规则可以组成一个规则链,而规则链则依据数据包处理位置的不同进行了分类
默认的规则链有:INPUT,OUTPUT、 forward,POSTROUTING,PREROUTING
- input:匹配目标IP是本机的数据包
- output:出口数据包,一般不在此链上做配置
- forward:匹配流经本机的数据包
- prerouting:修改目的地址,用来做 DNAT 。如:把内网中的 80 端口映射到互联网端口
- postrouting:修改源地址,用来做 SNAT。如:局域网共享一个公网IP接入Internet。
3、策略与规则链
防火墙会按照从上到下的顺序来读取配置的策略规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为(即放行或阻止)。如果在读取完所有的策略规则之后没有匹配项,就去执行默认的策略。
一般而言,防火墙策略规则的设置有两种:“允许”(即放行)和“阻塞”(即阻止)。当防火墙的默认策略为拒绝时(堵),就要设置允许规则(通),否则谁都进不来;如果防火墙的默认策略为允许,就要设置拒绝规则,否则谁都能进来,防火墙也就失去了防范的作用。
4、iptables处理数据包流程
- 当一个数据包进入网卡时,它首先进入
PREROUTING
链,内核根据数据包目的IP判断是否需要转送出去。 - 如果数据包就是进入本机的,它就会沿着图向下移动,到达
INPUT
链。数据包到了INPUT
链后,任何进程都会收到它。 - 本机上运行的程序可以发送数据包,这些数据包会经过
OUTPUT
链,然后到达POSTROUTING
链输出。 - 如果数据包是要转发出去的,且内核允许转发,数据包就会如图所示向右移动,经过
FORWARD
链,然后到达 POSTROUTING 链输出。
总结:整体数据包分两类:1、发给防火墙本身的数据包 ;2、需要经过防火墙的数据包
5、iptables 安装
安装前准备
永久关闭自带的防火墙
systemctl stop firewalld #关闭自带的firewalld服务
systemctl disable firewalld #禁止firewalld开机自启动
SElinux也要关闭
安装iptables
[root@server61 ~]# yum -y install iptables-services
[root@server61 ~]# systemctl start iptables #启动iptables
[root@server61 ~]# systemctl enable iptables #设置iptables开机自启动
[root@server61 ~]# iptables -V
iptables v1.4.21
[root@server61 ~]# rpm -ql iptables-services
/etc/sysconfig/ip6tables
/etc/sysconfig/iptables #配置文件
/usr/lib/systemd/system/ip6tables.service
/usr/lib/systemd/system/iptables.service #ipv4的服务
/usr/libexec/initscripts/legacy-actions/ip6tables
/usr/libexec/initscripts/legacy-actions/ip6tables/panic
/usr/libexec/initscripts/legacy-actions/ip6tables/save
/usr/libexec/initscripts/legacy-actions/iptables
/usr/libexec/initscripts/legacy-actions/iptables/panic
/usr/libexec/initscripts/legacy-actions/iptables/save
/usr/libexec/iptables
/usr/libexec/iptables/ip6tables.init
/usr/libexec/iptables/iptables.init
[root@server61 ~]# cat /usr/lib/systemd/system/iptables.service
[Unit]
Description=IPv4 firewall with iptables
Before=network-pre.target
Wants=network-pre.target
Before=ip6tables.service
After=syslog.target
AssertPathExists=/etc/sysconfig/iptables
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/iptables/iptables.init start
ExecReload=/usr/libexec/iptables/iptables.init reload
ExecStop=/usr/libexec/iptables/iptables.init stop
Environment=BOOTUP=serial
Environment=CONSOLETYPE=serial
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=basic.target
完事之后看一下运行的状态,确保它已经运行
将防火墙相关模块加载到内核中
查看内核中是否有iptables
[root@server61 ~]# lsmod | grep filter
iptable_filter 12810 0
ip_tables 27126 1 iptable_filter
我这边是之前就安装了,所以应该是有的。在这里需要注意不是过滤iptables,而是filter
为什么要加载到内核中,不加载会怎么样?
因为它是基于内核的防火墙。不加载即使写了策略也不会生效
临时加载
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
永久加载
cat >>/etc/rc.local<<EOF
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
EOF
一般情况下执行完会自动加载的,如果没有加载执行一下
depmod -a #执行全部内核加载命令
验证是否加载到内核中
[root@server61 ~]# lsmod | egrep 'filter|nat|ipt'
ipt_REJECT 12541 0
nf_reject_ipv4 13373 1 ipt_REJECT
iptable_filter 12810 1
ip_tables 27126 1 iptable_filter
配置文件
[root@localhost ~]# ll /etc/sysconfig/iptables
-rw------- 1 root root 550 10月 2 2020 /etc/sysconfig/iptables
###默认的配置文件内容
[root@localhost ~]# vim /etc/sysconfig/iptables
# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
6、实践命令规则
Iptables [-t 表名] 管理选项 [链名] [条件匹配] [-j 目标动作或或跳转]
不指定表名时,默认表示filter表
不指定链名时,默认表示该表内所有链
除非设置规则链的缺省策略,否则需要指定匹配条件
语法帮助
iptables -h
iptables中常用的参数以及作用
参数 | 作用 |
-P | 设置默认策略 |
-F | 清空规侧链 |
-L | 查看规侧链 |
-I | 在规则链的首行加入新规则,一般拒绝的规则使用-I |
-A | 在规则链的末尾加入新规侧,一般允许的规则使用-A |
-l num | 在规则链的头部幼加入新规侧 |
-D num | 删除某条规则 |
-S | 匹配来源地址lP/MASK,加叹号"!”表示这个IP除外 |
-d | 匹配目标地址 |
-i网卡名称 | 匹配从这块网卡流入的数据 |
-0网卡名称 | 匹配从这块网卡流出的数据 |
-P | 匹配协议,如TCP、UDP、ICMP |
–dport num | 匹配目标端口号 |
–sport num | 匹配来源端口号 |
7、iptables规则的查看
[root@server61 ~]# iptables -nL
Chain INPUT (policy DROP)
target prot opt source destination
DROP icmp -- 0.0.0.0/0 0.0.0.0/0
DROP all -- !10.5.0.0/16 0.0.0.0/0
ACCEPT all -- 10.5.0.0/16 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@server61 ~]#
8、iptables常用配置
iptables配置规则其实编辑的是filter表,默认INPUT链是ACCEPT(允许通过),这种模式默认是允许所有。我把这种默认允许的叫做“黑名单模式”,有黑名单自然就有白名单模式,白名单模式,默认把INPUT链更改为DROP拒绝通过。
什么情况下使用白名单,什么情况下使用黑名单?
- 架设在公网上的安全系数要求比较高的一般大多使用白名单,内外中的一般大多使用黑名单。
- 追求稳定的使用黑名单,因为白名单比较烦,容易出问题经常会把自己隔离在外,只能跑到机房去。
- 有1个陌生的IP,5分钟访问了我几百次,那么就直接用黑名单封掉他。
- 某些场景只允许某些IP或者IP段访问,就用白名单
具体情况可以根据需求来配置。
将INPUT规则链的默认策略设置为拒绝(DROP)——白名单模式
当需要把INPUT链设置为默认拒绝时,就必须先往里面写入允许策略了,否则所有流入的数据包都会被默认拒绝掉。
注意事项:
- 配置之前需要先允许访问机器通过22端口,防止将自己隔离在外。如果隔离了只能到机房去;
- 白名单模式千万不要使用
iptables -F
清除规则,这样同样会把自己隔离在外了; - 规则链的默认策略拒绝动作只能是DROP,而不能是REJECT;
更改前
[root@localhost ~]# iptables -L
Chain INPUT (policy ACCEPT) #看到这里默认的是ACCEPT(允许流量通过),俗称黑名单模式
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
更改后
[root@xiudaochengxian ~]# iptables -P INPUT DROP
[root@localhost ~]# iptables -L
Chain INPUT (policy DROP) #更改完之后,这里变成了DROP(拒绝流量通过),俗称白名单模式
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@localhost ~]#
以下都是在白名单模式下的实例
实例1:向INPUT链中添加允许ICMP流量进入的策略规则
使用ping命令来检查对方主机是否在线,而向防火墙的INPUT规则链中添加一条允许ICMP流量进入的策略规则就默认允许了这种ping命令检测行为
[root@xiudaochengxian ~]# iptables -I INPUT -p icmp -j ACCEPT
[root@xiudaochengxian ~]# ping -c4 192.168.1.105
PING 192.168.1.105 (192.168.1.105) 56(84) bytes of data.
64 bytes from 192.168.1.105: icmp_seq=1 ttl=64 time=0.113 ms
64 bytes from 192.168.1.105: icmp_seq=2 ttl=64 time=0.099 ms
64 bytes from 192.168.1.105: icmp_seq=3 ttl=64 time=0.076 ms
64 bytes from 192.168.1.105: icmp_seip'taq=4 ttl=64 time=0.057 ms
--- 192.168.1.105 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.057/0.086/0.113/0.022 ms
实例2:将INPUT规则链设置只允许指定网段的主机访问本机22端口,拒绝来自其他所有主机的流量
22号端口是ssh服务使用的
要对某台主机进行匹配,可直接写出它的IP地址
要对网段进行匹配,需要写为子网掩码的形式(比如192.168.1.0/24)
iptables -I INPUT -s 192.168.1.105 -p tcp --dport 22 -j ACCEPT
iptables -I INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
- -I 加入新规则排在首行
- INPUT 入站流量
- -s 源地址为192.168.1.105/192.168.1.0/24
- -p 协议为tcp
- –dport 目标端口为22
- -j 动作为ACCEPT(允许流量通过)
iptables -A INPUT -p tcp --dport 22 -j REJECT
- -A 末尾加入新规则;
- -p 协议
- –dport 目标端口
- -j 匹配动作是允许还是拒绝
注意事项:一般允许是排在
#在规则链末尾加入新规则,并且规则协议是TCP,目标端口是22,动作是允许(-j ACCEPT)
[root@xiudaochengxian ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT
[root@localhost ~]# iptables-save
# Generated by iptables-save v1.4.21 on Wed Apr 27 10:11:16 2022
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [19:2140]
-A INPUT -s 10.5.0.0/32 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Wed Apr 27 10:11:16 2022
[root@localhost ~]# iptables -nvL
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 10.5.0.0 0.0.0.0/0 tcp dpt:22
859 71300 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 120 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
3 145 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
2330 273K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 64 packets, 7251 bytes)
pkts bytes target prot opt in out source destination
实例4:向INPUT规则链中添加拒绝所有主机访问主机1000到1500端口的策略规则
[root@xiudaochengxian ~]# iptables -A INPUT -p tcp --dport 1000:1500 -j REJECT
连续的端口我们可以使用冒号,注意不是:1000-1500
黑名单模式下:
实例5:服务器防ping
[root@server61 ~]# iptables -I INPUT -p icmp -j DROP
实例6:屏蔽2222和12306不连续的两个端口
[root@server61 ~]# iptables -I INPUT -p tcp --dport 2222,12306 -j DROP
iptables v1.4.21: invalid port/service `2222,12306' specified
Try `iptables -h' or 'iptables --help' for more information.
[root@server61 ~]# iptables -I INPUT -p tcp -m multiport --dport 2222,12306 -j DROP
[root@server61 ~]# iptables -nL
Chain INPUT (policy DROP)
target prot opt source destination
DROP tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 2222,12306
DROP icmp -- 0.0.0.0/0 0.0.0.0/0
DROP all -- !10.5.0.0/16 0.0.0.0/0
ACCEPT all -- 10.5.0.0/16 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
-m 是指定模块,模块可以支持我们使用不连续的多个端口