学习iptables之前,我们需要先了解防火墙是什么呢?iptables又是如何发挥作用的呢?
一.防火墙基础知识
1.1 防火墙是什么?
firewall:对进出系统的数据进行过滤,符合要求的数据,可以放行也可以不放行,也就是对进出的数据进行限制
防火墙主要是对数据包进行分析,包括:帧、IP包、tcp/udp、协议(icmp、arp、http等)
一般情况下,防火墙是不能捕获应用层的包的,但是可以通过打补丁的方式来限制应用层的包
防火墙在计算机网络中类似于一个保安,允许何种数据进出,但是它并不能够防止病毒
防火墙的位置:
- 公司入口:路由器
- 重要的服务器集群前面放一个防火墙
- 服务器上也可以启用防火墙
防火墙过多的坏处?
- 成本过高
- 会导致数据延迟(网络的速度会比较慢)
1.2 iptables基础知识
iptables是一个软件,是用户用来传递参数的,它是用户端的程序,实现给内核传递参数。
真正起到防火墙作用的并不是iptables这个软件,而是内核中的netfilter模块。
也就是说,防火墙中的包过滤机制是netfilter模块,管理工具是iptables
内核:是操作系统内部最核心的软件 —>内核在内存里运行,也是一个软件对应的进程
内核负责的事情非常多,所以内核里面分了很多的模块来实现对应的功能。其中netfilter模块是对网络数据进行过滤,对tcp/ip协议的支持
回顾一下内核的作用有哪些?
1.CPU管理—>CPU
2.进程的管理,例如创建一个进程,杀死一个进程,运行进程等
3.内存的管理,例如给哪个进程分配内存空间,回收内存空间等–>内存memory
4.文件系统的管理,例如创建文件,删除文件等—>disk磁盘
5.网络的管理 —>防火墙,netfilter模块—>网卡
6.其他硬件的管理
1.3 netfilter和iptables的关系:
iptables和netfilter的关系:
user输入参数给iptables,iptables相当于一个中间人,再传递给netfilter
Linux中iptables和netfilter的具体存放位置:
[root@xieshan ~]# cd /lib/modules/3.10.0-957.el7.x86_64/kernel/net/netfilter/ #内核的具体位置
[root@xieshan netfilter]# ls
[root@xieshan /]# vim /sbin/iptables #iptables的具体位置
1.4 新型防火墙工具:firewalld
iptables是一个比较老式的防火墙工具,而firewalld是一个比较新式的防火墙工具,需要注意,这两者本质上都还是防火墙管理工具,都还是用来给netfilter传参的
firewalld底层原理还是使用了iptables规则,但是加入了很多新的概念(zone、DMZ),类似于Windows里的防火墙
firewalld的默认规则都是拒绝,而iptables默认规则是允许,这就意味着firewalld需要在每个服务器上设置了才能放行
firewalld与iptables的更多差别可以查看这两篇博客:
firewalld和iptables的具体比较
firewalld和iptables的具体比较
[root@xieshan ~]# service firewalld stop #背后就是清除所有的iptables规则
Redirecting to /bin/systemctl stop firewalld.service
二.iptables的四表五链
学习四表五链之前,我们先看一张图片:
正如图片中写的,我们可以将五个链路比喻成三国中的五个角色,这样,四表五链的学习会简单很多。
有了这张图的比喻,接下来我们再正式学习四表五链:
2.1 规则表
规则表:
具有某一类相似用途的防火墙规则,按照不同处理时机区分到不同的规则链以后,被归置到不同的“表”中
规则表是规则链的集合
默认的4个规则表
raw表:确定是否对该数据包进行状态跟踪 --》新连接还是就的连接产生的数据
mangle表:为数据包设置标记 --》往数据包插入标志
nat表:修改数据包中的源、目标IP地址或端口 --》snat和dnat相关
filter表:确定是否放行该数据包(过滤) --》进入应用程序相关
规则表间的优先顺序:raw、mangle、nat、filter(iptables默认的表就是filter表)
2.2 规则链
规则链:
规则的作用在于对数据包进行过滤或处理,根据处理时机的不同,各种规则被组织在不同的“链”中
规则链是防火墙规则/策略的集合
默认的5种规则链
INPUT:处理入站数据包
OUTPUT:处理出站数据包
FORWARD:处理转发数据包
POSTROUTING链:在进行路由选择后处理数据包
PREROUTING链:在进行路由选择前处理数据包
规则–》规则链–》表
各种规则组成了规则链,各种规则链组成了规则表
规则链间的匹配顺序:
入站数据:PREROUTING、INPUT
出站数据:OUTPUT、POSTROUTING
转发数据:PREROUTING、FORWARD、POSTROUTING
规则链内的匹配顺序:
按顺序依次进行检查,找到相匹配的规则即停止(LOG策略会有例外)
若在该链内找不到相匹配的规则,则按该链的默认策略处理
一般我们是在INPUT链和PREROUTING链中设置规则,如果防火墙的范围比较广,就在PREROUTING前面拦住,如果范围比较小就是在INPUT前面
2.3 规则表和规则链之间的关系
这张图片告诉我们不同的规则表中包含哪些链:
如果你不能很好的记住这张表中规则表与规则链的关系,也没事,在Linux中,我们可以通过命令来查看不同的表中包含哪些链:
[root@xieshan /]# iptables -t raw -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@xieshan /]# iptables -t mangle -L
[root@xieshan /]# iptables -t nat -L
[root@xieshan /]# iptables -t filter -L #通过这条命令可以查看表里面有哪些链
2.4 数据报的过滤匹配流程:
2.5 小练习
写一个脚本,对于INPUT链,设定以下规则:
1.允许任何人ping
2.允许192.168.2.102访问服务器80、22端口
3.默认规则设置为DROP
[root@xieshan shell-test]# vim iptables.sh
#!/bin/bash
iptables -F #清除filter里的所有的链的规则 ,不指定表就是filter表
iptables -t nat -F
#允许icmp协议通过
iptables -t filter -A INPUT -p icmp -j ACCEPT
#开放80端口给192.168.2.108主机
iptables -A INPUT -p tcp --dport 80 -s 192.168.2.108 -j ACCEPT
#开放22端口给192.168.2.108主机
iptables -A INPUT -p tcp --dport 22 -s 192.168.2.108 -j ACCEPT
#设置filter表的INPUT链默认策策略为DROP
iptables -P INPUT DROP #如果是脚本,默认规则链放在前面和后面都无所谓;如果是一条一条的敲的话,要放在后面
[root@xieshan shell-test]# bash iptables.sh
[root@xieshan shell-test]# iptables -t filter -L -n
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
三. iptables的语法
3.1 iptables命令的语法格式
iptables命令的语法格式:
iptables [-t 表名] 管理选项 [链名] [条件匹配] [-j 目标动作或跳转]
几个注意事项:
不指定表名时,默认表示filter表
不指定链名时,默认表示该表内的所有链
除非设置规则链的缺省策略,否则需要指定匹配策略
3.2 iptables的选项
接下来,我们来看一些iptables的使用举例:
[root@xieshan ~]# iptables -t filter -L -v -n --line #指定filter内的所有链,-L查看所有规则,-v展示详细信息,-n以数字方式显示ip地址和端口号,不进行域名解析,--line显示行号
Chain INPUT (policy DROP 6 packets, 2478 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
2 0 0 ACCEPT tcp -- * * 192.168.2.102 0.0.0.0/0 tcp dpt:80
3 11 828 ACCEPT tcp -- * * 192.168.2.102 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 7 packets, 784 bytes)
num pkts bytes target prot opt in out source destination
[root@xieshan shell-test]# iptables -P INPUT ACCEPT #设置filter表的INPUT链的默认规则为ACCEPT
[root@xieshan shell-test]# iptables -L #查看filter表的INPUT链的所有规则
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT icmp -- anywhere anywhere
ACCEPT tcp -- 192.168.2.102 anywhere tcp dpt:http
ACCEPT tcp -- 192.168.2.102 anywhere tcp dpt:ssh
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@xieshan shell-test]# iptables -A INPUT -s 192.168.2.43 -p tcp --dport 80 -j ACCEPT #在filter表的INPUT链末尾增加一条规则,规则内容是:允许源IP是192.168.2.43的访问服务器的80端口
[root@xieshan shell-test]# iptables -L -n #查看filter表的INPUT链的所有规则,并且以数字形式显示,不进行域名解析
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 192.168.2.43 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@xieshan shell-test]# iptables -I INPUT -s 192.168.2.33 -p tcp --dport 80 -j ACCEPT #在filter表的INPUT链首部增加一条规则,规则内容是:允许源IP是192.168.2.33的访问服务器的80端口
[root@xieshan shell-test]# iptables -L -n #查看filter表的INPUT链的所有规则,并且以数字形式显示,不进行域名解析
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.2.33 0.0.0.0/0 tcp dpt:80
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 192.168.2.43 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@xieshan shell-test]# iptables -I INPUT 3 -s 192.168.2.34 -p tcp --dport 80 -j ACCEPT #在filter表的INPUT链路上的第三条规则前面增加一条规则,规则内容是:允许源IP是192.168.2.34的访问服务器的80端口
[root@xieshan shell-test]# iptables -L -n --line #查看filter表的INPUT链的所有规则,并且以数字形式显示,不进行域名解析,并且显示行号
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 192.168.2.33 0.0.0.0/0 tcp dpt:80
2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
3 ACCEPT tcp -- 192.168.2.34 0.0.0.0/0 tcp dpt:80
4 ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
5 ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
6 ACCEPT tcp -- 192.168.2.43 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
[root@xieshan shell-test]# iptables -D INPUT 2 #单独删除INPUT链的第二条规则
[root@xieshan shell-test]# iptables -L -n --line
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 192.168.2.33 0.0.0.0/0 tcp dpt:80
2 ACCEPT tcp -- 192.168.2.34 0.0.0.0/0 tcp dpt:80
3 ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
4 ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
5 ACCEPT tcp -- 192.168.2.43 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
自定义链:
[root@xieshan shell-test]# iptables -N sc #新增一条链sc,放在filter表内
[root@xieshan shell-test]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.2.33 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.34 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 192.168.2.43 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain sc (0 references) #新增的链
target prot opt source destination
[root@xieshan shell-test]# iptables -A sc -p tcp --dport 80 -j ACCEPT #在sc链中新增一条规则
[root@xieshan shell-test]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.2.33 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.34 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 192.168.2.43 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain sc (0 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
[root@xieshan shell-test]# iptables -I INPUT -p tcp --dport 80 -j sc #拜在某条链的下面,做它安排的事
[root@xieshan shell-test]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
sc tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.33 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.34 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:80
ACCEPT tcp -- 192.168.2.102 0.0.0.0/0 tcp dpt:22
ACCEPT tcp -- 192.168.2.43 0.0.0.0/0 tcp dpt:80
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain sc (1 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
3.3 设置数据包的条件
通用条件匹配:
隐含条件匹配:
#从ens33口进来,打算跟3306数据库端口建立新的连接的IP,都拒绝(长选项放在短选项后面)
[root@xieshan shell-test]# iptables -I INPUT -i ens33 -p tcp --tcp-flags SYN,RST,ACK SYN --dport 3306 -j REJECT #指定tcp的标志位的SYN为1
[root@xieshan ~]# iptables -I INPUT -p icmp --icmp-type 8 -j REJECT #让别人ping不通自己(8是request包)
[root@xieshan ~]# ping 192.168.2.43
PING 192.168.2.43 (192.168.2.43) 56(84) bytes of data.
From 192.168.2.43 icmp_seq=1 Destination Port Unreachable
From 192.168.2.43 icmp_seq=2 Destination Port Unreachable
From 192.168.2.43 icmp_seq=3 Destination Port Unreachable
#注意区分Host Unreachable和Port Unreachable(host是对方IP地址未使用)
显式条件匹配:
[root@xieshan ~]# iptables -A FORWARD -m mac --mac-source 00:0c:29:27:55:3F -j DROP
[root@xieshan ~]# iptables -A INPUT -p tcp --m multiport --dport 20,21,25,110,1250:1280 -j ACCEPT
[root@xieshan ~]# iptables -A FORWARD -p tcp --m iprange --src-range 192.168.1.20-192.168.1.99 -j DROP
3.4 常见的数据包处理方式
数据包(-j后面的)处理方式:
ACCEPT:放行数据包
DROP:丢弃数据包
REJECT:拒绝数据包,给一个回复
LOG:记录日志信息,并传递给下一条规则处理 --》相当于抓包
用户自定义链名:传递给自定义链内的规则进行处理
SNAT:修改数据包的源地址信息
DNAT:修改数据包的目标地址信息
MASQUERADE: 实现snat功能,不需要经常换公网ip地址
LOG日志,相当于抓包
[root@xieshan ~]# iptables -A INPUT -p tcp --dport 22 -j LOG --log-level 6
记到哪里去?
/var/log/messages
谁会帮我们记录日志?
service rsyslogd 帮助我们记录日志
kernel nerfilter对数据过滤,会把日志告诉rsyslogd,让它记录日志–>kernel将日志记录功能外包给了rsyslog
[root@xieshan ~]# ps aux|grep rsyslogd #linux里真的有rsyslogd这个进程
root 3829 0.0 0.5 220776 5924 ? Ssl 7月27 0:10 /usr/sbin/rsyslogd -n
root 10588 0.0 0.0 112828 988 pts/1 S+ 09:52 0:00 grep --color=auto rsyslogd
Linux系统里专门记录日志的服务:rsyslog
[root@xieshan ~]# vim /etc/rsyslog.conf
*.info;mail.none;authpriv.none;cron.none /var/log/messages
cron.info 记录cron类型的日志的info以上级别的信息,包括info
[root@xieshan ~]# tail -f /var/log/messages #可以查看到日志信息
日志的设备类型:
1.kernel kern.info 内核产生的info以上级别的日志 kern.* 表示所有的kern类型的日志级别
2.authpriv --> ssh远程登录,需要输入用户名和密码
3.cron -->计划任务
4.mail
5.local1~local7 都是自定义的类型
日志的级别:(数字越小优先级越高)
7 debug
6 info
5 notice
4 warning
3 error
2 critical
1 alert
0 emergency
3.5 将iptables规则设置为开机自启的方式
[root@xieshan ~]# iptables-save >/lianxi/iptables.reles #保存iptables里的规则到指定目录下
[root@xieshan ~]# iptables -F #清除当前所有的规则
[root@xieshan ~]# iptables-restore < /lianxi/iptables.reles #从制定目录下的文件里重新加载规则
[root@xieshan ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 flags:0x16/0x02
LOG tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 LOG flags 0 level 4
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@xieshan ~]# vim /etc/rc.local #修改开机就会执行的文件/etc/rc.local,设置为开机加载规则
[root@xieshan ~]# cat /etc/rc.local
!/bin/bash
THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
It is highly advisable to create own systemd services or udev rules
to run scripts during boot instead of using this file.
In contrast to previous versions due to parallel execution during boot
this script will NOT be run after all other services.
Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
that this script will be executed during boot.
touch /var/lock/subsys/local
/usr/local/sclilin99/sbin/nginx
iptables-restore < /lianxi/iptables.rules #设置开机加载规则
3.6 iptables里的加载模块
[root@xieshan ~]# lsmod #查看内核里加载了哪些模块
[root@xieshan ~]# /sbin/depmod -a
[root@xieshan ~]# /sbin/modprobe ip_nat_ftp #新增ftp功能模块
[root@xieshan ~]# lsmod|grep ftp
nf_nat_ftp 12770 0
nf_conntrack_ftp 18638 1 nf_nat_ftp
nf_nat 26787 1 nf_nat_ftp
nf_conntrack 133095 3 nf_nat_ftp,nf_nat,nf_conntrack_ftp
[root@xieshan ~]# /sbin/modprobe -r ip_nat_ftp #卸载ftp功能模块
[root@xieshan ~]# lsmod|grep ftp
3.7 练习
题目:编写一个 sc_iptables_rule.sh脚本
1.搭建一台linux服务器,开启ssh和MySQL和nginx服务
2.使用防火墙iptables规则,允许192.168.0.*(你的windows机器)访问sshd服务,允许192.168.2.12~192.168.2.100这个ip地址段主机访问本机的8080端口
3.允许192.168.2.13和192.168.2.14访问mysql服务(3306端口)
4.web服务所有的人都可以访问
5.允许ping服务器
6.其他的端口都不允许访问
7.记录所有ping本机的信息到日志文件
8.保证开机自动使用这个脚本里的规则
[root@nginx-kafka01 lianxi]# vim /lianxi/sc_iptables_rule.sh
[root@nginx-kafka01 lianxi]# cat /lianxi/sc_iptables_rule.sh
#!bin/bash
#允许本机访问sshd服务
iptables -I INPUT -s 192.168.2.133 -p tcp --dport 22 -j ACCEPT
#允许ip地址段访问本机8080端口
iptables -I INPUT -m iprange --src-range 192.168.2.12-192.168.2.100 -p tcp --dport 8080 -j ACCEPT
#允许访问指定两台机器访问mysql服务
iptables -I INPUT -s 192.168.2.13 -p tcp --dport 3306 -j ACCEPT
iptables -I INPUT -s 192.168.2.14 -p tcp --dport 3306 -j ACCEPT
#80端口允许所有人访问
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
#运行所有人ping服务器
iptables -I INPUT -p icmp --icmp-type 8 -j ACCEPT
#将ping本机的信息记录到日志文件
iptables -I INPUT -p icmp --icmp-type 8 -j LOG
#设置默认规则为DROP
iptables -P INPUT DROP
3.8 SNAT、DNAT、iptables的综合实验
实验架构图:
在当路由器的那台机器上执行以下脚本:
这个实验跟我们之前SNAT、DNAT的实验有些相同之处,可以在回顾一下NAT的知识:09.计算机网络—网络层/NAT- SNAT- DNAT/跳板机-堡垒机-中控机