防火墙(iptables)

2020-10-13 15:09:29 浏览数 (1)

防火墙(iptables)基于Netfilter实现,它在Linux内核中的一个软件框架,用于管理网络数据包。不仅具有网络地址转换(NAT)的功能,也具备数据包内容修改、以及数据包过滤等防火墙功能。

关于Netfilter,它在Linux内核中的一个软件框架,用于管理网络数据包。不仅具有网络地址转换(NAT)的功能,也具备数据包内容修改、以及数据包过滤等防火墙功能。1990年代,Netfilter在Linux 2.3.15版时进入Linux内核。(http://www.netfilter.org/)

在很多云厂商以腾讯云为例,类似的产品如腾讯云的clb(负载均衡)、安全组和应用防火墙功能 ,开源产品的Nginx(负载均衡,应用层转发)和lvs 这些都可以通过Linux下的防火墙来实现或者也可以说这些产品的原型就是Netfilter的iptables。

整理介绍目录

防火墙的备份与恢复

在玩防火墙命令前建议先备份线上的规则,这是一个非常不错的习惯。

查看当前防火墙规则

代码语言:javascript复制
iptables -L -nv --line 

通过iptables-save “>” 将当前iptables规则备份在文件中。

代码语言:javascript复制
iptables-save > iptables.2020.10.1

通过iptables-restore命令来恢复之前备份好的防火墙规则

代码语言:javascript复制
 iptables-restore < iptables.2020.10.1

防火墙进阶

防火墙基础知识

学习iptables的顺序(Tables(表) -> Chains (链)-> Rules(规则))

表与链

防火墙(iptables) 分为常用的表和链,先介绍三张表分别为:

  • filter 过滤数据
  • nat 转发数据
  • mangle 数据包打标记

根据每张表的不同常用的链如下:

  • INPUT 用于匹配进入的数据包
  • OUTPUT 用于匹配出的数据包
  • FORWARD 用于匹配转发的数据包
  • PREROUTING 用于匹配NAT之前的数据包
  • POSTROUTING 用于匹配NAT之后的数据包

数据生命周期流程图

具体每张表对应链使用的场景可以见以下数据转发生命周期的流程图。

防火墙(iptables)语法

基本的使用如 iptables -t [接表] -A(操作命令) [接链] { [参数] | [匹配规则] | [扩展匹配] | [内部打标签] } -j [动作] ,具体的案例

代码语言:javascript复制
iptables -t filter -A INPUT -p tcp --dport 80  -j ACCEPT

防火墙中最长使用的表就是filter表,所以在操作filter表时可以省略执行-t filter ,最终精简效果如下

代码语言:javascript复制
iptables -A INPUT -p tcp --dport 80-j ACCEPT

Filter表

Filter表主要用户数据包的过滤。典型应用为腾讯云的安全组。

操作命令

-A {-C | -D} , -A (append) 追加一条规则到防火墙中; -C (check) 检测一条规则是否存在 ;-D 删除一条规则

代码语言:javascript复制
# 追加一条规则到防火墙中
iptables -t filter -A INPUT  -j DROP 
# 删除一条已经存在的防火墙规则
iptables -t filter -D INPUT 1 (规则id,可以通过iptalbes -L -nv --line 查到)
# 确认当前规则是否存在
iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
echo $? 
1
iptables -A INPUT -p tcp --dport 8080 --jump ACCEPT
iptables -C INPUT -p tcp --dport 8080 --jump ACCEPT
echo $? 
0

-I 插入规则

代码语言:javascript复制
iptables -t filter -I INPUT 1 (插入序号)

-R 替换规则

-P 设置链的目标规则

-F 清空规则

代码语言:javascript复制
# 清空INPUT链规则
iptables -t filter -F INPUT
# 清空OUTPUT链的规则
iptables -t filter -F OUIPUT

-E 修改链名

代码语言:javascript复制
iptables -E 源表名  新表名

-L 显示所有规则 ,通常接(-nv --line)

-Z 清空计数器

代码语言:javascript复制
iptables -Z INPUT 

执行后以下的计数器请零

-N 创建一个自定义链

代码语言:javascript复制
iptables -N 自定义链名

-X 删除自定义链

代码语言:javascript复制
iptables -X 自定义链名

参数

  • -p 接协议 udp、tcp、icmp
  • -s 接源地址IP或IP段
  • -d 接目的地址IP或IP段
  • -i 进数据的网卡,如eth0
  • -o 出数据的网卡,如eht0

扩展匹配

  • --dport 通常与-p连用,-p后可以接--dport ,但没有-p 参数无法使用--dpport参数
  • --sport 通dport相同
  • --tcp-flag 如 SYN, ACK, FIN, RST
  • --mac-source 匹配硬件地址
  • --limit 可赋的值有'/second', '/minute', '/hour', or '/day'这样的单位,默认是3/hour
  • --limit-burst number 匹配最大值
  • --multiport 可以将多个规则转为一个规则

owner

  • --uid-owner uid 通常用于OUPUT表出数据的uid控制
  • --gid-owner gid 通常用于OUTPUT表出数据的gid控制
  • --sid-owner seessionid  通常用于OUTPUT表数出数据的会话控制

状态防火墙

--state state 可能的状态是:INVALID表示包是未知连接,ESTABLISHED表示是双向传送的连接,NEW 表示包为新的连接,否则是非双向传送的,而RELATED表示包由新连接开始,但是和一个已存在的连接在一起,如FTP数据传送,或者一个ICMP错误。

IP数据包打标签

--tos tos 这个参数可以是一个标准名称,(用iptables -m tos -h 察看该列表),或者数值

iptables设置tos其实就是IP包中的这个tos字段。

日志记录

  • --log-level level 
  • --log-prefix prefix 
  • --log-tcp-sequence 
  • --log-tcp-options 

内部打标签

--set-mark mark 通常用于mangle表

Fileter表综合演示

案例1

允许本服务器的80、443和22对外提供访问,同时支持icmp协议

代码语言:javascript复制
iptables -t filter -A INPUT  -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT  -p tcp --dport 443 -j ACCEPT
iptables -t filter -A INPUT  -p tcp --dport 22 -j ACCEPT
iptables -t filter -A INPUT  -p icmp  -j ACCEPT
iptables -t filter -A INPUT  -j DROP

升级一下规则:

  • 22端口只准许202.106.184.183这个服务器访问
  • 支持本地回环访问
  • 将80和443规则合并为1条提高效率
  • 支持状态防火墙
代码语言:javascript复制
iptables -F 
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A INPUT  -p tcp -m multiport --dport 80,443 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -t filter -A INPUT  -p -s 202.106.184.183 tcp --dport 22 -j ACCEPT
iptables -t filter -A INPUT  -p icmp  -j ACCEPT
iptables -t filter -A INPUT  -j DROP

关于状态防火墙的补充,以下为host1 来访问host2 ,在host2数据进入防火墙前可以看到数据的状态。

案例2

1.准许某个网段访问

代码语言:javascript复制
iptables -A OUTPUT -p tcp -d 192.168.100.0/24 --dport 22 -j ACCEPT

2.禁止icmp协议

代码语言:javascript复制
iptables -A INPUT  -p icmp -j DROP

3. 如果你的网络中有两块网卡分别为eth0和eht1 ,可以限制指定网卡访问的IP

代码语言:javascript复制
iptables -A INPUT -i eth0 -s xxx.xxx.xxx.xxx -j DROP

4.很多网络攻击都会尝试用黑客自定义的非法数据包进行尝试,我们可以使用如下命令来丢弃无效数据包:

代码语言:javascript复制
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

5. 清理INPUT链规则

代码语言:javascript复制
iptables -A INPUT -F

6. 端口转发,将80端口数据包转发到8989端口上

代码语言:javascript复制
iptables -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8989

7. 对ping本服务器的icmp报进行限制

代码语言:javascript复制
ping 106.53.60.21  -l 100  -c 100
iptables -A INPUT -p icmp -m limit --limit 5/sec --limit-burst 5 -j ACCEPT
iptables -A INPUT -p icmp -j DROP 

每秒钟5个包,最高5个包以下为测试数据结果

8.防止syn flood 攻击

代码语言:javascript复制
# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT

NAT表

NAT为转发数据表。典型应用为腾讯云的clb或开源产品的lvs。以下为相关链的数据流向:

  • 入站顺序:PREROUTING→INPUT
  • 出站顺序:OUTPUT→POSTROUTING
  • 转发顺序:PREROUTING→FORWARD→POSTROUTING

综合演示

案例1

以腾讯云为例,经常有网友会问:

  • 腾讯云的海外园区MySQL未提供公网功能,我怎么通过公网连接内网的MySQL
  • 腾讯云的Redis默认端口为6379,如何更改?

其实这两个问题都可以通过本机的iptables Nat功能来实现,以第一个疑问为例。 用户可以购买一个cvm通过cvm的公网IP NAT后连接到内网的私有网络MySQL IP(测试可以,线上不建议这样操作) ,以下为操作过程:

代码语言:javascript复制
# 临时
echo 1 > /proc/sys/net/ipv4/ip_forward

# 永久
vi /etc/sysctl.conf
net.ipv4.ip_forward=1

# 清空转发表规则
iptables -t filter -A FORWARD -F

# 172.16.16.18 为主机公网对应的内网IP, 172.16.32.10 为内网MySQL的IP
iptables -t nat -A PREROUTING -d 172.16.16.18 -p tcp --dport 7788 
-j DNAT --to-destination 172.16.32.10:3306

# 反过来写
iptables -t nat -A POSTROUTING -d 172.16.32.10 -p tcp --dport 3306 
-j SNAT --to-source 172.16.16.18

Managle表

主要用于对数据包打标签

案例1

通过以下方式可以对指定协议和端口的方式对IP数据包打TOS标签,并通过路由器对数据进行限速处理。

代码语言:javascript复制
iptables -A PREROUTING -t mangle -p tcp --dport telnet -j TOS --set-tos Minimize-Delay
iptables -A PREROUTING -t mangle -p tcp --dport ftp -j TOS --set-tos Minimize-Delay
iptables -A PREROUTING -t mangle -p tcp --dport ftp-data -j TOS --set-tos Maximize-Throughput

案例2

通过ttl来伪装服务器。当黑客在攻击你的服务器前首先要判断服务器的操作系统,判断操作系统最简单方式就是通过ttl,以下通过iptables来改变ttl值,以实现伪装的目的。

代码语言:javascript复制
iptables -t mangle -A POSTROUTING  -j TTL --ttl-set 128

Linux系统返回ttl值为64 , Windowsttls值返回为128 。

综合案例

通过iproute2与iptables做负载均衡 (待扩展)

https://blog.csdn.net/weixin_33775572/article/details/85128552

iptables tc 流量控制(待扩展)

https://blog.csdn.net/snrnjhna/article/details/49908339

本文参考内容

https://www.cnblogs.com/jodyccf/p/12449091.html

https://zhidao.baidu.com/question/1799436930425315507.html

0 人点赞