Linux 下的 iptables 配置
1. 目标
1). 能正确的描述 IP 和 ROUTING
2). 了解 iptables netfilter 的结构
3). 灵活运用 iptables 命令
4). 重点学习,理解,灵活运用于实际生活中 NAT 转换
2.iptables 功能简介及工作原理
防火墙是指设置在不同网络或网络安全域之间的一系列部件的组合,它能增强机构内部网络的安全性。它通过访问控制机制,确定哪些内部服务允许外部访问,以及允许哪些外部请求可以访问内部服务。它可以根据网络传输的类型决定 IP 包是否可以传进或传出内部网。
iptables 在我们的工作中起着极其重要的作用,我们每个接触电脑用户几乎难以离开它,在有意或者无意中都一直在跟 iptbles 打交道,我们平时用的 360 ,金山,小红伞,诺顿都相当于是防火墙,在时时刻刻保护着我们的系统不受外界入侵。需要知道的是我们平时用的都是软防火墙,功能简单易于配置,真正用于企业中的是硬件防火墙,有专门的防火墙来保护公司的信息安全,当然其价钱也是极其昂贵的。下面我们就虚拟机来模拟 iptables 的功能来深入了解其工作原理。
防火墙的过滤功能根据防范的方式和侧重点的不同分为两种情况:简单的包过滤和基于状态检测的包过滤。基于简单的包过滤只检查包头,基于状态检测的包过滤可以检查数据内容,想对来说比较复杂,但功能及其强大,这也是我们真正在实际工作中要用到的,我们在下面的学习中将一点一点来展示其强大的功能。包过滤工作原理我们用下图来具体说明,
A .当基于简单的包过滤时,我们只检查到第三层和第四层中间( icmp )工作过程如下:
① 数据包从外网传送到防火墙后,防火墙抢在 IP 层向 TCP 层传送前,将数据包转发给包检查模块进行处理。
② 首先与第一个过滤规则比较。
③ 如果与第一个模块相同,则对它进行审核,判断是否转发该数据包,这时审核结果是转发数据包,则将数据包发送到 TCP 层进行处理,否则就将它丢弃。
④ 如果与第一个过滤规则不同,则接着与第二个规则相比较,如果相同则对它进行审核,过程与③相同。
⑤ 如果与第二个过滤规则不同,则继续与下一个过滤规则比较,直到与所有过滤规则比较完成。要是所有过滤规则都不满足,就将数据包丢弃。
B .当基于状态检测的包过滤时,其工作方式和基于简单的包过滤方式一致,但其在审核规则时都拷贝一份放到缓存中,如果包头过滤通过,直接放行;如果不通过则直接检查应用层的数据,如果审核通过,则放行,如果审核不通过,则只把应用层的数据丢弃,这样一传送的数据因为缺失也会失效。
3.iptables 的内部数据流传输过程
iptables 基础知识:
iptables 由表 (tables) ,链 (chains) ,规则 (rules) 组成
默认 iptables 内置了四个表( tables ): filter 表 nat 表 mangle 表和 raw 表
五个链: INPUT ,OUTPUT ,PREROUTING ,POSTROUTING ,FORWARD
filter 表 :INPUT ,OUTPUT ,FORWARD
nat 表 :PREROUTING ,POSTROUTING, OUTPUT
mangle 表 :ALL (跟路由无关,在任何点都行, ye 最高)
raw 表:
iptables 传输数据包的过程 ,如图
① 当一个数据包进入网卡时,它首先进入 PREROUTING 链,内核根据数据包目的 IP 判断是否需要转送出去。
② 如果数据包就是进入本机的,它就会沿着图向下移动,到达 INPUT 链。数据包到了 INPUT 链后,任何进程都会收到它。本机上运行的程序可以发送数据包,这些数据包会经过 OUTPUT 链,然后到达 POSTROUTING 链输出。
③ 如果数据包是要转发出去的,且内核允许转发,数据包就会如图 10-4 所示向右移动,经过 FORWARD 链,然后到达 POSTROUTING 链输出。
上面这幅图是我借鉴别人的,下面这幅是我自己画的,(丑了点,呵呵),但是是自己的理解
图中黄色的为五个链,希望这幅图可以形象的表达出我的意思。防火墙不管数据的流向,只要是有数据通过,只要通过就必须遵循数据检查
4 iptables 的命令格式及使用
在 linux 中【】中的内容表示可有可无,这里再强调下
iptables 的命令格式较为复杂,一般的格式如下: Iptables 【 -t table 】 command chains ( NUM ) match condition -j action
命令选项:
--append -A append 在规则表的最后追加一条规则
--insert -I 【 n 】 插到第 n 条规则之前
--replade -R n replace 第 n 条新规则
--delete -D n delete 第 n 条规则
--flush -F 清空表中所有规则
--policy -P ACCEPT|DROP 默认策略动作
--new-chain -N z 自定义新链
--rename-chain -E 重命名用户自定义的链
--zero -Z 清零计数器
1 .所有被本规则匹配到的数据包的个数
2. 所有被本规则匹配到的数据包的数据之和
--list -L list 链中的所有规则 默认保存在 /etc/sysconfig/iptables
-x 显示 -Z 选项中的数据时,不作单位换算,显示精确值
-n 不作名称解析,以数字的格式显示 ip
-v | -vv |-vvv|-vvvv | 显示详细的信息
--line-numbers 显示行号
-S 同 -L , print 出来
匹配选项
匹配分为通用匹配和扩展匹配
A .通用匹配
--proto -p protocol 协议类型
--source -s src-address 数据包匹配的源地址
--destination -d dst-address 数据包匹配到目标地址
--in-terface -i in_interface 数据入口
--out-interface -o out-interface 数据出口
B .扩展匹配
扩展又分为隐含扩展和显式扩展
隐含匹配 显式扩展
tcp --source-port -m tcp
--dport -m state --state NEW|ESTABLISHED|RELATED| INVALID
--sport -m limit --limit n/days |minute
--limit-burst N 峰值
--type-flags -m string --string
--syn -m mac --mac—source
-m multiport --source-ports
--destination-ports
--tcp-flags mask comp
Udp --sport
--dport
Icmp --icmp-types
8 echorequest
0 echo-reply
3 destination unreachable
Action 动作
-j DROP 丢弃数据包(“悄悄地“)
REJECT 丢弃数据包(明确的)
ACCEPT 接收数据包
SNAT 源端口转换
DNAT 目的端口转换
LOG 记录日志
REDIRECT 端口转换
MASQUERADE 端口伪装(动态获取网关时用,耗系统资源)
保存 iptables 规则 ,默认是不保存的,重启后,规则就会消失
[root@localhost ~]# service iptables save 默认保存在 /etc/sysconfig/iptables 下
[root@localhost ~]# iptables-save > /etc/iptables.save 自定义保存
Iptables 的实例演示
下面我们来简单接触下 ipitables 的用法,然后再慢慢深入
[root@song ~]# iptables -t filter –L 查看 filter 表的规则
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.1.0/24 192.168.0.0/24 tcp dpt:http state NEW,ESTABLISHED
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT icmp -- anywhere anywhere icmp echo-request
ACCEPT icmp -- anywhere anywhere icmp echo-reply
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.0.0/24 192.168.1.0/24 tcp spt:http state ESTABLISHED
[root@song ~]# iptables –F 清除表中所有规则
[root@song ~]# iptables –L 可以看出和 –t filter –L 效果一样 , 默认查询 filter 表
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@song ~]# iptables -P INPUT DROP -P 设置表的默认策略
[root@song ~]# iptables -P OUTPUT DROP
[root@song ~]# iptables -P FORWARD DROP
[root@song ~]# iptables -L
Chain INPUT (policy DROP )
target prot opt source destination
Chain FORWARD (policy DROP )
target prot opt source destination
Chain OUTPUT (policy DROP )
target prot opt source destination
下面我们以一个简单的实例来联系下测试下我们的功力到“第几段“了 呵呵
搭建好相应的实验环境,这里不再详细说
要求:内外网之间可以相互 ping 通,外网可以访问内网的 httpd , ftp 服务 ,其中的 ftp 服务只能在有请求时服务器才相应。只允许内网无限制访问 firewall 的 ssh 服务。
我们来一条一条的实现
配置 firewall
1 外网可以访问内网的 httpd , ftp 服务
[root@song ~]# vim /etc/sysctl.conf 开启 firewall 路由功能
[root@song ~]# sysctl –p 重读配置文件,临时开启路由功能
net.ipv4.ip_forward = 1 为 1 时表示开启路由功能
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.s ysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 4294967295
kernel.shmall = 268435456
设置默认规则为 DROP
[root@song ~]# iptables -P INPUT DROP
[root@song ~]# iptables -P OUTPUT DROP
[root@song ~]# iptables -P FORWARD DROP
[root@song ~]# iptables –L 查看设置
Chain INPUT (policy DROP )
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP )
target prot opt source destination
1 使相互之间可以 ping 通
[root@song ~]# iptables -A FORWARD -p icmp --icmp-type 8 -j ACCEPT
[root@song ~]# iptables -A FORWARD -p icmp --icmp-type 0 -j ACCEPT
测试
[root@station7 shared]# ping 10.0.2.100
PING 10.0.2.100 (10.0.2.100) 56(84) bytes of data.
64 bytes from 10.0.2.100: icmp_seq=1 ttl=63 time=130 ms
[root@congtou pub]# ping 10.0.3.100
PING 10.0.3.100 (10.0.3.100) 56(84) bytes of data.
64 bytes from 10.0.3.100: icmp_seq=1 ttl=63 time=176 ms
64 bytes from 10.0.3.100: icmp_seq=2 ttl=63 time=3.33 ms
2 外网可以访问内网的 httpd 服务
[root@congtou ~]# service httpd status 查看 httpd 服务状态
httpd (pid 4238 4237 4236 4235 4234 4233 4232 4231 4229) is running...
[root@congtou ~]# cd /var/www/html/
[root@congtou html]# ls
[root@congtou html]# vim index.html
[root@congtou html]# elinks 127.0.0.1 自己先测试下看 httpd 服务是否运行正常
在配置 iptables 前先在 10.0.3.100 客户端测试下看下是什么结果
下图可以看出不行。无法连接到 httpd 服务器
[root@station23 ~]# iptables -A FORWARD -s 10.0.3.0/24 -d 10.0.2.100 / 从 10.0.3.0 网段来到 10.0.2.100 的基于 tcp 协议目标端口是 80 的全部接受
> -p tcp --dport 80 -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -d 10.0.3.0/24 -s 10.0.2.100 -p tcp --sport 80 -j ACCEPT 与上面的相对应
[root@station23 ~]# iptables -L -n
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 8
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 0
ACCEPT tcp -- 10.0.3.0/24 10.0.2.100 tcp dpt:80
ACCEPT tcp -- 10.0.2.100 10.0.3.0/24 tcp spt:80
Chain OUTPUT (policy DROP)
target prot opt source destination
客户端测试
3 外网可以访问内网的 ftp 服务, ftp 服务只能在有请求时服务器才相应
这里我们要用到基于状态的扩展匹配
服务器自己测试
[root@congtou pub]# service vsftpd status 查看服务器 ftp 服务的状态
vsftpd (pid 4307) is running...
[root@congtou pub]# lftp 127.0.0.1
lftp 127.0.0.1:~> ls
drwxr-xr-x 2 0 0 4096 Mar 05 10:16 pub
lftp 127.0.0.1:/> cd pub
lftp 127.0.0.1:/pub> ls
-rw-r--r-- 1 0 0 0 Mar 05 10:16 aa
-rw-r--r-- 1 0 0 0 Mar 05 10:16 bb
-rw-r--r-- 1 0 0 0 Mar 05 10:16 cc
lftp 127.0.0.1:/pub> exit
客户端测试结果如下
[root@station7 shared]# lftp 10.0.2.100
lftp 10.0.2.100:~> ls
`ls' at 0 [Connecting...] 这里我们会发现虽然可以 lftp 进去但是却无法 ls
在配置 ftp 状态规则是,我们需要添加以下 ip_conntrack_ftp 模块。如想开机挂载模块,需要编辑 /etc/sysconfig/iptables-config 这个文件,将所需要的模块名添加到 IPTABLES_MODULES="" 中
[root@station23 ~]# vim /etc/sysconfig/iptables-config
# Load additional iptables modules (nat helpers)
# Default: -none-
# Space separated list of nat helpers (e.g. 'ip_nat_ftp ip_nat_irc'), which
# are loaded after the firewall rules are applied. Options for the helpers are
# stored in /etc/modprobe.conf.
IPTABLES_MODULES=""
#
#
#
[root@station23 net]# modprobe ip_conntrack_ftp
[root@station23 ~]# iptables -A FORWARD -s 10.0.3.0/24 -d 10.0.2.100 -p /
> tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -s 10.0.2.100 -d 10.0.3.0/24 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -s 10.0.3.0/24 -d 10.0.2.100 -m /
> state --state ESTABLISHED,RELATED -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -d 10.0.3.0/24 -s 10.0.2.100 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@station23 ~]# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT icmp -- anywhere anywhere icmp echo-request
ACCEPT icmp -- anywhere anywhere icmp echo-reply
ACCEPT tcp -- 10.0.3.0/24 10.0.2.100 tcp dpt:http
ACCEPT tcp -- 10.0.2.100 10.0.3.0/24 tcp spt:http
ACCEPT tcp -- 10.0.3.0/24 10.0.2.100 tcp dpt:ftp state NEW,ESTABLISHED
ACCEPT tcp -- 10.0.2.100 10.0.3.0/24 tcp spt:ftp state ESTABLISHED
ACCEPT all -- 10.0.3.0/24 10.0.2.100 state RELATED,ESTABLISHED
ACCEPT all -- 10.0.2.100 10.0.3.0/24 state RELATED,ESTABLISHED
[root@station23 ~]# iptables -A FORWARD -s 192.168.2.0/24 -d 192.168.3.100 /
> -p tcp --dport 80 -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -d 192.168.2.0/24 -s 192.168.3.100 -p tcp --sport 80 -j ACCEPT
[root@station7 shared]# lftp 10.0.2.100
lftp 10.0.2.100:~> ls
drwxr-xr-x 2 0 0 4096 Mar 05 10:16 pub
lftp 10.0.2.100:/> ls
lftp 10.0.2.100:/pub> ls
-rw-r--r-- 1 0 0 0 Mar 05 10:16 aa
-rw-r--r-- 1 0 0 0 Mar 05 10:16 bb
-rw-r--r-- 1 0 0 0 Mar 05 10:16 cc
4 .只允许内网访问 firewall 的 ssh 服务,
这里测试时会发现内外网均无法进入
[root@station7 shared]# ssh root@10.0.3.1
[root@congtou netfilter]# ssh root@10.0.2.1
[root@congtou netfilter]# ssh root@10.0.2.100
配置防火墙规则
[root@station23 ~]# iptables -A INPUT -s 10.0.2.100 -d 10.0.2.1 -p tcp --dport 22 -j ACCEPT
[root@station23 ~]# iptables -A OUTPUT -d 10.0.2.100 -s 10.0.2.1 -p tcp --sport 22 -j ACCEPT
[root@station23 ~]# netstat -tnulp | grep 22
tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 3696/hpiod
tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN 3701/python
tcp 0 0 :::22 :::* LISTEN 3731/sshd
测试结果如下 10.0.2.100 可以 ssh 到 firewall 内,但 10.0.3.100 仍然无法进入
10.0.2.100 的测试结果
[root@congtou netfilter]# ssh root@10.0.2.1
The authenticity of host '10.0.2.1 (10.0.2.1)' can't be established.
RSA key fingerprint is 93:e3:85:43:4f:43:9a:7b:71:2f:97:fb:3f:e9:f6:92.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.2.1' (RSA) to the list of known hosts.
root@10.0.2.1's password:
Last login: Fri Mar 5 17:37:12 2010
[root@station23 ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:54:4C:91
inet addr:10.0.2.1 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe54:4c91/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:133497 errors:0 dropped:0 overruns:0 frame:0
TX packets:322 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:24273511 (23.1 MiB) TX bytes:38337 (37.4 KiB)
Interrupt:67 Base address:0x2024
10.0.3.100 的测试结果
[root@station7 shared]# ssh root@10.0.3.1
好的,这里我们只是简单的讨论了下 iptales 的用法,其中有很多的用法我们都还没说,例如非常重要的 SNAT ,DNAT 转换,字符匹配过滤,同是定义多端口,最大连接数限制,访问时间限制,匹配速率限制,还有就是现在企业中经常要用到的 l7layer 应用层过滤 !!我们会在下次讨论这些非常重要有用的东东 ..