了解sed的工作原理(pattern space 和 hold space)

作者:sealinger 发布时间:February 27, 2011 分类:混口饭吃

sed是一个非交互式的流编辑器(stream editor)。所谓非交互式,是指使用sed只能在命令行下输入编辑命令来编辑文本,然后在屏幕上查看输出;而所谓流编辑器,是指sed每次只从文件(或输入)读入一行,然后对该行进行指定的处理,并将结果输出到屏幕(除非取消了屏幕输出又没有显式地使用打印命令),接着读入下一行。整个文件像流水一样被逐行处理然后逐行输出。

sed一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区(pattern space)中的内容,处理完成后,把缓冲区(pattern space)的内容送往屏幕。接着清空缓冲区(pattern space),处理下一行,这样不断重复,直到文件末尾。

pattern space(模式空间)相当于车间sed把流内容在这里处理
hold space(保留空间)相当于仓库,加工的半成品在这里临时储存(当然加工完的成品也在这里存储)

How sed Works:


先读入一行,去掉尾部换行符,存入pattern space,执行编辑命令。
处理完毕,除非加了-n参数,把现在的pattern space打印出来,在后边打印曾去掉的换行符。
把pattern space内容给hold space,把pattern space置空。
接着读下一行,处理下一行。

一种非平凡情况,一个文件仅一行,尾部没换行,sed只打印,不会尾部加换行,但若在尾部又附加了输出,他会再补上那个换行。

经典实例解释:


下面的解释小而简洁,但是可以将它作为一个准则,帮助你理解sed命令。

SED在哪里缓存数据

SED维护两个数据缓冲区:主动模式空间(pattern space)和辅助保留空间(hold space)。在“通常”操作中,SED从输入流读取一行存入pattern space,这里就是文本编辑操作发生的地方。hold space最初是空的,但也有在pattern space和hold space直接移动数据的命令。

这里,我们用SED的“x”命令来做一个小实验:

'x'  - 交换pattern space和hold space的内容

一个文件包含三行:

#cat file
line1
line2
line3
#

用SED x 命令操作后:
#sed 'x' file



line1
line2
#

解释:

#sed 'x' file 
        <-- 第一行是空的,因为hold space和pattern space交换了内容,记住最初的时候hold space是空的;在处理完第一行后,现在hold space的内容是line1。
line1    <-- 第二行输出是line1,现在hold space的内容是line2,and so on a so forth . ^_^
line2
#

------------------

操作pattern space和hold space的命令:


$ man sed
       d      Delete pattern space.  Start next cycle.
              删除pattern space的内容,开始下一个循环.

       h H    Copy/append pattern space to hold space.
              复制/追加pattern space的内容到hold space.
       g G    Copy/append hold space to pattern space.
              复制/追加hold space的内容到pattern space.
       x      Exchange the contents of the hold and pattern spaces.
              交换hold space和pattern space的内容.

课后理解:


1)交换第1行和第2行的内容


$ sed -n '1{h;n;x;H;x};p' filename

2)用sed实现tac的功能


$ sed -n -e '1!G;h;$p' filename

$ sed -e '1!G;h;$!d' filename

这2种写法都相当于tac filename。

---------------------------------

引用资料:

# info sed

File: sed.info,  Node: Execution Cycle,  Next: Addresses,  Up: sed Programs

How `sed' Works
===============

   `sed' maintains two data buffers: the active _pattern_ space, and
the auxiliary _hold_ space. Both are initially empty.

   `sed' operates by performing the following cycle on each lines of
input: first, `sed' reads one line from the input stream, removes any
trailing newline, and places it in the pattern space.  Then commands
are executed; each command can have an address associated to it:
addresses are a kind of condition code, and a command is only executed
if the condition is verified before the command is to be executed.

   When the end of the script is reached, unless the `-n' option is in
use, the contents of pattern space are printed out to the output
stream, adding back the trailing newline if it was removed.(1) Then the
next cycle starts for the next input line.

   Unless special commands (like `D') are used, the pattern space is
deleted between two cycles. The hold space, on the other hand, keeps
its data between cycles (see commands `h', `H', `x', `g', `G' to move
data between both buffers).


 

-------------------

following explaination could be small but concise , can treat it as a guideline when you study all the sed commands.

Where SED buffers data
SED maintains two data buffers: the active pattern space, and the auxiliary hold space. In "normal" operation, SED reads in one line from the input stream and places it in the pattern space. This pattern space is where text manipulations occur. The hold space is initially empty, but there are commands for moving data between the pattern and hold spaces.

right, a small practice here for SED command "x" :
'x'  - Exchange the contents of the hold and pattern spaces.

say a file contains following 3 lines ,
#cat file
line1
line2
line3
#
by applying 'x' command, the output is as following :
#sed 'x' file

line1
line2
#
explain :

            <-- first line is empty , because hold space and pattern space exchange the contents , do remember initially the hold space is empty , now hold space contains line1 after first line data manipulation .
line1     <- second output is line1, now hold space contains line2 , and so on a so forth . ^_^
line2

洗了个牙,清爽多了

作者:sealinger 发布时间:February 20, 2011 分类:简单生活

这周末都在跑医院。今天洗了个牙,过程有些痛苦:保持口型、调整呼吸、忍受酸痛,使得全身紧张,四肢僵硬。坚持了半个钟后,看着洗掉的牙结石,感觉很爽!

不经历风雨,怎么见彩虹呢?想要得到,必先付出啊。。。。

【转】sed学习笔记

作者:sealinger 发布时间:February 15, 2011 分类:混口饭吃

本想自己记录几个例子,还是在别人好文章的基础上修改吧,感谢原作者。不一定完全记住,知道sed能做什么,需要时回头翻翻参考即可。

原文作者:Jims of 肥肥世家 <jims.yang@gmail.com>




1. Sed简介


sed是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。以下介绍的是Gnu版本的Sed 3.02。

2. 定址


可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美元符号($)表示最后一行。范围可以通过数据,正则表达式或者二者结合的方式确定 。

3. Sed命令


调用sed命令有两种形式:
  • sed [options] 'command' file(s)
  • sed [options] -f scriptfile file(s)

 
a\
在当前行后面加入一行文本。

b lable
分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。

 

c\
用新的文本改变本行的文本。
d
从模板块(Pattern space)位置删除行。
D
删除模板块的第一行。
i\
在当前行上面插入文本。
h
拷贝模板块的内容到内存中的缓冲区。
H
追加模板块的内容到内存中的缓冲区
g
获得内存缓冲区的内容,并替代当前模板块中的文本。
G
获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l
列表不能打印字符的清单。
n
读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N
追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p
打印模板块的行。
P(大写)
打印模板块的第一行。
q
退出Sed。
r file
从file中读行。
t label
if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
T label
错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
w file
写并追加模板块到file末尾。
W file
写并追加模板块的第一行到file末尾。
!
表示后面的命令对所有没有被选定的行发生作用。
s/re/string
用string替换正则表达式re。
=
打印当前行号码。
#
把注释扩展到下一个换行符以前。
以下的是替换标记
  • g表示行内全面替换。
  • p表示打印行。
  • w表示把行写入一个文件。
  • x表示互换模板块中的文本和缓冲区中的文本。
  • y表示把一个字符翻译为另外的字符(但是不用于正则表达式)

4. 选项


-e command, --expression=command
允许多台编辑。

-h, --help
打印帮助,并显示bug列表的地址。

 

-n, --quiet, --silent
取消默认输出。
-f, --filer=script-file
引导sed脚本文件名。
-V, --version
打印版本和版权信息。

5. 元字符集


^
锚定行的开始 如:/^sed/匹配所有以sed开头的行。

$
锚定行的结束 如:/sed$/匹配所有以sed结尾的行。

 (sealinger注:也可匹配最后一行(Match the last line.))

.
匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d。
*  (sealinger注:这里有点错误 )
原文:匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
应为:*用来修饰它前面的字符,表示它前面的正则表达式能出现零次或多次,并且匹配任意一个(包括零个)在他前面的字符。举个例子:
$ cat sed.txt
curlcurl
curl
curlll
cur
$ sed -n '/curl*/p' sed.txt 
curlcurl
curl
curlll
cur
$
.* (sealinger补充:.* 就是匹配零个或多个字符了。)
匹配零个或多个字符,如/sed.*/匹配sed和sedabc。
[]
匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。
[^]
匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\)
保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
&
保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\<
锚定单词的开始,如:/\<love/匹配包含以love开头的单词的行。
\>
锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\}
重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。
x\{m,\}
重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。
x\{m,n\}
重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。

6. 实例


删除:d命令
  • $ sed '2d' example-----删除example文件的第二行。
  • $ sed '2,$d' example-----删除example文件的第二行到末尾所有行。
  • $ sed '$d' example-----删除example文件的最后一行。
  • $ sed '/test/'d example-----删除example文件所有包含test的行。
替换:s命令
  • $ sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。
  • $ sed -n 's/^test/mytest/p' example----- (-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。
  • $ sed 's/^192.168.0.1/&localhost/' example-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加localhost,变成192.168.0.1localhost。
  • $ sed -n 's/\(love\)able/\1rs/p' example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。
  • $ sed 's#10#100#g' example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。
选定行的范围:逗号
  • $ sed -n '/test/,/check/p' example-----所有在模板test和check所确定的范围内的行都被打印。
  • $ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。
  • $ sed '/test/,/check/s/$/sed test/' example-----对于模板test和west之间的行,每行的末尾用字符串sed test替换。
  • $ sed -i '/<!--/,/-->/d' example -----删除<!--和-->之间的内容,删除注释时很好用。(sealinger补充)
多点编辑:e命令
  • $ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。
  • $ sed --expression='s/test/check/' --expression='/love/d' example-----一个比-e更好的命令是--expression。它能给sed表达式赋值。
从文件读入:r命令
  • $ sed '/test/r file' example-----file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。
写入文件:w命令
  • $ sed -n '/test/w file' example-----在example中所有包含test的行都被写入file里。
追加命令:a命令
  • $ sed '/^test/a\this is a new line' example'this is a new line'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。
插入命令:i命令
$ sed '/test/i\this is a new line' example

如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。

下一个:n命令
  • $ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。
变形:y命令
  • $ sed '1,10y/abcde/ABCDE/' example-----把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。这个读者需要自己试验下(sealinger注):
           y/source/dest/
                  Transliterate the characters in the pattern space which appear in source to the corresponding character in dest.
退出:q命令
  • $ sed '10q' example-----打印完第10行后,退出sed。
保持和获取:h命令和G命令
  • $ sed -e '/test/h' -e '$G' example-----在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。这个读者最好自己试验下(sealinger注):试验结果为只有最后一个匹配的行,被追加到文件末尾。
保持和互换:h命令和x命令
  • $ sed -e '/test/h' -e '/check/x' example -----互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。这个读者最好自己试验下(sealinger注):试验结果为包含test的行替换了包含check的行。

7. 脚本


Sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。

8. 小技巧


  • 在sed的命令行中引用shell变量时要使用双引号,而不是通常所用的单引号。下面是一个根据name变量的内容来删除named.conf文件中zone段的脚本:
    name='zone "localhost"'
    sed "/$name/,/};/d" named.conf

利用iptables根据目的地址转换出去的源IP(SNAT)

作者:sealinger 发布时间:February 14, 2011 分类:混口饭吃

1、先说一下背景,了解一下老外对IP的一个使用技巧。


租用的美国服务器,除了有一个主IP,还有8个Secondary IP,这个8个Secondary IP的掩码,都是255.255.255.255。这些Secondary IP从外部能被正常的访问,跟资深网络工程师讨论后,得知其妙处,不得不佩服老外就是老外,对计算机网络这种人家创造的东东,就是比我们牛啊:

1)这8个连续的IP,划到一个子网中,就是 xxx.xxx.xxx.xxx/29,即掩码为 255.255.255.248 的一段IP,且连子网号和广播地址都用上了,节约IP资源;

2)这一段IP,以路由模式传递给我的服务器的主IP上,所以减少了ARP广播;

3)这一段IP,只能在我的机器上使用,因为绑定了我的主IP,只能随主IP使用,别人用不了;

4)收回了主IP,也就收回了这8个Secondary IP,方便管理。

举个实例:

1)我的主IP是 67.228.xxx.99,掩码 255.255.255.224,网关为 67.228.xxx.97;

2)另外8个辅IP是 174.37.xxx.224 到 174.37.xxx.231,掩码 255.255.255.255:

# cat /etc/sysconfig/network-scripts/ifcfg-eth1-range0
IPADDR_START=174.37.xxx.224
IPADDR_END=174.37.xxx.231
CLONENUM_START=0
NETMASK=255.255.255.255

留意到,这些网卡接口eth1:0~eth1:7启动后,其上显示广播地址都是174.37.xxx.224。

我们的问题:

虽然额外分配给我了8个辅IP,但是这8个IP,只能从外部主动访问到,从服务器主动请求外部服务的时候,是不会以这些IP作为源IP地址出去的,因为路由(网关)的关系:

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
67.228.xxx.96   0.0.0.0         255.255.255.224 U     0      0        0 eth1
10.16.23.0      0.0.0.0         255.255.255.128 U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth1
10.0.0.0        10.16.23.1      255.0.0.0       UG    0      0        0 eth0
0.0.0.0         67.228.xxx.97   0.0.0.0         UG    0      0        0 eth1
#

当我的服务器作为代理,想利用这些IP,从而减少被网站因为频繁访问而屏蔽的几率,我希望使用这些Secondary IP出去访问网站,此时就出现了一个源地址转换的需求。

2、使用iptables根据目的地址对服务器出口源地址进行转换


根据《iptables笔记》一文,可以得知我们需要在NAT表的POSTROUTING链中作SNAT操作,即可达到这个目的:
iptables -t nat -A POSTROUTING -o eth1 -p tcp -d 173.212.255.138 \
  -j SNAT --to-source 174.37.xxx.224-174.37.xxx.231

查看web服务器的access log,来源IP已被改变,而且是轮询的:
$ tail    sealinger.com.access.log
174.37.xxx.225 - - [14/Feb/2011:00:25:42 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.226 - - [14/Feb/2011:00:26:28 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.227 - - [14/Feb/2011:00:26:30 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.228 - - [14/Feb/2011:00:26:44 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.229 - - [14/Feb/2011:00:26:45 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.230 - - [14/Feb/2011:00:26:47 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.231 - - [14/Feb/2011:00:26:48 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.224 - - [14/Feb/2011:00:26:51 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.225 - - [14/Feb/2011:00:26:53 +0800] "GET / HTTP/1.0" 200 79041 "-"
174.37.xxx.226 - - [14/Feb/2011:00:26:54 +0800] "GET / HTTP/1.0" 200 79041 "-"

【转】iptables笔记

作者:sealinger 发布时间:February 11, 2011 分类:混口饭吃

不错的文章,转了。修改了原文章的一些笔误,又根据另一篇《iptables笔记2》做了一些补充。

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
原文链接:http://aneya.blogbus.com/logs/65536626.html

一、netfilter/iptable的理解

    这个当初我理解不了,主要是没把netfilter理解清楚。 Netfilter是集成在内核中的,用来定义存储各种规则的。Iptalbe是修改这些规则的工具,修改后存在netfilter里面。数据包进入LINUX服务器时,先进入服务器的netfilter模块中进行判断处理。

   Netfilter包含有三种表,三种表下共包含有五种链,链下面包含各种规则。即表包含若干链,链包含若干规则。

  (一)三种表为:filter   nat  mangle

 1、filter:处理与本机有关的数据包,是默认表,包含有三种链:input   output forward

 2、nat表:与本机无关。主要处理源与目的地址IP和端口的转换。有三种链:prerouting  postrouting output

 3、mangle表:用于高级路由信息包,如包头内有更改(如tos改变包的服务类型,ttl包的生存时间,mark特殊标记)。有两种链:prerouting  output  (kernel  2.4.18后又加了两种链:input forward)这种表很少使用。

   (二)五种链(链在表下面,为了条理清晰,才另外作一大点讲解)

   1、prerouting:进入netfilter后的数据包在进入路由判断前执行的规则。改变包。

 2、Input:当经过路由判断后,要进入本机的数据包执行的规则。

 3、output:由本机产生,需向外发的数据包执行的规则。

 4、forward:经过路由判断后,目的地不是本机的数据包执行的规则。与nat 和 mangle表相关联很高,与本机没有关联。

 5、postrouting:经过路由判断后,发送到网卡接口前。即数据包准备离开netfilter时执行的规则。

   上图中,运行中的守护进程,是指本机。Input的包都会发到本机。本机处理后再经output 发出去。

   (三)数据包进入netfilter后的经过图:

   1、数据包进入linux服务器入接口,接口把数据包发往netfilter,数据包就此进入netfilter。

 2、经prerouting处理,(如是否需要更改数据包的源IP地址等)

 3、数据包到路由,路由通过路由表判断数据包的目的地。如果目的地是本机,就把数据包转给intput处理后进入本机。如果目的地不是本机,则把数据包转给forward处理。

 4、数据包通过forward处理后,再转给postrouting处理,(是否有目标地址需要改变等),处理后数据包就出了netfilter,到linux服务器出接口,就出了linux服务器。

 5、如果数据包进了本机后经过处理需要外发数据包,或本机自身有数据包需要外发,就把数据包发给output链进行处理后,转给postrouting处理后,出linux服务器。进入外面的花花世界。

   (四)规则的执行顺序

当数据包进入netfilter,就会和里面的规则进行对比。规则是有顺序的。

先和规则1对比,如果和规则1相匹配,被规则1接受(accept),则数据将不再和后面的规则进行对比。如果不匹配,则按顺序和后面的规则进行对比,直到被接受。如果所有的规则都不匹配,则进行默认策略操作,以决定数据包的去向。所以规则的顺序很重要。

    IPTABLE主要是理解上面的内容,一些详细参数可以见附件中的指南。

  二、iptalbe语法及参数

iptable [-t table] command [chain] [match][-j target]
注释:iptable [-t 表名] -命令 [链接] [匹配] [-j 动作/目标]

(一) table  (表)

1、filter表:默认用filter表执行所有的命令。只操作与本机有关的数据包。
2、nat表:主要用于NAT地址转换。只有数据流的第一个数据包被这个链匹配,后面的包会自动做相同的处理。
  分为:DNAT(目标地址转换)、SNAT(源地址转换)、MASQUERADE

(1)DNAT操作主要用在这样一种情况,你有一个合法的IP地址,要把对防火墙的访问 重定向到其他的机子上(比如DMZ)。也就是说,我们改变的是目的地址,以使包能重路由到某台主机。

(2)SNAT 改变包的源地址,这在极大程度上可以隐藏你的本地网络或者DMZ等。内网到外网的映射。

(3)MASQUERADE 的作用和SNAT完全一样,只是计算机的负荷稍微多一点。因为对每个匹配的包,MASQUERADE都要查找可用的IP地址,而不象SNAT用的IP地址是配置好的。当然,这也有好处,就是我们可以使用通过PPP、 PPPOE、SLIP等拨号得到的地址,这些地址可是由ISP的DHCP随机分配的。

3、mangle表:用来改变数据包的高级特性,一般不用。

(二) command(命令)详解 
1、 -A或者--append     //将一条或多条规则加到链尾
2、 -D或者--delete     //从链中删除该规则
3、 -R或者--replace   //从所选链中替换一条规则
4、 -L或者--list       //显示链的所有规则
5、 -I或者--inset     //根据给出的规则序号,在链中插入规则。按序号的顺序插入,如是 “1”就插入链首
6、 -X或者--delete-chain  //用来删除用户自定义链中规则。必须保证链中的规则都不在使用时才能删除链。如没有指定链,将删除所有自定义链中的规则。
7、 -F或者--flush        //清空所选链中的所有规则。如指定链名,则删除对应链的所有规则。如没有指定链名,则删除所有链的所有规则。
8、 -N或者--new-chain      //用命令中所指定的名字创建一个新链。
9、 -P或者--policy        //设置链的默认目标,即策略。 与链中任何规则都不匹配的信息包将强制使用此命令中指定的策略。
10、-Z或者--zero        //将指定链中的所有规则的包字节计数器清零。

(三) match 匹配

分为四大类:通用匹配、隐含匹配、显示匹配、针对非正常包的匹配

1、通用匹配

   无论我们使用何种协议,装入何种扩展,通用匹配都可以使用。不需要前提条件

(1) -p(小写)或--protocol  

用来检查某些特定协议。协议有TCP\UDP\ICMP三种。可用逗号分开这三种协议的任何组合。也可用“!”号进行取反,表示除该协议外的剩下的协议。也可用all表示全部协议。默认是all,但只代表tcp\udp\icmp三种协议。

$ iptable -A INPUT -p TCP,UDP
$ iptable -A INPUT -p ! ICMP     //这两种表示的意思为一样的。

(2) -s 或 --source

以Ip源地址匹配包。根据源地址范围确定是否允许或拒绝数据包通过过滤器。可使用 “!”符号。    默认是匹配所有ip地址。
可是单个Ip地址,也可以指定一个网段。  如: 192.168.1.1/255.255.255.255  表示一个地址。   192.168.1.0/255.255.255.0  表示一个网段。

(3) -d  或 --destination 

用目的Ip地址来与它们匹配。与  source 的格式用法一样

(4)  -i 

   以包进入本地所使用的网络接口来匹配包。只能用INPUT \ FORWARD \PREROUTING 三个链中。用在其他任何链中都会出错。
   可使用“+”  “!”两种符号。
  只用一个“+"号,表示匹配所有的包,不考虑使用哪个接口。如: iptable -A INPUT  -i +  //表匹配所有的包。
  放在某类接口后面,表示所有此类接口相匹配。如:    iptable  -A INPUT -i eth+   //表示匹配所有ethernet 接口。

(5)  -o   
  以数据包出本地所使用的网络接口来匹配包。与-i一样的使用方法。
   只能用OUTPUT \ FORWARD \POSTROUTING 三个链中。用在其他任何链中都会出错。
   可使用“+”  “!”两种符号。 

 (6)  -f  (或  --fragment )

      用来匹配一个被分片的包的第二片或以后的部分。因一个数据包被分成多片以后,只有第一片带有源或目标地址。后面的都不带 ,所以只能用这个来匹配。可防止碎片攻击。

2、隐含匹配

   这种匹配是隐含的,自动的载入内核的。如我们使用 --protocol tcp  就可以自动匹配TCP包相关的特点。
   分三种不同协议的隐含匹配:tcp   udp  icmp

  2.1   tcp match

       tcp match 只能隐含匹配TCP包或流的细节。但必须有  -p tcp 作为前提条件。

   (2.1.1)  TCP --sport  

            基于tcp包的源端口匹配包  ,不指定此项则表示所有端口。

            iptable -A INPUT -p  TCP  --sport   22:80    //TCP源端口号22到80之间的所有端口。
            iptable -A INPUT -p  TCP  --sport   22:      //TCP源端口号22到65535之间的所有端口。     

   (2.1.2)  TCP --dport  

            基于tcp包的目的端口来匹配包。   与--sport端口用法一样。

    (2.1.3)  TCP --flags  

            匹配指定的TCP标记。 

            iptable  -p  TCP --tcp-flags  SYN,FIN,ACK   SYN

   2.2   UDP match

       (2.1.1)  UDP --sport  

            基于UDP包的源端口匹配包  ,不指定此项则表示所有端口。
      
        (2.1.1)  UDP --dport  

            基于UDP包的目的端口匹配包  ,不指定此项则表示所有端口。

   2.3   icmp match

       icmp --icmp-type   

       根据ICMP类型包匹配。类型 的指定可以使用十进制数或相关的名字,不同的类型,有不同的ICMP数值表示。也可以用“!”取反。

例:      iptable  -A INPUT  -p icmp-imcp-type 8 

  3、显示匹配

    显示匹配必须用  -m装 载。 

     (1)limit match   
       必须用 -m limit 明确指出。  可以对指定的规则的匹配次数加以限制。即,当某条规则匹配到一定次数后,就不再匹配。也就是限制可匹配包的数量。这样可以防止DOS攻击。
       限制方法: 设定对某条规则 的匹配最大次数。设一个限定值 。 当到达限定值以后,就停止匹配。但有个规定,在超过限制次数后,仍会每隔一段时间再增加一次匹配次数。但增加的空闲匹配数最大数量不超过最大限制次数。

        --limit rate
          最大平均匹配速率:可赋的值有'/second', '/minute', '/hour', or '/day'这样的单位,默认是3/hour。

        --limit-burst number
         待匹配包初始个数的最大值:若前面指定的极限还没达到这个数值,则概数字加1.默认值为5

    iptable -A INPUT -m limit --limt 3/hour    //设置最大平均匹配速率。也就是单位时间内,可匹配的数据包个数。   --limt 是指定隔多 长时间发一次通行证。
    iptable -A INPUT  -m limit --limit-burst 5  //设定刚开始发放5个通行证,也最多只可匹配5个数据包。

   (2) mac match

        只能匹配MAC源地址。基于包的MAC源地址匹配包

   iptable -A  INPUT -m mac  --mac-source   00:00:eb:1c:24     //源地址匹配些MAC地址

    (3)  mark match

       以数据包被 设置的MARK来匹配包。这个值由  MARK TARGET 来设置的。

  (4)  multiport match

         这个模块匹配一组源端口或目标端口,最多可以指定15个端口。只能和-p tcp 或者 -p udp 连着使用。
 

        多端口匹配扩展让我们能够在一条规则里指定不连续的多个端口。如果没有这个扩展,我们只能按端口来写规则了。这只是标准端口匹配的增强版。不能在一条规则里同时用标准端口匹配和多端口匹配。

 三个选项:   --source-port   ;  --destination-port  ;   --port

        iptable  -A INPUT  -p TCP   -m  multiport  --source-port 22,28,115       
        iptable  -A INPUT  -p TCP   -m  multiport  --destination-port 22,28,115 
        iptable  -A INPUT  -p TCP   -m  multiport  --port 22,28,115

  (5) state match

       状态匹配扩展要有内核里的连接跟踪代码的协助。因为是从连接跟踪机制得到包的状态。这样不可以了解所处的状态。

 (6)  tos match

       根据TOS字段匹配包,用来控制优先级。 

 (7)   ttl match

     根据IP头里的TTL字段来匹配包。

用来更改包的TTL,有些ISP根据TTL来判断是不是有多台机器共享连接上网。

   iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-set 64
   iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-dec 1
   # 离开防火墙的时候实际上TTL已经-2了,因为防火墙本身要-1一次。
   iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1
   # 离开防火墙的时候不增不减,tracert就不好用了,呵呵。

(8) owner match

基于包的生成者(即所有者或拥有者)的ID来匹配包。 
owner 可以是启动进程的用户的ID,或用户所在的级的ID或进程的ID,或会话的ID。此只能用在OUTPUT 中。
此模块设为本地生成包匹配包创建者的不同特征。而且即使这样一些包(如ICMP ping应答)还可能没有所有者,因此永远不会匹配。

--uid-owner userid
如果给出有效的user id,那么匹配它的进程产生的包。

--gid-owner groupid
如果给出有效的group id,那么匹配它的进程产生的包。

--sid-owner seessionid
根据给出的会话组匹配该进程产生的包。

( 四) targets/jump  

  指由规则指定的操作,对与规则匹配的信息包执行什么动作。

  1、accept

这个参数没有任何选项。指定  -j accept 即可。 
一旦满 足匹配不再去匹配表或链内定义的其他规则。但它还可能会匹配其他表和链内的规则。即在同一个表内匹配后就到上为止,不往下继续。

2、drop 

-j drop   当信息包与规则完全匹配时,将丢弃该 包。不对它做处理。并且不向发送者返回任何信息。也不向路由器返回信息。

3、reject

与drop相同的工作方式,不同的是,丢弃包后,会发送错误信息给发送方。

   iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with icmp-net-unreachable
  
4、DNAT

用在prerouting链上。
做目的网络地址转换的。就是重写目的的IP地址。
如果一个包被匹配,那么和它属于同一个流的所有的包都会被自动转换。然后可以被路由到正确的主机和网络。
也就是如同防火墙的外部地址映射。把外部地址映射到内部地址上。

iptables -t nat   -A PREROUTING   -d 218.104.235.238 -p TCP  --dport 110,125    -j DNAT --to-destination  192.168.9.1 
//把所有访问218.104.235.238地址  110.125端口的包全部转发到 192.168.9.1上。

--to-destination   //目的地重写

5、SNAT

用在nat 表的postrouting链表。这个和DNAT相反。是做源地址转换。就是重写源地址IP。 常用在内部网到外部网的转换。

--to-source 

iptables -t nat POSTROUTING  -o eth0 -p tcp  -j SNAT --to-source 218.107.248.127  //从eth0接口往外发的数据包都把源地址重写为218.107.248.127

********************

   iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.9
   # 将所有的访问15.45.23.67:80端口的数据做DNAT发到192.168.1.9:80
   如果和192.168.1.9在同一内网的机器要访问15.45.23.67,防火墙还需要做设置,改变源IP为防火墙内网IP 192.168.1.1。否则数据包直接发给内网机器,对方将丢弃。
   iptables -t nat -A POSTROUTING -p tcp --dst 15.45.23.67 --dport 80 -j SNAT --to-source 192.168.1.1
   # 将所有的访问15.45.23.67:80端口的数据包源IP改为192.168.1.1
   如果防火墙也需要访问15.45.23.67:80,则需要在OUTPUT链中添加,因为防火墙自己发出的包不经过PREROUTING。
   iptables -t nat -A OUTPUT --dst 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.9

********************

6、MASQUERADE

masquerade 的作用和 SNAT的作用是一样的。 区别是,他不需要指定固定的转换后的IP地址。专门用来设计动态获取IP地址的连接的。
MASQUERADE的作用是,从服务器的网卡上,自动获取当前ip地址来做NAT
如家里的ADSL上网,外网的IP地址不是固定的,你无法固定的设定NAT转换后的IP地址。这时就需要用masquerade来动态获取了。

iptables -t nat -A POSTROUTING  -s 192.168.1.0/24 -j masquerade      //即把192.168.1.0 这个网段的地址都重写为动态的外部IP地址。

7、REDIRECT 

只能在NAT表中的PREROUTING  OUTPUT 链中使用
在防火墙所在的机子内部转发包或流到另一个端口。比如,我们可以把所有去往端口HTTP的包REDIRECT到HTTP proxy(例如squid),当然这都发生在我们自己的主机内部。

--to-ports

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

不使用这个选项,目的端口不会被改变。

指定一个端口,如--to-ports 8080

指定端口范围,如--to-ports 8080-8090

8、RETURN

顾名思义,它使包返回上一层,顺序是:子链——>父链——>缺省的策略。具体地说,就是若包在子链中遇到了RETURN,则返回父链的下一条规则继续进行条件的比较,若是在父链(或称主链,比如INPUT)中遇到了RETURN,就要被缺省的策略(一般是ACCEPT或DROP)操作了。(译者注:这很象C语言中函数返回值的情况)

9、MIRROR

 颠倒IP头中的源地址与目的地址,再转发。

10、LOG

 在内核空间记录日志,dmesg等才能看。

11、ULOG

 在用户空间记录日志。

(五)IP转发功能

打开转发IP功能(IP forwarding):

echo "1" > /proc/sys/net/ipv4/ip_forward

如果使用PPP、DHCP等动态IP,需要打开:

echo "1" > /proc/sys/net/ipv4/ip_dynaddr