网络协议与iptables实战:建立强固的网络防线

Introduction

  • iptablesLinux 系统一个工具集。通过它我们可以配置、管理网络流量规则。值得注意的是这里包括入站流量、出战流量。

  • iptables 保障了系统的安全性,给过滤流量以及网络地址转换制定了规则.

  • iptables 主要存在以下几个概念:

    • Table(表) : Filter, NAT, Mangle, Raw ;默认 Filter 也是我们常用的防火墙设置
    • Chains(链路): 链是数据包匹配的规则列表。常见的链包括 Input(用于传入的数据包)、Output(用于传出的数据包)和 Forward(用于经过系统路由的数据包)。
    • Rules(规则): 规则用于定义数据包在链中的处理方式。规则由一组条件和一个关联的操作组成,这些操作可以是 Accept、Drop 或 Reject
    • Target(目标动作):目标是当规则匹配时可以采取的行动。常见的目标包括 Accept(允许一个数据包),Drop(丢弃一个数据包)和 Reject(拒绝一个数据包并发送错误消息)。
  • iptables 的命令格式如下

shell 复制代码
iptables [ -t 表名] [COMMAND] [链名] [条件匹配] [-j 目标动作或跳转] 

TABLE

  • Table 分为四类: Filter、Nat、Mangle、RawTable 的加载顺序: Raw>Mangle>Nat>Filter
  • 我的个人理解是 TABLE 就是功能场景,我们使用 iptables 最常用的场景就是 Filter,用来对端口的出入站进行控制。

  • 其中 TABLE 对应 iptables 中命令的 -t 参数 , 默认情况下 -t 可以不填,不填的话默认就是 -t Filter.

COMMAND

  • Command 就是告诉 iptables 接下来需要做什么? 比如告诉 iptables 新增一条规则 or 删除一条规则过滤功能。
  • source destination 分别对应的是 -s-d 两个参数,这里我们可以设置 IP 地址也可以设置网络地址 192.168.0.135192.168.0.135/24
  • 我们可以通过 -s 设置指定 IP 范围。

CHAINS

  • Chains 在每个 Table 下的概念,主要归纳为

    • PREROUTING : 数据包进入路由表之前
    • INPUT : 本机入站流量
    • OUTPUT : 本机出站流量
    • FORWARD: 将数据转发到本机的其他网卡设备上
    • POSTROUTING : 数据包离开路由表之后,或者进入网卡之前。
  • 其中中间三条 INPUTOUTPUTFORWARD 三个在 Filter 中使用最频繁,而我们常规的 iptables 只有 INPUT 使用最频繁的。

  • 上面介绍的四种表中并不是每个都有五条链的。下面介绍下每张表分别有哪些链条(四表五链)。

Table Chains
Filter INPUT 、 OUTPUT 、 FORWARD
Nat PREROUTING 、INPUT 、OUTPUT 、FORWARD、POSTROUTING
Mangle PREROUTING 、INPUT 、 OUTPUT 、 FORWARD
Raw PREROUTING 、OUTPUT

RULES

  • 其中最主要的就是规则。每次进出站都是通过匹配规则执行相应动作的。
shell 复制代码
sudo iptables -I INPUT -p tcp -m multiport --dport 80,443,1883,3306,5432,8700,8743,8080,8848,18080,8999,3000 -j ACCEPT
  • 上面的命令就是针对所有的入站针对指定的多个端口进行放行。其中的规则就是 -p 。这里是针对协议。除了针对协议 以外还有如下配置:
匹配参数 说明
-p 指定规则协议,如 tcp, udp,icmp 等,可以使用 all 来指定所有协议
-s 指定数据包的源地址参数,可以使 IP 地址、网络地址(子网掩码方式)、主机名
-d 指定目的地址(同-s)
-i 输入接口 , 网卡设置
-o 输出接口 , 网卡设置
-m 扩展字段

什么叫扩展条件?

  • 还是看上面我们的命令,除了 -p 这个条件指定的是 tcp 模式,我们还注意到 -m 就是我们提到的扩展条件。意思就是有了 -m 我们就可以使用二级条件,比如后面紧跟的 --dport 。因为在 -m 一级条件中已经指明了 multiport 所以在二级命令中我们添加了多个端口。这样就避免我们多次添加端口过滤了。
命令 作用 显示
tcp --sport : 源端口;--dport : 目标端口; --tcp-flags: TCP 握手阶段拦截,SYN,ACK,RST 等; --syn :第一次握手 NO
udp --sport : 源端口;--dport : 目标端口;
icmp 8 : 输出请求。; 0 : 输出响应
state 用于连接状态的检测;NEW , ESTABLISHED, RELATED ,INVALID .
multiport --dport : 多个目标端口; --sport : 多个目标源端口; --ports : 多个源&目端口
limit --limit : 速率,如--limit 3 表示 1 分钟不超过 3 个数据包;--limit-burst : 峰值
connlimit --connlimt-above n : 连接数超过 n
iprange --src-range 192.168.0.100-192.168.0.200 : 源 IP 范围; --dst-range 类似
mac --mac-source mac 地址限制
string --algo [bm kmp] 匹配算法; --string pattern : 正则匹配 //TODO 不明白
recent 用不上
markdown 复制代码
                                                                         |                                                 |   |

JUMP

  • jump 对应的是我们命令模式中的 -j,也可以叫做 Target ,这个在 iptables -L n 中能够体现。 主要就是三个动作 ACCEPT DROP REJECT ` 。
Jump Description
ACCEPT 允许数据包通过。
DROP 直接丢弃数据包,不给出任何回应信息。
REJECT 拒绝数据包通过,必须时会给数据发送端一个响应信息。
LOG 在/var/log/messages 文件中记录日志信息,然后将数据包传递给下一条规则。
QUEUE 防火墙将数据包移交到用户空间
RETURN 防火墙停止执行当前链中的后续 Rules,并返回到调用链(the calling chain)

Common Command

  • iptables -A: 添加一个规则
  • iptables -D: 删除一个规则.
  • iptables -L: 查看 Chains 中的规则列表 : iptables -L INPUT. ;在每个 Chain 的最后还会输出默认策略是啥,这里对应 iptables -P
  • iptables -F: 清空 Chains 中所有规则.
  • iptables -P: 给 Chains 设置默认策略 (e.g., ACCEPT or DROP).
  • service iptables saveiptables-save > /etc/sysconfig/iptables: 保存当前 iptables 规则,以便在系统重启时自动加载。
shell 复制代码
iptables -A INPUT -p tcp --dport 1000:2000 -j ACCEPT  # 1000~2000 端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT  # 80
iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 443
  • 指定位置添加 : `iptables -I INPUT 2 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

  • 允许远程连接: iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

Brief Summary

FILTER

  • 上面大段的介绍全都是基于 Filter 表展开的。所以这里我们直接跳过吧。

NAT

  • Network Address Translation 网络地址转换。
  • 我们大部分使用它来流量代理转换,类似于 nginx 一样。

Scene

  • 实现 A 服务器流量转发到 B 服务器上。
    • 192.168.0.135:80
    • 192.168.0.190:81
  • 针对上面两个服务端口实现,135 上的 80 端口流量全部转发到 190 上的 81 端口。

Prefix Conditions

  • 首先我们得开启内核支持。临时开启的话只需要保证 /proc/sys/net/ipv4/ip_forward 文件内容为 1
  • 如果是永久生效的话,我们得保证 /etc/sysctl.conf 中存在 net.ipv4.ip_forward=1 配置。
    • echo 1 > /proc/sys/net/ipv4/ip_forward
    • echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
    • 上述无误后我们重启即可。systemctl restart network
  • 最终我们查看下配置是否支持转发sysctl net.ipv4.ip_forward

Operation

shell 复制代码
iptables -t nat -A PREROUTING -d 192.168.0.135/32 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.190:81;
iptables -t nat -A POSTROUTING -d 192.168.0.190/32 -p tcp --dport 81 -j SNAT --to-source 192.168.0.135;
  • 最后我们验证下 telnet 192.168.0.135 8700 会看到信息展示 190 的信息。具体我就不展示了,因为没有实际操作。

MANGLE

  • Mangle 的主要功能是修改数据包。
  • 假设上面是我们内部的网络拓扑图,我们内网有台代理服务器作为网关存在 Proxy. 在这台服务上存在三个网口分别是 enth0: 内网、enth1:美国、enth2:韩国。

  • 这也就意味着 Proxy 这台服务器可以同时连接美国和韩国的网络的同时还存在一组内网。

Scene

  • 现在在内网的一台设备 Client 想要实现所有通过内网访问的 80 端口都映射到美国网络中,而所以通过 UDP 协议访问的 53 端口全部走韩国路线。

Operation

  • 这就需要我们针对不同的协议端口进行打标签,从而才能区分出来该如何进行路由。而打标签就是我们 iptables Mangle 表来实现修改数据包功能。
shell 复制代码
iptables -t mangle -A PREROUTING -i enth0 -p tcp --dport 80 -j MARK --set- mark 1
iptables -t mangle -A PREROUTING -i enth0 -p udp --dport 53 -j MARK --set- mark 2
  • 上面的配置就会在进路由分发之前给两个端口协议打上 mark 标签。动态路由就涉及到 ip ruleip route 的知识,这里就直接贴代码
shell 复制代码
ip rule add from all fwmark 1 table 10
ip rule add from all fwmark 2 table 20
  • 可以看出只要是 mark=1 的就会走 route=10 的路由策略。
shell 复制代码
ip route add default via 10.0.20.21 dev enth1 table 10
ip route add default via 10.0.20.22 dev enth1 table 20

FQA

开放端口后依然无法访问问题

  • --reject-with icmp-host-prohibited . 不难发现在上述的防火墙列表上存在 icmp-host-prohibited . ICMP (Internet Control Message Protocol) .这个是拒绝连接的提示信息。对应的错误信息提示 code 应该是 Host Prohibited.
shell 复制代码
iptables -A INPUT -p tcp --dport 80 -j REJECT --reject-with icmp-host-prohibited
  • 如上我们添加 80 端口拒绝连接并做出响应的提示,值得注意的是给出提示其实也是信息不安全的,所以如果我们想绝对的安全那就直接将 Reject 换成 Drop 模式。
相关推荐
伯牙碎琴19 分钟前
十一、SOA(SOA的具体设计模式)
架构
小黑爱编程24 分钟前
【LInux】HTTPS是如何实现安全传输的
linux·安全·https
BeyondESH29 分钟前
Linux线程同步—竞态条件和互斥锁(C语言)
linux·服务器·c++
wn53130 分钟前
【Go - 类型断言】
服务器·开发语言·后端·golang
鱼饼6号1 小时前
Prometheus 上手指南
linux·运维·centos·prometheus
Asher Gu1 小时前
Linux系统编程入门 | 模拟实现 ls -l 命令
linux
希冀1231 小时前
【操作系统】1.2操作系统的发展与分类
后端
c无序1 小时前
【Linux进程控制】进程程序替换
linux
GoppViper1 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
爱上语文2 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring