侧边栏壁纸
  • 累计撰写 25 篇文章
  • 累计创建 26 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Linux使用技能之iptables

Yttrium
2022-02-06 / 0 评论 / 0 点赞 / 245 阅读 / 0 字

什么是iptables

@Wikipedia https://zh.wikipedia.org/wiki/Iptables iptables
iptables是运行在用户空间的应用软件,通过控制Linux内核netfilter模块,来管理网络数据包的处理和转发。在大部分Linux发行版中,可以通过手册页或 man iptables 获取用户手册。通常iptables需要内核模块支持才能运行,此处相应的内核模块通常是Xtables。因此,iptables操作需要超级用户权限 。同时,需要说明的是,以上命令通常只用于处理 IPv4 数据包;而对于 IPv6 数据包,则使用类似的 ip6tables 命令。

目前,iptables 支持内核2.4以上版本,旧版内核环境下则使用ipchains(于2.2版内核)或 ipwadm(于2.0版内核)完成类似的功能。2014年1月19日起发行的Linux内核3.13版则使用nftables取而代之,但仍然提供 iptables 命令做为兼容接口。

规则

iptables、ip6tables等都使用Xtables框架。存在“表(tables)”、“链(chain)”和“规则(rules)”三个层面。

每个“表”指的是不同类型的数据包处理流程,如filter表表示进行数据包过滤。每个表中又可以存在多个“链”,系统按照预订的规则将数据包通过某个内建链,例如将从本机发出的数据通过OUTPUT链。在“链”中可以存在若干“规则”,这些规则会被逐一进行匹配,如果匹配,可以执行相应的动作,如修改数据包,或者跳转。跳转可以直接接受该数据包或拒绝该数据包,也可以跳转到其他链继续进行匹配,或者从当前链返回调用者链。当链中所有规则都执行完仍然没有跳转时,将根据该链的默认策略(“policy”)执行对应动作;如果也没有默认动作,则是返回调用者链。

filter表

filter表是默认的表,如果不指明表则使用此表。其通常用于过滤数据包。其中的内建链包括:

  • INPUT,输入链。发往本机的数据包通过此链。
  • OUTPUT,输出链。从本机发出的数据包通过此链。
  • FORWARD,转发链。本机转发的数据包通过此链。

nat表

nat表如其名,用于地址转换操作。其中的内建链包括:

  • PREROUTING,路由前链,在处理路由规则前通过此链,通常用于目的地址转换(DNAT)。
  • POSTROUTING,路由后链,完成路由规则后通过此链,通常用于源地址转换(SNAT)。
  • OUTPUT,输出链,类似PREROUTING,但是处理本机发出的数据包。

mangle表

mangle表用于处理数据包。其和nat表的主要区别在于,nat表侧重连接而mangle表侧重每一个数据包。其中内建链列表如下。

  • PREROUTING
  • OUTPUT
  • FORWARD
  • INPUT
  • POSTROUTING

raw表

raw表用于处理异常,有如下两个内建链:

  • PREROUTING
  • OUTPUT

模块

state

对于state模块的连接而言,”连接”其中的报文可以分为5种状态,报文状态可以为NEW、ESTABLISHED、RELATED、INVALID、UNTRACKED
含义大致与conntrack相同

conntrack

包的状态依据IP所包含的协议不同而不同,但在内核外部,也就是用户空间里,只有4种状态: NEWESTABLISHEDRELATEDINVALID 。它们主要是和状态匹配一起使用。下面就简要地介绍以下这几种状态:

表1: 数据包在用户空间的状态

| State | Comment |
| :----: | :----: |
| NEW | NEW说明这个包是我们看到的第一个包。意思就是,这是conntrack模块看到的某个连接第一个包,它即将被匹配了。比如,我们看到一个SYN 包,是我们所留意的连接的第一个包,就要匹配它。第一个包也可能不是SYN包,但它仍会被认为是NEW状态。这样做有时会导致一些问题,但对某些情况是有非常大的帮助的。例如,在我们想恢复某条从其他的防火墙丢失的连接时,或者某个连接已经超时,但实际上并未关闭时. |
| ESTABLISHED | ESTABLISHED已经注意到两个方向上的数据传输,而且会继续匹配这个连接的包。处于ESTABLISHED状态的连接是非常容易理解的。只要发送并接到应答,连接就是ESTABLISHED的了。一个连接要从NEW变为ESTABLISHED, 只需要接到应答包即可,不管这个包是发往防火墙的,还是要由防火墙转发的 。ICMP的错误和重定向等信息包也被看作是ESTABLISHED,只要它们是我们所发出的信息的应答. |
| RELATED | RELATED是个比较麻烦的状态。当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的了。换句话说,一个连接要想是RELATED的, 首先要有一个ESTABLISHED的连接。这个ESTABLISHED连接再产生一个主连接之外的连接 ,这个新的连接就是RELATED的了,当然前提是conntrack模块要能理解RELATED。ftp是个很好的例子,FTP-data 连接就是和FTP-control有RELATED的。还有其他的例子,比如,通过IRC的DCC连接。有了这个状态,ICMP应答、FTP传输、DCC等才能穿过防火墙正常工作。注意,大部分还有一些UDP协议都依赖这个机制。这些协议是很复杂的,它们把连接信息放在数据包里,并且要求这些信息能被正确理解 |
| INVALID | INVALID说明 数据包不能被识别属于哪个连接或没有任何状态 。有几个原因可以产生这种情况,比如, 内存溢出 , 收到不知属于哪个连接的ICMP错误信息 。一般地,我们DROP这个状态的任何东西|

这些状态可以一起使用,以便匹配数据包。这可以使防火墙非常强壮和有效。以前,我们经常打开1024以上的所有端口来放行应答的数据。现在,有了状态机制,就不需再这样了。可以只开放那些有应答数据的端口,其他的都可以关闭。这样就安全多了

命令使用

参数表

root@hostname:~# iptables --help
iptables v1.8.4

Usage: iptables -[ACD] chain rule-specification [options]
       iptables -I chain [rulenum] rule-specification [options]
       iptables -R chain rulenum rule-specification [options]
       iptables -D chain rulenum [options]
       iptables -[LS] [chain [rulenum]] [options]
       iptables -[FZ] [chain] [options]
       iptables -[NX] chain
       iptables -E old-chain-name new-chain-name
       iptables -P chain target [options]
       iptables -h (print this help information)

Commands:
Either long or short options are allowed.
  --append  -A chain            Append to chain
  --check   -C chain            Check for the existence of a rule
  --delete  -D chain            Delete matching rule from chain
  --delete  -D chain rulenum
                                Delete rule rulenum (1 = first) from chain
  --insert  -I chain [rulenum]
                                Insert in chain as rulenum (default 1=first)
  --replace -R chain rulenum
                                Replace rule rulenum (1 = first) in chain
  --list    -L [chain [rulenum]]
                                List the rules in a chain or all chains
  --list-rules -S [chain [rulenum]]
                                Print the rules in a chain or all chains
  --flush   -F [chain]          Delete all rules in  chain or all chains
  --zero    -Z [chain [rulenum]]
                                Zero counters in chain or all chains
  --new     -N chain            Create a new user-defined chain
  --delete-chain
            -X [chain]          Delete a user-defined chain
  --policy  -P chain target
                                Change policy on chain to target
  --rename-chain
            -E old-chain new-chain
                                Change chain name, (moving any references)
Options:
    --ipv4      -4              Nothing (line is ignored by ip6tables-restore)
    --ipv6      -6              Error (line is ignored by iptables-restore)
[!] --protocol  -p proto        protocol: by number or name, eg. `tcp'
[!] --source    -s address[/mask][...]
                                source specification
[!] --destination -d address[/mask][...]
                                destination specification
[!] --in-interface -i input name[+]
                                network interface name ([+] for wildcard)
 --jump -j target
                                target for rule (may load target extension)
  --goto      -g chain
                              jump to chain with no return
  --match       -m match
                                extended match (may load extension)
  --numeric     -n              numeric output of addresses and ports
[!] --out-interface -o output name[+]
                                network interface name ([+] for wildcard)
  --table       -t table        table to manipulate (default: `filter')
  --verbose     -v              verbose mode
  --wait        -w [seconds]    maximum wait to acquire xtables lock before give up
  --wait-interval -W [usecs]    wait time to try to acquire xtables lock
                                default is 1 second
  --line-numbers                print line numbers when listing
  --exact       -x              expand numbers (display exact values)
[!] --fragment  -f              match second or further fragments only
  --modprobe=<command>          try to insert modules using this command
  --set-counters PKTS BYTES     set the counter during insert/append
[!] --version   -V              print package version.


命令图解

command

不使用-t指定表. 默认使用filter
param
! 为取反

target参数详解

ACCEPT

放行, 不再对比其它规则, 进入下一个链

REDIRECT

将封包重新导向到另一个端口(PNAT). 这个功能可以用来端口映射或用来保护 web 服务器, 不会中断当前链比对.

SNAT

改写封包来源 IP 为指定IP地址, 使用--to-source指定IP或IP范围或端口范围, 只能用在POSTROUTING链上, 中断当前链.

MASQUERADE

相当于固定SNAT源IP为当前网卡的IP, 只能用在POSTROUTING链上, 中断当前链.

DNAT

改写封包地址地址 IP 为指定IP地址, 使用--to-destination指定IP或IP范围或端口范围, 只能用在PREROUTING链上, 中断当前链.

MIRROR

镜射封包,将来源 IP 与目的地 IP 对调后送回,该动作会中断过滤程序。

QUEUE

结束结束过滤, 将包放入队列以供其它程序处理.

RETURN

中断当前自定义链的规则对比, 返回主链.

MARK

将封包标上某个代号, 为后续规则过滤条件提供依据, 使用--set-mark, 不中断当前链比对.

使用例程

通常需要将服务器的闲置端口全部禁止外部访问, 不响应外部ping, 内部其它应用可以正常访问. 有两种选择, 一种在PREROUTING链处理, 另一种在INPUT链处理

  1. 先放行向外部提供服务的端口(以22,80,443为例)
# PREROUTING 链
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j ACCEPT
# INPUT 链
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
  1. 封锁闲置端口, 禁止外部访问, 禁ping
# PREROUTING 链
iptables -t mangle -A PREROUTING -p tcp -j DROP
iptables -t mangle -A PREROUTING -p icmp -j DROP
# INPUT 链
iptables -A INPUT -p tcp -j DROP
iptables -A INPUT -p icmp -j DROP

到这一步就实现了禁ping和封锁闲置端口的功能, 但是除了放行的应用, 其它内部应用无法正常访问

  1. 让内部其它应用可以正常访问
# PREROUTING 链
iptables -t mangle -I PREROUTING -m state --state RELATED,ESTABLISHED -j ACCEPT
# INPUT 链
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
  1. 允许本地回环
# PREROUTING 链
iptables -t mangle -I PREROUTING -i lo -j ACCEPT
# INPUT 链
iptables -I INPUT -i lo -j ACCEPT
0

评论区