Skip to main content

Iptables使用

centos iptables

通过iptables防火墙,用户可对与Linux系统进行交互的IP数据包执行高度的控制,而且这一控制是在Linux内核中实现。iptables策略是由一组有序的规则建立,它告诉内核应如何处理某些类别的数据包。iptables规则应用于一个表中的一个链,一个iptables链是一个规则集,这些规则按顺序与包含共同特征的数据包进行比较。

iptables基础介绍

表是iptables构建块,描述了其功能的大类,如包过滤或者网络地址转换(NAT)。iptables中共有四个表:filternatmangleraw,过滤规则应用于filter表,NAT规则应用于nat表。

每个表都有自己的一组内置链,对我们来说,最重要的内置链是filter表中的INPUTOUTPUTFORWARD链:

  • INPUT:当流入的数据包指向本地主机时,将经过INPUT链的检查。
  • OUTPUTOUTPUT链用于本地主机自身生成的数据包。
  • FORWARDFORWARD链管理经过Linux系统路由的数据包。

另外两个很重要的链是nat表中的PREROUTINGPOSTROUTING链,分别用于IP路由之前和之后修改数据包的头部。

下图展示了数据包是如何通过natfilter表的不同链:

iptables

由图可知,为了实现对Linux服务器的访问进行控制,主要就是针对filter表的INPUT链进行配置管理。

规则匹配

每个iptables规则都包含一组匹配以及一个目标,后者告诉iptables对于符合规则的数据包应该采取什么动作。常见的匹配规则如下:

  • --source (-s) :匹配源IP地址或者网络
  • --destination (-d):匹配目标IP地址或者网络
  • --destination port (-dport): 匹配目标地址的端口号
  • --protocol (-p):匹配协议
  • --in-interface (-i):流入接口(例如:eth0
  • --out-interface (-o):流出接口
  • --state:匹配一组连接状态
  • --string:匹配应用层数据字节序列

目标

最后,iptables支持一组目标,用于在数据包匹配一个规则时触发一个动作。

  • ACCEPT:允许数据包通过
  • DROP:丢弃数据包
  • LOG:将数据包信息记录到syslog
  • REJECT:丢弃数据包,同时发送适当的响应报文
  • RETURN:在调用链中继续处理数据包

在CentOS7中使用

CentOS7中默认使用的防火墙是firewalld,为了使用iptables,需要先禁用firewalld

禁用firewalld

首先停止firewalld服务:

$ sudo systemctl stop firewalld

然后禁止firewalld服务开机自启动:

$ sudo systemctl disable firewalld

为了防止firewalld服务被其他服务再次启动:

$ sudo systemctl mask --now firewalld

安装iptables

先检查是否已经安装了iptables

$ sudo systemctl status iptables

确认没有安装后通过包管理器进行安装:

$ sudo yum install iptables-services

安装成功后启动服务:

$ sudo systemctl start iptables

设置开机自启动:

$ sudo systemctl enable iptables

查看服务运行状态:

$ sudo systemctl status iptables
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; enabled; vendor preset: disabled)
Active: active (exited) since Thu 2019-12-19 13:31:35 CST; 1min 30s ago
Main PID: 2966 (code=exited, status=0/SUCCESS)

出现以上信息,则表明服务运行正常。接下来可查看当前的iptables默认规则:

$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
113 6860 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 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
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
0 0 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 66 packets, 6232 bytes)
pkts bytes target prot opt in out source destination

定义过滤规则

定义规则的命令格式如下:

$ sudo iptables -t <table> -A <chain> -i <interface> -p <protocol (tcp/udp) > -s <source> --dport <port no.>  -j <target>

参数说明可参考上文中的操作选项归纳说明,这里的-t指定需定义规则的表,默认为filter

开启HTTP(端口80)SSH(端口22)SSL(443)三个服务

$ sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

规则添加后查看如下:

$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
69 4580 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443

结果表明,所有访问8022443端口的TCP请求都被允许。

根据源IP地址限制访问

例如允许IP192.168.1.3访问本机:

$ sudo iptables -A INPUT -s 192.168.1.3 -j ACCEPT

也可以通过DROP目标限制某一IP地址访问:

$ sudo iptables -A INPUT -s 192.168.1.3 -j DROP

如果需要限制源地址为IP段,可通过掩码设定:

$ sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT

丢弃所有其他访问请求

定义好允许访问的规则之后,通常需要将其他未授权的访问请求都禁止掉,以达到访问控制的目的:

$ sudo iptables -A INPUT -j DROP

也可以通过定义整个INPUT链的策略来限制未授权的访问:

$ sudo iptables -P INPUT DROP

如果是远程修改iptables规则,在限制全局访问时,一定要先开启远程连接的端口,比如SSH(端口22),否则容易造成远程连接中断。

删除规则

如果要删除所有规则,可使用-F选项(flush):

$ sudo iptables -F

如果需要删除其中某一条规则,首先要查看所有规则的编号:

$ sudo iptables -nvL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 306 18777 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
2 8 563 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
3 9 611 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
4 45 2532 DROP all -- * * 0.0.0.0/0 0.0.0.0/0

在每条规则的开头就是编号,比如删除编号为3的规则:

$ sudo iptables -D INPUT 3

规则保存

之前对iptables规则的操作都是保存在内存中,如果系统重启,所有的操作都会丢失,因此在修改规则完成后,需要对其进行保存。

$ sudo service iptables save

典型设置脚本示例

#!/bin/sh
# 先允许所有
iptables -P INPUT ACCEPT
#清空所有默认规则
iptables -F
#清空所有自定义规则
iptables -X
#所有计数器归0
iptables -Z
#允许来自于lo接口的数据包(本地访问)
iptables -A INPUT -i lo -j ACCEPT
#开放22端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#开放21端口(FTP)
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
#开放80端口(HTTP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
#开放443端口(HTTPS)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
#允许ping
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
#其他入站一律丢弃
iptables -P INPUT DROP
#所有出站一律绿灯
iptables -P OUTPUT ACCEPT
#所有转发一律丢弃
iptables -P FORWARD DROP
#保存上述规则
service iptables save
#重启服务
systemctl restart iptables

iptables操作选项归纳说明

查看选项

简写选项说明
-L--list chain rulenum列出所有链及规则,默认表为filter
-n--numericIP地址和端口显示为数字
-v--verbose显示详细信息
--line-numbers显示规则编号

链操作选项

简写选项说明
-A--append chain rule向链添加规则
-D--delete chain rulenum通过编号删除规则
-I--insert chain rulenum插入规则,默认编号为1
-R--replace chain rulenum替换规则,默认编号为1
-F--flush chain删除指定链所有规则,如未指定,则删除所有链规则
-P--policy chain target修改链政策

规则选项

简写选项说明
-p--proto proto协议。{tcp, udp, udplite, icmp, esp, ah, sctp}等
-s--source address/mask源IP地址
-d--destination address/mask目的IP地址

目标选项

简写选项说明
-j--jump target调整到目标

通用选项

简写选项说明
-t--table table指定表,默认为filter
-V--version查看版本

补充

CentOS 7配置完后发现无法使用YUM包管理器,需添加如下规则:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

如下:

Chain INPUT (policy DROP 58 packets, 6674 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
1309 109K ACCEPT tcp -- * * 10.42.6.0/24 0.0.0.0/0 tcp dpt:22
167 17907 ACCEPT tcp -- * * 10.0.0.0/8 0.0.0.0/0 tcp dpt:80
15809 27M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED