Packet filtering with Linux & NAT

http://www.linuxfocus.org/ChineseGB/May2003/article289.shtml

 

Gateway, Proxy-Arp 和 Ethernet Bridge ?

过滤机构可以被考虑成一张能够过滤有害的数据包的网。最重要要的是找到合适大 小的网孔和安装他的正确位置。

防火墙在网络中的位置
Firewall location

为了能够完全的过滤数据包,这个过滤机构必须无缝的插入他所要保护的网络和“其 余的世界”之间。在实践上,这个可以用一台带有两块网络接口(通常是以太网卡)的 设备来完成 ,一个连接内部的网络,另一块连接外部作为路由转发。这种方式,通信 将不得不通过防火墙,这样防火墙可以阻止他们或不依照他们的内容进行发送。
设备运行过滤机构可以被配置成3种不同的方式:

- "simple" Gateway: 这是最普通的配置。设备被用作两个网络或子网之间的网关。在本地网络内的电脑将使 用防火墙代替他们的默认路由。

- "Proxy-ARP" Gateway: 前面那个配置暗示着把一个网络划分成两个子网,这个 会造成一半可利用的 ip 地址失效了。这是有点恼人的。举个例子,一个16个地址的子 网(28位子网掩码),除去网络地址和广播地址只有14个是有效的,子网添加一位,有 效地址将从14减少到6(8个ip减去网络地址和广播地址)。当你不能够接受失去一半有 效ip地址的情况,你可以使用这种技术,我们将会在稍后的文章里解释他。此外,这种 技术不需要对网络中存在的路由器和被保护的电脑做的任何改变。 

- Ethernet bridge: 作为一个以太网网关安装 (不是ip网关),使过滤机构对于 其他设备来说是透明的。因此不分配ip地址给以太网接口是妥当的。于是,设备将不会 被ping,traceroute等工具发现。让我们注意一个数据包过滤执行,在2.4.x内核还 还没完成前提下,基于这个端口的特性需要2.2.x的内核。

 

过滤基本规则

既然我们知道什么地方安装过滤器,那么我们必须定义什么应该阻止什么应该接受。
这里有两种方式去配置一个过滤器:

- 好的方法:没有数据被允许通过,除了规则允许的。
- 坏的方法:(不幸的是经常被使用)明确地阻止被禁止数据包,所有的数据包被接受。

这有一个简单的解释:在第一种情况,遗忘规则导致服务不完全工作或根本不工作。通 常,这会被很快的注意到,然后添加适当的规则使服务再运行起来。
在第二中情况,遗忘一个规则会造成一个潜在的弱点,如果我们去找,很难去发现...

 

Netfilter

在linux 2.4内核上使用的最多的包过滤软件是Netfilter:它很好的取代了使 用在2.2内核的‘ipchains’。Netfilter由两部分组成:内核支持这需要编译你的 内核和在你系统中可用到的‘iptables’命令

 

安装实例

一个实例的注释比一段长时间的演讲要好的多,下面我们将描述怎样去安装和配置 一个过滤器设备。首先,设备要先配置成一个网关,使用Proxy-ARP来限定ip地址的 数量,我们将配置过滤系统。

著者偏好选择了Debian发布版来构建一个这样的系统,任何linux发行版都可以。

首先,检查你的内核已经支持Netfilter。如果是的,引导信息将包含:

ip_conntrack (4095 buckets, 32760 max)
ip_tables: (c)2000 Netfilter core team

另外,当Netfilter支持被激活后你不得不反编译内核。相应的选项将会在 "Networking Options"菜单里的"Network Packet Filtering" 子菜单里找到。从"Netfilter Configuration"选项,选择你需要的。 如果不能确定,你可以全部选择。此外,最好把Netfilter包含至内核,而不是作为加 载模块。如果因为一些原因或者Netfilter一个模块出错或不能加载,过滤器将不能工 作,我们不更多的谈论关于这么做所冒的风险了。

你也应该安装‘iproute2’包(这在最后是不必要做的,但是我们的实例将使 用从它允许我们建立配置脚本文件开始。)对于Debian,‘apt-get install iproute’ 命令足够了。
其他的发行版,获得相应的软件包。用通常的方法,或从源程序安装。你可以在下面的 地址下载到相应的软件包:
ftp://ftp.inr.ac.ru/ip-routing/

现在对两块以太网卡配置。我们必须注意Liunx的内核,自动检测硬件程序到检测 网络卡的这一步时就会发现它。可是,仅仅第一块被探测到。
一个简单的解决方案是在lilo.conf文件里添加一句话:
append="ether=0,0,eth1"

现在,我们配置以太网接口。我们选择对两块网卡使用同一个ip地址的方法,因而 可以节约一个地址。
我们假定有一个10.1.2.96/28的子网。它的地址从10.1.2.96到10.1.2.111 路由器的地址是10.1.2.97,我们的过滤器设备的地址的10.1.2.98。eth0 接口之间如果没有通过hub或switch相连,那么将通过RJ45双绞线直接连接路由器; eth1接口将连接hub或switch, 通过他它到达本地网络设备。

因此,两个接口将会被配置成下列参数:

address  : 10.1.2.98
netmask  : 255.255.255.240
network  : 10.1.2.96
broadcast: 10.1.2.111
gateway  : 10.1.2.97

接下来,我们使用下面的脚本,它必须在网卡初始化配置以后运行。

net.vars: configuration variables

PREFIX=10.1.2
DMZ_ADDR=$PREFIX.96/28
# Interface definitions
BAD_IFACE=eth0
DMZ_IFACE=eth1
ROUTER=$PREFIX.97


net-config.sh: network configuration script

#!/bin/sh
# Comment out the next line to display the commands at execution time
# set -x
# We read the variables defined in the previous file
source /etc/init.d/net.vars
# We remove the present routes from the local network
ip route del $PREFIX.96/28 dev $BAD_IFACE
ip route del $PREFIX.96/28 dev $DMZ_IFACE
# We define that the local network can be reached through eth1
# and the router through eth0.
ip route add $ROUTER dev $BAD_IFACE
ip route add $PREFIX.96/28 dev $DMZ_IFACE
# We activate Proxy-ARP for both interfaces
echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp
# We activate the IP forwarding to allow the packets coming to one card
# to be routed to the other one.
echo 1 > /proc/sys/net/ipv4/ip_forward

让我们返回Proxy-ARP机制对我们的配置所必需的。
当一个设备在同一个网段里同另一台设备会话时,他需要知道以太网地址(或者MAC地 址或者硬件地址)相应的ip地址。当源设备广播请求”ip地址位1.2.3.4的MAC地址是 什么?”目标设备必须回答。

这里有一个“会话”的实例,是通过tcpdump检测到的:
- the request: the machine 172.16.6.72 asks the MAC address corresponding to the IP address IP 172.16.6.10.
19:46:15.702516 arp who-has 172.16.6.10 tell 172.16.6.72
- the answer: the machine 172.16.6.10 provides its card number.
19:46:15.702747 arp reply 172.16.6.10 is-at 0:a0:4b:7:43:71

通过这个简略的解释将引导我们到达目的地:ARP请求通过广播传播,因此它被限 定在同一个物理网段里。因此,受保护的设备想要去查找路由器MAC地址的请求将会被 过滤器设备阻止。激活着的Proxy-ARP的特色就是解决这个问题,它将传 输ARP请求。

这下一阶段里,你将有一个运行着的网络,它是由一台设备管理整个本地网络和外 网的通信。

现在,我们必须使用Netfilter建立过滤。
Netfilter允许直接对经过的数据包有所行动。在基本配置里,数据包被3条规则链管理:
- INPUT:数据包通过一个接口进来。
- FORWARD:把所有的数据包从一个接口转发到另一个接口。
- OUTPUT:数据包通过一个接口出去。

‘iptables’命令允许对这些链添加,改变或者移除规则从而修改过滤器的动作。
此外,每一个链有一个默认的策略,换句话说,它知道当一个数据包没有规则匹配时该 怎么处理。 
当前有四个选项:
- ACCEPT:允许通过数据包。
- REJECT:拒绝数据包通过,关联的错误信息被传送(ICMP端口不能到达,TCP重置 关于这些的),
- LOG:把数据包记录写在syslog。
- DROP:忽略数据包,不发送回答。

数据流通过标准链

 

Packet flow

这里有一些操作整个链常用到的iptables选项。我们将在稍后解释他们:

 

-N:创建一条新链。
-X:移除一条空链。
-P:改变一条链的默认策略。
-L:列出一条链的规则。
-F:清空一条链里所的规则。
-Z:清除已经通过这条链的字节和数据包包的计算器。

修改一条链,下面的命令将会有用的:
-A:添加一条规则在链的最后。
-I:插入一条新规则在链的给定位置。
-R:取代一条给定规则。
-D:删除链里的规则,可以使用规则的编号或它的具体描述。

让我们看一个简单的实例:我们将阻止对给定设备PING回应(这是一个'echo-reply' 类型的ICMP数据包)。
首先,让我们检测能"ping"通所给定的设备:

# ping -c 1 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes
64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms

--- 172.16.6.74 ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.6/0.6/0.6 ms

现在,我们对INPUT链添加一条规则,这将截取来自172.16.6.74('-s 172.16.6.74') 的ICMP-Reply数据包('-p icmp --icmp-type echo-reply')这些数据包将会被 忽略('-j DROP')。

# iptables -A INPUT -s 172.16.6.74 -p icmp --icmp-type echo-reply -j DROP

让我们再PING那个设备:

# ping -c 3 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes

--- 172.16.6.74 ping statistics ---

3 packets transmitted, 0 packets received, 100% packet loss

这和我们所期望的一样,回应没有通过。我们检查已经被阻止的3个回 应。(3个数据包共252字节)

# iptables -L INPUT -v
Chain INPUT (policy ACCEPT 604K packets, 482M bytes)
 pkts bytes target     prot opt in    out     source       destination
  3   252   DROP       icmp --  any   any     172.16.6.74    anywhere

如果想返回到初始状态,我们要做的仅仅是移除INPUT链里的第一条规则:

# iptables -D INPUT 1

我们再PING一次:

# ping -c 1 172.16.6.74
PING 172.16.6.74 (172.16.6.74): 56 data bytes
64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms

--- 172.16.6.74 ping statistics ---

1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.6/0.6/0.6 ms
#

运行了!

你可以对3条存在链添加其他的链(这3条链你无论如何不能移除),使通信通过他 们。这是有用,举个例子,可以避免在不同的链里重复规则。

让我们设置一个最小化的防火墙所必需的规则。他将允许ssh,域(DNS),http, smtp服务和其他一些无关紧要的。
为了简单化,将设置命令写在shell脚本比配置更容易一点。当这个脚本设立一个新的 规则前应当清空当前配置。这里有一个小诀窍去运行脚本,就是在配置没有副本规则下 被激活。

rc.firewall

#!/bin/sh

# Flushing out the rules
iptables -F
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD


# The chain is built according to the direction.
# bad = eth0 (outside)
# dmz = eth1 (inside)
iptables -X bad-dmz
iptables -N bad-dmz
iptables -X dmz-bad
iptables -N dmz-bad
iptables -X icmp-acc
iptables -N icmp-acc
iptables -X log-and-drop
iptables -N log-and-drop

# Specific chain used for logging packets before blocking them
iptables -A log-and-drop -j LOG --log-prefix "drop "
iptables -A log-and-drop -j DROP

# The packets having the TCP flags activated are dropped
# and so for the ones with no flag at all (often used with Nmap scans)
iptables -A FORWARD -p tcp --tcp-flags ALL ALL -j log-and-drop
iptables -A FORWARD -p tcp --tcp-flags ALL NONE -j log-and-drop

# The packets coming from reserved addresses classes are dropped
# and so for multicast
iptables -A FORWARD -i eth+ -s 224.0.0.0/4 -j log-and-drop
iptables -A FORWARD -i eth+ -s 192.168.0.0/16 -j log-and-drop
iptables -A FORWARD -i eth+ -s 172.16.0.0/12 -j log-and-drop
iptables -A FORWARD -i eth+ -s 10.0.0.0/8 -j log-and-drop

# The packets belonging to an already established connexion are accepted
iptables -A FORWARD -m state --state INVALID -j log-and-drop
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# The corresponding chain is sent according to the packet origin
iptables -A FORWARD -s $DMZ_ADDR -i $DMZ_IFACE -o $BAD_IFACE -j dmz-bad
iptables -A FORWARD -o $DMZ_IFACE -j bad-dmz
# All the rest is ignored
iptables -A FORWARD -j log-and-drop

# Accepted ICMPs
iptables -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type echo-request -j ACCEPT
iptables -A icmp-acc -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A icmp-acc -j log-and-drop

# Outside -> Inside chain
# mail, DNS, http(s) and SSH are accepted
iptables -A bad-dmz -p tcp --dport smtp -j ACCEPT
iptables -A bad-dmz -p udp --dport domain -j ACCEPT
iptables -A bad-dmz -p tcp --dport domain -j ACCEPT
iptables -A bad-dmz -p tcp --dport www -j ACCEPT
iptables -A bad-dmz -p tcp --dport https -j ACCEPT
iptables -A bad-dmz -p tcp --dport ssh -j ACCEPT
iptables -A bad-dmz -p icmp -j icmp-acc
iptables -A bad-dmz -j log-and-drop

# Inside -> Outside chain
# mail, DNS, http(s) and telnet are accepted
iptables -A dmz-bad -p tcp --dport smtp -j ACCEPT
iptables -A dmz-bad -p tcp --sport smtp -j ACCEPT
iptables -A dmz-bad -p udp --dport domain -j ACCEPT
iptables -A dmz-bad -p tcp --dport domain -j ACCEPT
iptables -A dmz-bad -p tcp --dport www -j ACCEPT
iptables -A dmz-bad -p tcp --dport https -j ACCEPT
iptables -A dmz-bad -p tcp --dport telnet -j ACCEPT
iptables -A dmz-bad -p icmp -j icmp-acc
iptables -A dmz-bad -j log-and-drop

# Chains for the machine itself
iptables -N bad-if
iptables -N dmz-if
iptables -A INPUT -i $BAD_IFACE -j bad-if
iptables -A INPUT -i $DMZ_IFACE -j dmz-if

# External interface
# SSH only accepted on this machine
iptables -A bad-if -p icmp -j icmp-acc
iptables -A bad-if -p tcp --dport ssh -j ACCEPT
iptables -A bad-if -p tcp --sport ssh -j ACCEPT
ipchains -A bad-if -j log-and-drop

# Internal interface
iptables -A dmz-if -p icmp -j icmp-acc
iptables -A dmz-if -j ACCEPT

关于服务质量的几点说明。Linux能够修改ToS("Type of Service")字段,对 一个数据包赋予不同的优先权。举例:下面的命令改善流出的SSH数据包的连接响应。

iptables -A OUTPUT -t mangle -p tcp --dport ssh -j TOS --set-tos Minimize-Delay

用同样的方法,对于FTP连接你可以使用'--set-tos Maximize-Throughput' 选项来改善传输速度。

这就是Netfilter。现在你知道设置一个有效的数据包过滤系统的基础知识。但是, 紧记当涉及安全时防火墙并不是万能药。他仅仅是一种预防。你还需使用强壮的密码, 最新的安全补丁,入侵检测系统等等。

 

涉及资料

 

 

 

http://blog.chinaunix.net/uid-26495963-id-3279216.html

 

防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种。无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘。而我们的任务就是需要去定义到底防火墙如何工作,这就是防火墙的策略,规则,以达到让它对出入网络的IP、数据进行检测。
 
目前市面上比较常见的有3、4层的防火墙,叫网络层的防火墙,还有7层的防火墙,其实是代理层的网关
 
对于TCP/IP的七层模型来讲,我们知道第三层是网络层,三层的防火墙会在这层对源地址和目标地址进行检测。但是对于七层的防火墙,不管你源端口或者目标端口,源地址或者目标地址是什么,都将对你所有的东西进行检查。所以,对于设计原理来讲,七层防火墙更加安全,但是这却带来了效率更低。所以市面上通常的防火墙方案,都是两者结合的。而又由于我们都需要从防火墙所控制的这个口来访问,所以防火墙的工作效率就成了用户能够访问数据多少的一个最重要的控制,配置的不好甚至有可能成为流量的瓶颈。
 
二:iptables 的历史以及工作原理
 
1.iptables的发展:
 
iptables的前身叫ipfirewall (内核1.x时代),这是一个作者从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具。但是ipfirewall工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。当内核发展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用,而现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能
 
他们都是工作在用户空间中,定义规则的工具,本身并不算是防火墙。它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)
 
    作者一共在内核空间中选择了5个位置,
    1.内核空间中:从一个网络接口进来,到另一个网络接口去的
    2.数据包从内核流入用户空间的
    3.数据包从用户空间流出的
    4.进入/离开本机的外网接口
    5.进入/离开本机的内网接口
        
2.iptables的工作机制
 
从上面的发展我们知道了作者选择了5个位置,来作为控制的地方,但是你有没有发现,其实前三个位置已经基本上能将路径彻底封锁了,但是为什么已经在进出的口设置了关卡之后还要在内部卡呢? 由于数据包尚未进行路由决策,还不知道数据要走向哪里,所以在进出口是没办法实现数据过滤的。所以要在内核空间里设置转发的关卡,进入用户空间的关卡,从用户空间出去的关卡。那么,既然他们没什么用,那我们为什么还要放置他们呢?因为我们在做NAT和DNAT的时候,目标地址转换必须在路由之前转换。所以我们必须在外网而后内网的接口处进行设置关卡。        
 
 这五个位置也被称为五个钩子函数(hook functions),也叫五个规则链。
1.PREROUTING (路由前)
2.INPUT (数据包流入口)
3.FORWARD (转发管卡)
4.OUTPUT(数据包出口)
5.POSTROUTING(路由后)
        这是NetFilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链。       
 
3.防火墙的策略
 
防火墙策略一般分为两种,一种叫“通”策略,一种叫“堵”策略,通策略,默认门是关着的,必须要定义谁能进堵策略则是,大门是洞开的,但是你必须有身份认证,否则不能进。所以我们要定义,让进来的进来,让出去的出去,所以通,是要全通,而堵,则是要选择。当我们定义的策略的时候,要分别定义多条功能,其中:定义数据包中允许或者不允许的策略,filter过滤的功能,而定义地址转换的功能的则是nat选项。为了让这些功能交替工作,我们制定出了“表”这个定义,来定义、区分各种不同的工作功能和处理方式。
 
我们现在用的比较多个功能有3个:
1.filter 定义允许或者不允许的
2.nat 定义地址转换的 
                3.mangle功能:修改报文原数据
 
我们修改报文原数据就是来修改TTL的。能够实现将数据包的元数据拆开,在里面做标记/修改内容的。而防火墙标记,其实就是靠mangle来实现的。
 
小扩展:
对于filter来讲一般只能做在3个链上:INPUT ,FORWARD ,OUTPUT
对于nat来讲一般也只能做在3个链上:PREROUTING ,OUTPUT ,POSTROUTING
而mangle则是5个链都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
 
iptables/netfilter(这款软件)是工作在用户空间的,它可以让规则进行生效的,本身不是一种服务,而且规则是立即生效的。而我们iptables现在被做成了一个服务,可以进行启动,停止的。启动,则将规则直接生效,停止,则将规则撤销。 
iptables还支持自己定义链。但是自己定义的链,必须是跟某种特定的链关联起来的。在一个关卡设定,指定当有数据的时候专门去找某个特定的链来处理,当那个链处理完之后,再返回。接着在特定的链中继续检查。
 
注意:规则的次序非常关键,谁的规则越严格,应该放的越靠前,而检查规则的时候,是按照从上往下的方式进行检查的。
 
三.规则的写法:
 
 iptables定义规则的方式比较复杂:
 格式:iptables [-t table] COMMAND chain CRETIRIA -j ACTION
 -t table :3个filter nat mangle
 COMMAND:定义如何对规则进行管理
 chain:指定你接下来的规则到底是在哪个链上操作的,当定义策略的时候,是可以省略的
 CRETIRIA:指定匹配标准
 -j ACTION :指定如何进行处理
 
 比如:不允许172.16.0.0/24的进行访问。
 iptables -t filter -A INPUT -s 172.16.0.0/16 -p udp --dport 53 -j DROP
 当然你如果想拒绝的更彻底:
 iptables -t filter -R INPUT 1 -s 172.16.0.0/16 -p udp --dport 53 -j REJECT
 
 iptables -L -n -v #查看定义规则的详细信息
 
四:详解COMMAND:
 
1.链管理命令(这都是立即生效的)
-P :设置默认策略的(设定默认门是关着的还是开着的)
默认策略一般只有两种
iptables -P INPUT (DROP|ACCEPT)  默认是关的/默认是开的
比如:
iptables -P INPUT DROP 这就把默认规则给拒绝了。并且没有定义哪个动作,所以关于外界连接的所有规则包括Xshell连接之类的,远程连接都被拒绝了。
        -F: FLASH,清空规则链的(注意每个链的管理权限)
    iptables -t nat -F PREROUTING
    iptables -t nat -F 清空nat表的所有链
        -N:NEW 支持用户新建一个链
            iptables -N inbound_tcp_web 表示附在tcp表上用于检查web的。
        -X: 用于删除用户自定义的空链
            使用方法跟-N相同,但是在删除之前必须要将里面的链给清空昂了
        -E:用来Rename chain主要是用来给用户自定义的链重命名
            -E oldname newname
         -Z:清空链,及链中默认规则的计数器的(有两个计数器,被匹配到多少个数据包,多少个字节)
            iptables -Z :清空
 
2.规则管理命令
         -A:追加,在当前链的最后新增一个规则
         -I num : 插入,把当前规则插入为第几条。
            -I 3 :插入为第三条
         -R num:Replays替换/修改第几条规则
            格式:iptables -R 3 …………
         -D num:删除,明确指定删除第几条规则
        
3.查看管理命令 “-L”
 附加子命令
 -n:以数字的方式显示ip,它会将ip直接显示出来,如果不加-n,则会将ip反向解析成主机名。
 -v:显示详细信息
 -vv
 -vvv :越多越详细
 -x:在计数器上显示精确值,不做单位换算
 --line-numbers : 显示规则的行号
 -t nat:显示所有的关卡的信息
 
五:详解匹配标准
 
1.通用匹配:源地址目标地址的匹配
 -s:指定作为源地址匹配,这里不能指定主机名称,必须是IP
IP | IP/MASK | 0.0.0.0/0.0.0.0
而且地址可以取反,加一个“!”表示除了哪个IP之外
 -d:表示匹配目标地址
 -p:用于匹配协议的(这里的协议通常有3种,TCP/UDP/ICMP)
 -i eth0:从这块网卡流入的数据
流入一般用在INPUT和PREROUTING上
 -o eth0:从这块网卡流出的数据
流出一般在OUTPUT和POSTROUTING上
        
2.扩展匹配
2.1隐含扩展:对协议的扩展
    -p tcp :TCP协议的扩展。一般有三种扩展
--dport XX-XX:指定目标端口,不能指定多个非连续端口,只能指定单个端口,比如
--dport 21  或者 --dport 21-23 (此时表示21,22,23)
--sport:指定源端口
--tcp-fiags:TCP的标志位(SYN,ACK,FIN,PSH,RST,URG)
    对于它,一般要跟两个参数:
1.检查的标志位
2.必须为1的标志位
--tcpflags syn,ack,fin,rst syn   =    --syn
表示检查这4个位,这4个位中syn必须为1,其他的必须为0。所以这个意思就是用于检测三次握手的第一次包的。对于这种专门匹配第一包的SYN为1的包,还有一种简写方式,叫做--syn
    -p udp:UDP协议的扩展
        --dport
        --sport
    -p icmp:icmp数据报文的扩展
        --icmp-type:
echo-request(请求回显),一般用8 来表示
所以 --icmp-type 8 匹配请求回显数据包
echo-reply (响应的数据包)一般用0来表示
                  
2.2显式扩展(-m)
     扩展各种模块
      -m multiport:表示启用多端口扩展
      之后我们就可以启用比如 --dports 21,23,80
                  
        
六:详解-j ACTION
 
 常用的ACTION:
 DROP:悄悄丢弃
一般我们多用DROP来隐藏我们的身份,以及隐藏我们的链表
 REJECT:明示拒绝
 ACCEPT:接受
custom_chain:转向一个自定义的链
 DNAT
 SNAT
 MASQUERADE:源地址伪装
 REDIRECT:重定向:主要用于实现端口重定向
 MARK:打防火墙标记的
 RETURN:返回
在自定义链执行完毕后使用返回,来返回原规则链。
 
练习题1:
     只要是来自于172.16.0.0/16网段的都允许访问我本机的172.16.100.1的SSHD服务
     分析:首先肯定是在允许表中定义的。因为不需要做NAT地址转换之类的,然后查看我们SSHD服务,在22号端口上,处理机制是接受,对于这个表,需要有一来一回两个规则,如果我们允许也好,拒绝也好,对于访问本机服务,我们最好是定义在INPUT链上,而OUTPUT再予以定义就好。(会话的初始端先定义),所以加规则就是:
     定义进来的: iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.1 -p tcp --dport 22 -j ACCEPT
     定义出去的: iptables -t filter -A OUTPUT -s 172.16.100.1 -d 172.16.0.0/16 -p tcp --dport 22 -j ACCEPT
     将默认策略改成DROP:
  iptables -P INPUT DROP
  iptables -P OUTPUT DROP
  iptables -P FORWARD DROP
        
七:状态检测:
 
是一种显式扩展,用于检测会话之间的连接关系的,有了检测我们可以实现会话间功能的扩展
        什么是状态检测?对于整个TCP协议来讲,它是一个有连接的协议,三次握手中,第一次握手,我们就叫NEW连接,而从第二次握手以后的,ack都为1,这是正常的数据传输,和tcp的第二次第三次握手,叫做已建立的连接(ESTABLISHED),还有一种状态,比较诡异的,比如:SYN=1 ACK=1 RST=1,对于这种我们无法识别的,我们都称之为INVALID无法识别的。还有第四种,FTP这种古老的拥有的特征,每个端口都是独立的,21号和20号端口都是一去一回,他们之间是有关系的,这种关系我们称之为RELATED。
所以我们的状态一共有四种:
        NEW
        ESTABLISHED
        RELATED
        INVALID
 
所以我们对于刚才的练习题,可以增加状态检测。比如进来的只允许状态为NEW和ESTABLISHED的进来,出去只允许ESTABLISHED的状态出去,这就可以将比较常见的反弹式木马有很好的控制机制。
        
对于练习题的扩展:
进来的拒绝出去的允许,进来的只允许ESTABLISHED进来,出去只允许ESTABLISHED出去。默认规则都使用拒绝
iptables -L -n --line-number  :查看之前的规则位于第几行
    改写INPUT
        iptables -R INPUT 2 -s 172.16.0.0/16 -d 172.16.100.1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
        iptables -R OUTPUT 1 -m state --state ESTABLISHED -j ACCEPT
 
    此时如果想再放行一个80端口如何放行呢?
        iptables -A INPUT -d 172.16.100.1 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
 
        iptables -R INPUT 1 -d 172.16.100.1 -p udp --dport 53 -j ACCEPT
 
练习题2:
假如我们允许自己ping别人,但是别人ping自己ping不通如何实现呢?
分析:对于ping这个协议,进来的为8(ping),出去的为0(响应).我们为了达到目的,需要8出去,允许0进来
 
在出去的端口上:iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
在进来的端口上:iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
 
小扩展:对于127.0.0.1比较特殊,我们需要明确定义它
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
 
八:SNAT和DNAT的实现
 
由于我们现在IP地址十分紧俏,已经分配完了,这就导致我们必须要进行地址转换,来节约我们仅剩的一点IP资源。那么通过iptables如何实现NAT的地址转换呢?
 
1.SNAT基于原地址的转换
基于原地址的转换一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将我们内网的地址转换为一个外网的IP,我们就可以实现连接其他外网IP的功能
所以我们在iptables中就要定义到底如何转换:
定义的样式:
比如我们现在要将所有192.168.10.0网段的IP在经过的时候全都转换成172.16.100.1这个假设出来的外网地址:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.1
这样,只要是来自本地网络的试图通过网卡访问网络的,都会被统统转换成172.16.100.1这个IP.
那么,如果172.16.100.1不是固定的怎么办?
我们都知道当我们使用联通或者电信上网的时候,一般它都会在每次你开机的时候随机生成一个外网的IP,意思就是外网地址是动态变换的。这时我们就要将外网地址换成 MASQUERADE(动态伪装):它可以实现自动寻找到外网地址,而自动将其改为正确的外网地址。所以,我们就需要这样设置:
         iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
         这里要注意:地址伪装并不适用于所有的地方。
 
2.DNAT目标地址转换
对于目标地址转换,数据流向是从外向内的,外面的是客户端,里面的是服务器端 通过目标地址转换,我们可以让外面的ip通过我们对外的外网ip来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上
 
    如何做目标地址转换呢?:
iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp --dport 80 -j DNAT --todestination 172.16.100.2
        目标地址转换要做在到达网卡之前进行转换,所以要做在PREROUTING这个位置上
 
九:控制规则的存放以及开启
 
注意:你所定义的所有内容,当你重启的时候都会失效,要想我们能够生效,需要使用一个命令将它保存起来
1.service iptables save 命令
它会保存在/etc/sysconfig/iptables这个文件中
    2.iptables-save 命令
iptables-save > /etc/sysconfig/iptables
 
    3.iptables-restore 命令
开机的时候,它会自动加载/etc/sysconfig/iptabels
如果开机不能加载或者没有加载,而你想让一个自己写的配置文件(假设为iptables.2)手动生效的话:
iptables-restore < /etc/sysconfig/iptables.2
则完成了将iptables中定义的规则手动生效
 
 
十:总结
         Iptables是一个非常重要的工具,它是每一个防火墙上几乎必备的设置,也是我们在做大型网络的时候,为了很多原因而必须要设置的。学好Iptables,可以让我们对整个网络的结构有一个比较深刻的了解,同时,我们还能够将内核空间中数据的走向以及linux的安全给掌握的非常透彻。我们在学习的时候,尽量能结合着各种各样的项目,实验来完成,这样对你加深iptables的配置,以及各种技巧有非常大的帮助。
 
附加iptables比较好的文章:
 
 
NAT&&NAT
http://blog.chinaunix.net/uid-25452915-id-3138291.html
下面以CentOS为例,说明单网卡NAT代理的配置。
首先增加eth0:0接口:
新建文件:/etc/sysconfig/network-scripts/ifcfg-eth0:0
文件的内容如下:

点击(此处)折叠或打开

  1. DEVICE=eth0:0
  2. IPADDR=192.168.164.100
  3. NETMASK=255.255.255.0
  4. ONBOOT=yes
  5. BOOTPROTO=static
其中192.168.164.100为内网的代理网关的ip,保存刚才新建的文件,然后运行命令: service network restart,重启网络。
输入ifconfig命令,网络配置如下:
eth0的ip为211.69.198.191,即外网ip,eth0:0的ip为192.168.164.100, 即内网ip。读者要根据自己的情况对这两个ip进行替换。
接着输入以下命令:

点击(此处)折叠或打开

  1. echo 1 > /proc/sys/net/ipv4/ip_forward
  2. iptables -F
  3. iptables -F -t nat
  4. iptables -P FORWARD DROP
  5. iptables -A FORWARD -s 192.168.164.0/24 -j ACCEPT
  6. iptables -A FORWARD -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
  7. iptables -t nat -A POSTROUTING -o eth0 -s 192.168.164.0/24 -j SNAT --to 211.69.198.191
在另一台主机上进行配置:
ip为: 192.168.164.114
netmask为: 255.255.255.0
网关为: 192.168.164.100
如下图所示:
则这台主机即可利用配置好的nat代理上网了
 
http://blog.csdn.net/tge7618291/article/details/5616884
 
content:
    0. 本次配置的网络的拓扑结构:
    1. 配置IP地址
    .   1.1 正确配置学校分配的IP使能正常上网
    .   1.2 新增eth0别名设备eth0:0
    .   1.3 配置后 查看一下是否配置成功:
    2. 配置路由
    3. 配置NAT
    4. 大功告成
    5. 配置客户机(可以是windows或linux等其它系统)


0. 本次配置的网络的拓扑结构:
#
#             |
#             |
#     ========+===============
#             |10.3.10.0/24
#             |
#             |
#             |10.3.10.19
#        +----+----+            +-------+        +-------+
#        |         |            |       |        |       |
#        | linux   |            | win1  |        | win2  |
#        | (NAT)   |            |       |        |       |
#        +----+----+            +---+---+        +---+---+
#             |192.168.50.1         |192.168.50.2    |192.168.50.3
#             |                     |                |
#             |                     |                |
#             |                     |                |
#   ==========+=====================+================+============
#                    192.168.50.0/24
#
#


1. 配置IP地址
1.1 正确配置学校分配的IP使能正常上网
1)  按学校分配的IP地址配置好Linux主机
[~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
| DEVICE=eth0              |
| BOOTPROTO=none           |
| HWADDR=00:1E:90:13:E0:25 |
| IPADDR=10.3.10.19        |
| NETMASK=255.255.255.0    |
| GATEWAY=10.3.10.254      |
| ONBOOT=yes               |
| TYPE=Ethernet            |
| DNS1=211.64.120.2        |
| DEFROUTE=yes             |
| DOMAIN=168.96.1.1        |

2)  重起网卡
[~]# servie network restart

note: 经过以上的配置, Linux主机应该能够正常上网了!

1.2 新增eth0别名设备eth0:0
[~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
| # eth0:0 必须要用''括起来: 'eth0:0' |
| DEVICE='eth0:0'                            |
| ONBOOT=yes                                 |
| BOOTPROTO=static                           |
| IPADDR=192.168.50.1                        |
| NETMASK=255.255.255.0                      |
| USERCTL=no                                 |



1.3 配置后 查看一下是否配置成功:
[~]# ifconfig
| eth0      Link encap:Ethernet  HWaddr 00:1E:90:13:E0:25                     |
|           inet addr:10.3.10.19  Bcast:10.3.10.255  Mask:255.255.255.0       |
|           inet6 addr: fe80::21e:90ff:fe13:e025/64 Scope:Link                |
|           UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1        |
|           RX packets:187685 errors:0 dropped:0 overruns:0 frame:0           |
|           TX packets:137327 errors:0 dropped:0 overruns:0 carrier:0         |
|           collisions:0 txqueuelen:1000                                      |
|           RX bytes:134816893 (128.5 MiB)  TX bytes:56066393 (53.4 MiB)      |
|           Interrupt:27 Base address:0xa000                                  |

| eth0:0    Link encap:Ethernet  HWaddr 00:1E:90:13:E0:25                     |
|           inet addr:192.168.50.1   Bcast:192.168.50.255  Mask:255.255.255.0 |
|           UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1        |
|           Interrupt:27 Base address:0xa000                                  |

2. 配置路由
由于在配置网卡接口时, 已自动配置一定的路由, 所以我们只需查看一下其信息, 验证其
是否已经被正确配置:
[root ~]$ route
 Kernel IP routing table
 Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
 192.168.50.0    *               255.255.255.0   U     0      0        0 eth0
 10.3.10.0       *               255.255.255.0   U     1      0        0 eth0
 link-local      *               255.255.0.0     U     1002   0        0 eth0
 default         10.3.10.254     0.0.0.0         UG    0      0        0 eth0


3. 配置NAT
1)  新建nat.sh脚本文件并保存在 /usr/local/nat/ 目录下:
[~]# cat /usr/local/nat/nat.sh
| #!/bin/bash                                                           |

| # 0. 设定你的参数值                                            |
| EXIF='eth0'           # 这个是对外的网卡接口, 可能是'ppp0'等     |
| EXNET='192.168.50.0/24'       # 这个是对内的网段                    |

| # 底下如无需要, 请不要改动了!                             |
| # 1. 启动routing等                                                 |
| echo 1 > /proc/sys/net/ipv4/ip_forward                              |
| /sbin/iptables -F                                                     |
| /sbin/iptables -X                                                     |
| /sbin/iptables -Z                                                     |
| /sbin/iptables -F -t nat                                              |
| /sbin/iptables -X -t nat                                              |
| /sbin/iptables -Z -t nat                                              |
| /sbin/iptables -P INPUT   ACCEPT                                      |
| /sbin/iptables -P OUTPUT  ACCEPT                                      |
| /sbin/iptables -P FORWARD ACCEPT                                      |
| /sbin/iptables -t nat -P PREROUTING   ACCEPT                            |
| /sbin/iptables -t nat -P POSTROUTING  ACCEPT                           |
| /sbin/iptables -t nat -P OUTPUT       ACCEPT                                |

| # 2. 载入模组                                                     |
| /sbin/modprobe ip_tables 2> /dev/null                                 |
| /sbin/modprobe ip_nat_ftp 2> /dev/null                                |
| /sbin/modprobe ip_nat_irc 2> /dev/null                                |
| /sbin/modprobe ip_conntrack 2> /dev/null                              |
| /sbin/modprobe ip_conntrack_ftp 2> /dev/null                          |
| /sbin/modprobe ip_conntrack_irc 2> /dev/null                          |

| # 3. 启动ip伪装                                                   |
| /sbin/iptables -t nat -A POSTROUTING -o $EXIF -s $EXNET -j MASQUERADE |

2)  增加可执行权限
[~]# chmod +x /usr/local/nat/nat.sh

4. 大功告成
1)  Linux主机配置完成, 现在只需重新启动一下刚才的配置:
[~]# servie network restart
[~]# /usr/local/nat/nat.sh

2)  为了使得开机即可运行, 可在 /etc/rc.d/rc.local 文件加入相应的命令:
[~]# echo "/usr/local/nat/nat.sh" >> /etc/rc.d/rc.local

5. 配置客户机(可以是windows或linux等其它系统)
    1. network 设定需要为:  192.168.50.0

    2. broadcast 设定需要为:  192.168.50.255

    3. netmask 设定需要为 255.255.255.0

    4. IP 设定需要为 192.168.50.1 ~ 192.168.50.254 之一, 且『不能重复』

    5. Gateway 或者要设定为你的 Linux 的对内 IP , 以我的例子来说, 就是
    192.168.50.1

    6. DNS 的设定: 这个最容易出错了, 你的 DNS 设定需要是你的 ISP 给你的 DNS
    IP, 如果你不知道的话, 可以填入 168.95.1.1 这一个中华电信的 DNS 或者是
    139.175.10.20 这一个 SeedNet 的 DNS 即可!千万不要设定为 192.168.1.2 呦!会
    连不出去!


see also:
http://www.chinaitlab.com/www/special/linux11.asp#7
 
 

转载于:https://www.cnblogs.com/virusolf/p/4754230.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值