zoukankan      html  css  js  c++  java
  • iptables基础原理和使用简介

    概念简介

    名称

    Netfilter/iptables模块有两部分组成:

    Netfilter框架以及iptables,iptables又分为iptables(内核空间)和iptables命令行工具(用户空间);

    Netfilter/iptables模块 在一般使用者眼里简称为iptables,但其实在相关开发者眼里更倾向于叫作Netfilter,从项目官网地址也看得出来: https://netfilter.org/

    作用

    用于数据包处理,比如:报文的转发、过滤、修改,网络地址转换等功能,是一种软件防火墙。

    iptables基本原理

    基本工作流程

    基本工作流程图

    ​ 数据包沿着链传输,iptables有5个链:PREROUTING, INPUT, FORWORD, OUTPUT, POSTROUTING,可以想象成5个关卡,每个关卡都有很多规则,也可能没有规则。

    工作流程如下:

    1、当一个数据包进入网卡后,它会先进入PREROUTING,然后根据目的地址进行路由决策,如果目的地址是本机,则走INPUT,不是本机则走FORWARD,然后再走POSTROUTING转出去。

    2、进入INPUT的数据包会转给本地进程,进程处理后,会发送新的数据包,走OUTPUT,然后经过POSTROUTING转出去。

    3、当然上面的过程每经过一个链,都要按照链中的规则顺序来匹配链中的规则,只要遇到一个匹配的规则就按照这个规则进行处理,后面的规则对这个数据就不再起作用。

    简单的规则添加

    ​ 只有本地socket是用户态,其余都是内核处理。平时我们加iptables规则,就是加到各个链中的,我们创建一个容器进行测试,容器中我已经安装好了iptables,直接使用iptables命令即可:

    #首先启动一个容器
    [root@kube-master ~]# docker run -itd --name "cos8_test" --cap-add=NET_ADMIN centos:base /bin/bash
    bd0c29186387b01ae64514050b3b4b804babc988f3dbc52c0cfe6eeac115d1b2
    

    注:要修改容器网络,容器启动时需加上 --cap-add=NET_ADMIN,不然容器中执行iptables命令会报错:

    (nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)

    查看iptables规则,可以看到当前没有任何策略

    [root@kube-master ~]# docker ps | grep cos8
    bd0c29186387        centos:base                                                     "/bin/bash"              21 hours ago        Up 21 hours                             cos8_test
    [root@kube-master ~]# docker exec -it bd0 bash
    [root@bd0c29186387 /]#
    [root@bd0c29186387 /]# iptables -nL
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    

    创建一个规则:拒绝所有访问80端口的tcp数据包。

    [root@bd0c29186387 /]# iptables -A INPUT -p tcp --dport 80 -j DROP
    [root@bd0c29186387 /]#
    [root@bd0c29186387 /]# iptables -nL
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    

    这里有个小插曲:可以看到我只在INPUT链中添加了规则,但是怎么FORWARD和OUTPUT链中也有这条规则,随后我手动删了INPUT链中的规则,然后FORWARD和OUTPUT链中的规则也随之消失了,此容器的OS版本和内核信息如下

    [root@bd0c29186387 /]# cat /etc/redhat-release
    CentOS Linux release 8.2.2004 (Core)
    [root@bd0c29186387 /]#
    [root@bd0c29186387 /]# uname -a
    Linux bd0c29186387 3.10.0-1127.13.1.el7.x86_64 #1 SMP Tue Jun 23 15:46:38 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
    

    之前没用过centos8,考虑到可能是OS更新了netfilter模块,于是换成了一个centos7.8.2003的容器测试了一下,发现添加规则是符合预期的,如下

    [root@kube-master /]# docker run -itd --name "cos7" --cap-add=NET_ADMIN centos7:base /bin/bash
    c951c0a9d34d8e43a56e43872294ab5ab6a1504b365721238178de134e8d3bde
    [root@kube-master /]#
    [root@kube-master /]# docker exec -it cos7 bash
    [root@c951c0a9d34d /]#
    [root@c951c0a9d34d /]# iptables -nL
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    [root@c951c0a9d34d /]#
    [root@c951c0a9d34d /]# iptables -A INPUT -p tcp --dport 80 -j DROP
    [root@c951c0a9d34d /]#
    [root@c951c0a9d34d /]# iptables -nL
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    DROP       tcp  --  0.0.0.0/0            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
    

    拒绝可以使用DROP,也可以使用REJECT关键字,DROP不会给客户端返回任何信息,所以客户端看到的情况就是连接超时,很难判断是防火墙原因还是网络设备故障等原因。

    而REJECT则明确返回给客户端一个拒绝的信息,客户端会知道我是被防火墙拒绝了。

    可根据场景使用,REJECT更适合调试,DROP抗攻击上面更安全些。

    后面使用centos7的容器作为测试,先不管centos8更新了啥。

    四表五链

    上面我添加的规则命令如下:

    iptables -A INPUT -p tcp --dport 80 -j DROP
    

    但这只是简写后的,稍微写全些如下,其实还可以更全些,暂不说明。

    iptables -t filter -A INPUT -s 0.0.0.0/0 -p tcp -d 0.0.0.0/0 --dport 80 -j DROP
    

    -t : 指定表,这里是filter表,规则会添加到filter表中。

    -s : 指定源地址,0.0.0.0/0是指所有IP。

    -d : 指定目的地址。

    --dport : 指定目的端口。

    -j : 指定处理动作,这里是DROP,也就是丢弃。

    表的概念

    上面提到了filter表,那什么是表呢?

    ​ 我们加规则,加到每个链中,每个链中的规则有很多,有一部分规则是相似的,比如,有一部分都是端口的过滤,有一部分都是报文的修改,根据这些规则的类型,把相似的规则放在一起,这些放在一起的规则的集合称为表。

    ​ 那不同的规则的集合就放在了不同的表中,总共有4种表,也就是4种规则:

    filter表:负责过滤功能;

    nat表:network address translation,网络地址转换功能;

    mangle表:拆解、修改、并重新封装报文;

    raw表:关闭nat表上启用的连接追踪机制;

    因为每个链中都有不同规则,所以表存在于每一个链中,但不是每个链都有这4种表,

    PREROUTING 的规则可以存在于:raw表,mangle表,nat表。

    INPUT 的规则可以存在于:mangle表,filter表,nat表(centos7中有nat表,centos6中没有)。

    FORWARD 的规则可以存在于:mangle表,filter表。

    OUTPUT 的规则可以存在于:raw表mangle表,nat表,filter表。

    POSTROUTING 的规则可以存在于:mangle表,nat表。

    表的处理优先级如下:

    raw --> mangle --> nat --> filter

    所以我们一开始iptables的基本工作流程图可以更详细些

    其实还可以再详细些,我们单独拿一个链出来,比如PREROUTING链,大概是如下情况,这些规则组和在了一起便成了一条链。

    ​ 所以,我们上面加的禁止访问本机80端口的规则是存放在filter表中的,我们来查看下filter表中的规则,可以看到我们添加的规则,netfilter默认把80端口绑定为http。

    [root@c951c0a9d34d /]# iptables -L -t filter
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    DROP       tcp  --  anywhere             anywhere             tcp dpt:http
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    

    iptables常用命令举例

    查看规则

    按表查看: iptables -L -t table
    按照链查看: iptables -nL INPUT
    

    设置链的默认规则

    #INPUT链默认拒绝所有数据包
    iptables -P INPUT DROP
    #OUTPUT默认允许所有数据包出去
    iptables -P INPUT ACCEPT
    

    清空表中的规则

    #清空nat表中PREROUTING链的规则
    iptables -t nat -F PREROUTING
    #清空filter表中所有链的规则
    iptables -t filter -F
    #清空使用者自定义的表规则
    iptables -X
    

    删除某一条规则

    #可以通过编号来删除
    #--line-number在规则前面显示了编号
    [root@c951c0a9d34d /]# iptables -nL --line-number
    Chain INPUT (policy ACCEPT)
    num  target     prot opt source               destination
    1    DROP       tcp  --  0.0.0.0/0            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@c951c0a9d34d /]#
    [root@c951c0a9d34d /]# iptables -D INPUT 1
    
    #也可以直接删除规则
    #下面命令中,-D后面的全是匹配条件,凡是某条规则中包含下面所有的匹配项,就删除这条规则
    [root@c951c0a9d34d /]# iptables -D INPUT -p tcp --dport 80 -j DROP
    

    禁ping

    #禁止别人ping自己,但是自己可以ping别人
    #type 8: 表示ping包请求流量
    #type 0: 表示ping包响应流量
    iptables -A INPUT -p icmp --icmp-type 0 -j DROP
    iptables -A OUTPUT -p icmp --icmp-type 8 -j DROP
    
    #禁止别人ping自己,也禁止自己ping别人
    iptables -A INPUT -p icmp -m icmp --icmp-type any -j DROP
    
    #也可以改参数实现禁ping
    echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
    

    转发

    #开启转发功能
    echo 1 > /proc/sys/net/ipv4/ip_forward
    
    #对于外部访问自己80端口的流量全部转到172.17.0.4的80端口,
    #xxx.xxx.xxx.xx代表本机的IP
    iptables -t nat -I PREROUTING -d xxx.xxx.xxx.xx -p tcp --dport 80 -j DNAT --to-destination 172.17.0.4:80
    
    #对于从本机出去的流量,源ip全部转换为172.17.0.4
    iptables -t nat -A POSTROUTING -p tcp -j SNAT --to-source 172.17.0.4
    

    针对链接状态作规则

    #NEW 用户发起一个全新的请求
    #ESTABLISHED 对一个全新的请求进行回应
    #RELATED 两个完整连接之间的相互关系,一个完整的连接,需要依赖于另一个完整的连接。
    #INVALID 无法识别的状态。
    iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
    

    先这些吧。

    原文作者:大鹏SP
    版权声明:本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可,转载请标明作者及原文链接。
  • 相关阅读:
    antd table表单再次进入清空搜索框的内容
    antd 4.x Form表单getFieldValue获取内容和清空内容
    antd select下拉添加全选的按钮
    antd 日期组件显示中文
    ie和谷歌浏览器自定义修改滚动条颜色
    canvas实现图片js在图片上添加文字和二维码
    every,some,filter,map数组方法区别
    小程序安装npm包
    safri overflow:hidden;失效
    弹框显示时阻止浏览器滚动行为
  • 原文地址:https://www.cnblogs.com/sunpong/p/13931676.html
Copyright © 2011-2022 走看看