Profil de 军tell you a story to make...PhotosBlogListesPlus Outils Aide

Blog


28 janvier

iptables运行流程小结

前几天稍稍了解了iptable的功能以及基本的命令。但是实际操作过程当中,对于iptable中的三个table的具体分工还不是很了解,而且iptables工作时的流程也没有一个详尽的认识,以至于在使用的过程当中概念很模糊,今天查了一下资料,了解到一些信息,记录下来。

iptables产生的功能是针对ipv4的数据包的,进行的操作三个tables的分工,大体如下:

mangle:table mangle的链最多,有5个链,分别为PREROUTING,INPUT,OUTPUT,FORWARD,POSTROUTING。

filter: table filter有三个链,分别为,INPUT,OUTPUT,FORWARD。

nat:table nat有三个链,分别为,PREROUTING,OUTPUT,POSTROUTING。

链的概念:数据包从传进防火墙开始,使用iptables,会经过很多步骤地处理,在这些不同的处理步骤中,应用不同的“链”。下面的图看过之后就很容易理解了。

功能分类

mangle的功能:因为mangle有很多的链,所以它能够做很多的事情,甚至可以取代filter链,因为filter链的功能仔细看就会知道,是mangle链的一个子集。但是,一般mangle不用于过滤包的操作(因为不知道据谁说,即使用这个链来过滤数据报,也会有漏网之鱼通过,估计是程序的缺陷),过滤包的操作留给filter table和nat table来完成。mangle所完成的任务是,在iptables处理ip数据包的时候对数据包头的一些信息进行修改。

nat的功能:nat从名字上看来是进行nat转换作用的,事实上也是如此,使用nat table,能对ip数据报头信息的源地址和目的地址进行修改,达到控制数据报流向的作用。而且在进行转发的时候,因为filter table没有FORWARD链,所以转发的情况之下,过滤的功能就由nat table来进行。

filter的功能:从名字来看,filter table的功能就是过滤ip数据报的作用,事实上也是如此,iptables中,对数据报的过滤基本上都是通过filter table来完成的。包括允许哪些特性的数据包进入系统,哪些数据报能够通过系统发送出去。但是因为没有FORWORD这个链,所以转发的时候的过滤就交给nat 它table 来完成了。filter这个table应该是最重要的一个table。起到主要的作用。

iptables工作流程分析:

因为之前一直不知道iptables的工作流程,所以用的时候郁闷无比,今天查到了一张图,终于很清晰的了解了这一流程。稍稍描述一下,以免以后忘记。

如左边的图所示,iptables的工作流程如下,我们分析一下通过接口收到一个数据报经过iptables会遇到哪些处理:

1,从网络接口处接受到ip数据报。这里的网络接口就是网卡NIC,包括外网,也包括内网,总而言之就是传给防火墙的数据报。

2,PREROUTING首先是mangle table的PREROUTING,然后是nat的。mangle table在这里是做修改ip数据报头信息的作用,当然不包括修改ip地址,因为

这是nat table的作用,nat table在此处的作用是,完成目的地址转换,即将ip数据报中的目的地址根据自己的设定转换成合适的地址(比如防火墙的后面隐藏了一个web服务器,此web服务器用防火墙的ip对外提供web服务,所以,当防火墙收到目的地址为自己的ip地址,端口为80的请求时候,就知道这实际是发给自己后面的web服务器的,那么此时,就可以用nat的PREROUTING链将目的地址转为防火墙后面的服务器的实际地址,发出去。

3,转发选择,PREROUTING之后,iptables判断收到的ip数据报是否是发给自己防火墙本机的,如果是的话,就不需要转发,直接转到INPUT链处理,如果不是发给防火墙的话,就需要转发给其他机器,这个时候就交给FORWORD链处理。

4.1,如果需要转发,那么首先经过mangle和filter的FORWORD链,mangle一般此时不怎么使用,filter根据我们事先设定的条件,对比数据报中的信息,判断,对于收到的这个数据报是否转发,不转发一般就丢弃了。

4.2,如果不转发,那么这个数据报就是发给防火墙的,那么对于防火墙来说,要接收这个包,但是在接收之前,要判断一下,这个数据报的是否符合接收的条件,当然这个条件是我们事先设定好的(比如设定目的端口是22的数据报被抛弃,那么此时经过判断,发现这个数据报正是目的端口是22,那么这个数据报就不能被接受,被抛弃),此处manglehefilter都有INPUT链,一般不使用mangle。那么filter就负责数据报的过滤功能。

5,当防火墙需要对外发送数据报的时候,就要经过OUTPUT链,mangle,filter,nat在OUTPUT链都有自己对应的规则,一般而言使用filter来判断数据报是否能被输出。

6,经过OUTPUT链,或者FORWORD链的时候,数据报即将被发往防火墙之外。这个时候要经过POSTROUTING这个链,在这个链能够起作用的是mangle和nat table。前者我不了解,因为不常用,但是知道后者很重要。个人觉得nat table在POSTROUTING链和PREROUTING链起着非常大的作用,iptables的很多特色就是通过这两个步骤来实现的。nat table在这个链起的作用是在发送数据报出去之前,能够修改数据报的源地址(PREROUTING的时候是修改目的地址),这个功能很重要,能够实现地址欺骗,举例来说,当局域网内的用户希望防火墙做代理服务器,能够共享上网的时候,从局域网用户发来的请求,防火墙不能直接转发过去,因为局域网内部的ip不对外公开(比如192.168.1.2,这样的地址属于特殊的内网专用地址,即使防火墙将192.168.1.2对外网的请求发送了出去,服务器受到请求后,也不知道应该将回答发给谁,因为Internat上并没有192.168.1.2这个地址,这个地址只能用在局域网内),这时,nat 的POSTROUTING链如果将源地址变为防火墙自己的实际对外地址,然后将数据包发送出去的话,那么外网服务器收到请求之后,将回答发送给防火墙,防火墙再转发给内网实际发出请求的用户。这样,就实现了代理服务器的功能。

至此,iptables的工作流程分析完毕。

这个周末本来想研究一下PREROUTING和POSTROUTING的功能,实现地址欺骗或者在外网通过访问防火墙的80端口,从而能够访问防火墙后面局域网中的一台web服务器,无奈感觉太麻烦,还要叫同学在他家不停的访问我的防火墙,来观察功能是否实现。于是采用了另一个测试方法,实现从我的局域网的一台机器A(192.168.1.2),通过访问防火墙(192.168.1.1)的80端口,从而能够访问我的局域网的另一台机器B的web服务器(192.168.1.3)。本来是很简单的一个功能,但是搞了两天才搞定,感觉真是白痴,当然,也由于局域网的特殊特性没有了解,所以走了很多弯路,不过最后还是弄懂了。爽啊!

脚本贴下,以做备份,当然,起作用的是星号包围的那一段,其他的部分都是废话。

test-firewall.sh:

#!/bin/sh
INITNET="192.168.1.0/24"
IBMIP="192.168.1.2/24"
INITIP="192.168.1.1/24"
UNIVERSE="0.0.0.0/24"
OUTIP="`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"
echo -e "output ip is $OUTIP"
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

/sbin/depmod -a
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_conntrack_irc
/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ip_nat_irc
#echo "load mod ok"

iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
#echo "flush ok"

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

#*********************************************************************************************************************************

iptables -t nat -A PREROUTING -d 192.168.1.1 -p tcp --dport 80 -j DNAT --to-destination  192.168.1.3
iptables -t nat -A PREROUTING -d 192.168.1.1 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth1 -d 192.168.1.3 -p tcp --dport 80 -j ACCEPT
iptables -t nat -A POSTROUTING -d 192.168.1.3 -p tcp --dport 80 -j SNAT --to-source 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.1.3 -p tcp --dport 80 -j ACCEPT

iptables -t nat -A PREROUTING -d 192.168.1.1 -p tcp --sport 80 -j DNAT --to-destination 192.168.1.2
iptables -t nat -A PREROUTING -d 192.168.1.1 -p tcp --sport 80 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth1 -d 192.168.1.2 -p tcp --sport 80 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.1.3 -p tcp --sport 80 -j SNAT --to-source 192.168.1.1
iptables -t nat -A POSTROUTING -s 192.168.1.3 -p tcp --sport 80 -j ACCEPT

#***********************************************************************************************************************************

最后再贴个图,加深理解

 

19 janvier

iptables 入门心得


最近才知道iptables这个东西,顿时被它所吸引。决定研究研究。
一个月前做网关的时候就碰到这个东西,当时不知道它有什么作用,只是从网上抄了个脚本文件,然后稍稍配置了一下,果然建成了网关。
后来又接触到防火墙的时候,才发现原来iptables是一个如此强大的工具,对于想研究网络的我来说,真的是一个不可多得的工具。

简介:iptables是这样的一个工具,对于安装了iptables的机器来说,在接受到包(packet)的时候,发送包的时候,或者转发包的时候,能够根据事先iptables规定好的规则,决定包的去向,或者更改包的信息。这样的一个工具,使得我们能够利用它来建立网关,做代理服务器,做NAT,也能够做防火墙,也能做路由器。由于它的功能是如此的强大,以我现在微薄的知识,我甚至认为,只要跟处理包有关的所有功能,使用iptables,都能够实现。
安装:基于Debian的系统安装iptables非常的简单,我采用的也是最为白痴的方法,就是直接采用命令:
            apt-get install iptables
网络结构:纯粹是兴趣所致,使用家庭网络,总共才3台计算机。一台做服务器,兼作防火墙(虽然这样是极度不推荐的,但是没有办法,小本经营,无力也没有必要做DMZ),另外两台客户机(192.168.1.2/3)。防火墙使用双网卡,eth0接外网(DHCP),eth1接内网(192.168.1.1)。           
使用命令:iptables的使用,网络上有数不清的教程。可以参考。(一直觉得看中文的技术文档没有什么前途,看完后经常是一头雾水,英文的文档翔实而让人容易懂,后来发现原来日文的文档更加的清晰)。iptables的命令行的解析,也有官方的文档可以参考。
这里不做详细的介绍,作为我记忆之用,写出几个实现一些特定功能的命令。
            简单一点说,iptables能够实现的功能是下面几个(目前我网络知识有限,能理解的就只有这几点):
            1.从外网进来的包的控制 (INPUT)
            2.从内网出去的包的控制  (OUTPUT)
            3.对于要求转发的包的控制 (FORWORD)
            4.实现NAT
            5.实现地址重定向
INPUT相关的命令:
内容跟OUTPUT
类似,主要功能是控制防护墙的哪些功能对外开放,就是控制哪些包能够通过防火墙进入机器,判定标准有很多,用的比较多的判定标准是两到三个,一个是ip地址,一个是tcp端口号,一个是包的类型。斯
iptables -A INPUT -p ICMP -j ACCEPT              #允许ICMP包通过防火墙
 ,这里没有指定从哪个NIC进入防火墙,所以对外网来的包和内网来的包都适用。
iptables -A INPUT -p --dport 80 -j ACCEPT     #请求端口号为80的包允许通过,即防火墙提供web服务器功能。
iptables -A INPUT -i eth1 -s 192.168.1.0/24 -j ACCEPT    #对于从eth1进来的源地址在192.168.1.0段的包,允许进入防火墙。
iptables -A INPUT -i eth0 -d 192.168.1.0/24 -j DROP   #对于从外网进来的包,目的地址是内网网段的包,丢弃。这个命令能够保护内网。
iptables -A INPUT -i eth0 -m state --state RELATED,ESTABILISHED -j ACCEPT # 这个命令是根据包的性质来判断接受与否,如果这个包属于已建立的连接,就接收,否则扔掉。

OUOUTTPUT相关的命令:

跟INPUT差不多,主要控制哪些包能够通过防火墙出去。(这里的出去,可能是进入外网(通过eth0),也有可能进入内网(通过eth1),进入和输出是相对于防火墙来说的)
iptables -A OUTPUT -o lo -s 0.0.0.0/24 -d 0.0.0.0/24 -j ACCEPT #这里指定了lo这个特殊的NIC,lo是一个模拟NIC,常用来检测网络软件的安装情况。
iptables -A OUTPUT -o eth1 -s 192.168.1.1/24 -d 192.168.1.0/24 -j ACCEPT #这条命令指定了从eth1输出的源地址是192.168.1.1,目的地址是192.168.1.0段的包允许通过eth1输出

FORWORD相关的命令:
转发相关,防火墙起到代理服务器的作用,是内网通往外网的出口,当内网的机器需要通过防火墙,进入外网的时候,就需要让防火墙来转发。同样,防火墙是外网通往内网的入口,当外网的包想进入内网的时候,需要经过防火墙,让防火墙来转发。
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT #内网通往外网的转发请求都接受
iptables -A FORWARD -i eth0 -o eth0 -m state --state ESTABLISHED -j ACCEPT  # 对于外部进入内部的转发请求,只有已经建立连接的包才能通过,建立连接只有内网通往外网才有可能,所以就是内网往外网的请求的回答才能通过防火墙转发。(实际上本系统中不会出现这种情况,出去的包都进行了nat转换,外网的服务器不可能知道内网的地址,)


NAT相关的命令:
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to (这里是fiareall的外网的地址) #包从防火墙eth0出去的时候进行地址转换,将原ip地址换成外网的地址,然后发送
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to (需要转换为的内网地址) #这个命令将传送目的
地址转化为其他的地址,当内网中安装有服务器的时候,可以使用这个命令将特定端口的(比如80)请求包通过防火墙转发给内网web服务器。
iptables -t nat -A POSTROUTING -o eth0 -j MASQUARDE # 这个命令是用来进行内网到外网的地址转换,跟第一个命令的功能一样。

下面是一个具体的实现防火墙的bash脚本,网络的具体构造忘记了,应该跟我的构造是一样的


#!/bin/sh

#  IPTABLES  FIREWALL  script for the Linux 2.4 kernel.
#  This script is a derivitive of the script presented in
#  the IP Masquerade HOWTO page at:
#  www.tldp.org/HOWTO/IP-Masquerade-HOWTO/stronger-firewall-examples.html
#  It was simplified to coincide with the configuration of
#  the sample system presented in the Guides section of
#  www.aboutdebian.com
#
#  This script is presented as an example for testing ONLY
#  and should not be used on a production firewall server.
#
#    PLEASE SET THE USER VARIABLES
#    IN SECTIONS A AND B OR C

echo -e "\n\nSETTING UP IPTABLES FIREWALL..."


# === SECTION A
# -----------   FOR EVERYONE

# SET THE INTERFACE DESIGNATION AND ADDRESS AND NETWORK ADDRESS
# FOR THE NIC CONNECTED TO YOUR _INTERNAL_ NETWORK
#   The default value below is for "eth0".  This value
#   could also be "eth1" if you have TWO NICs in your system.
#   You can use the ifconfig command to list the interfaces
#   on your system.  The internal interface will likely have
#   have an address that is in one of the private IP address
#   ranges.
#       Note that this is an interface DESIGNATION - not
#       the IP address of the interface.

# Enter the designation for the Internal Interface's
INTIF="eth0"

# Enter the NETWORK address the Internal Interface is on
INTNET="192.168.1.0/24"

# Enter the IP address of the Internal Interface
INTIP="192.168.1.1/24"



# SET THE INTERFACE DESIGNATION FOR YOUR "EXTERNAL" (INTERNET) CONNECTION
#   The default value below is "ppp0" which is appropriate
#   for a MODEM connection.
#   If you have two NICs in your system change this value
#   to "eth0" or "eth1" (whichever is opposite of the value
#   set for INTIF above).  This would be the NIC connected
#   to your cable or DSL modem (WITHOUT a cable/DSL router).
#       Note that this is an interface DESIGNATION - not
#       the IP address of the interface.
#   Enter the external interface's designation for the
#   EXTIF variable:

EXTIF="ppp0"


# ! ! ! ! !  Use ONLY Section B  *OR*  Section C depending on
#  ! ! ! !   the type of Internet connection you have.
# ! ! ! ! !  Uncomment ONLY ONE of the EXTIP statements.


# === SECTION B
# -----------   FOR THOSE WITH STATIC PUBLIC IP ADDRESSES

   # SET YOUR EXTERNAL IP ADDRESS
   #   If you specified a NIC (i.e. "eth0" or "eth1" for
   #   the external interface (EXTIF) variable above,
   #   AND if that external NIC is configured with a
   #   static, public IP address (assigned by your ISP),
   #   UNCOMMENT the following EXTIP line and enter the
   #   IP address for the EXTIP variable:

#EXTIP="your.static.IP.address"



# === SECTION C
# ----------   DIAL-UP MODEM, AND RESIDENTIAL CABLE-MODEM/DSL (Dynamic IP) USERS


# SET YOUR EXTERNAL INTERFACE FOR DYNAMIC IP ADDRESSING
#   If you get your IP address dynamically from SLIP, PPP,
#   BOOTP, or DHCP, UNCOMMENT the command below.
#   (No values have to be entered.)
#         Note that if you are uncommenting these lines then
#         the EXTIP line in Section B must be commented out.

#EXTIP="`/sbin/ifconfig ppp0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"


# --------  No more variable setting beyond this point  --------


echo "Loading required stateful/NAT kernel modules..."

/sbin/depmod -a
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_conntrack_irc
/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ip_nat_irc

echo "    Enabling IP forwarding..."
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

echo "    External interface: $EXTIF"
echo "       External interface IP address is: $EXTIP"
echo "    Loading firewall server rules..."

UNIVERSE="0.0.0.0/0"

# Clear any existing rules and setting default policy to DROP
iptables -P INPUT DROP
iptables -F INPUT
iptables -P OUTPUT DROP
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F -t nat

# Flush the user chain.. if it exists
if [ "`iptables -L | grep drop-and-log-it`" ]; then
   iptables -F drop-and-log-it
fi

# Delete all User-specified chains
iptables -X

# Reset all IPTABLES counters
iptables -Z

# Creating a DROP chain
iptables -N drop-and-log-it
iptables -A drop-and-log-it -j LOG --log-level info
iptables -A drop-and-log-it -j REJECT

echo -e "     - Loading INPUT rulesets"

#######################################################################
# INPUT: Incoming traffic from various interfaces.  All rulesets are
#        already flushed and set to a default policy of DROP.
#

# loopback interfaces are valid.
iptables -A INPUT -i lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT

# local interface, local machines, going anywhere is valid
iptables -A INPUT -i $INTIF -s $INTNET -d $UNIVERSE -j ACCEPT

# remote interface, claiming to be local machines, IP spoofing, get lost
iptables -A INPUT -i $EXTIF -s $INTNET -d $UNIVERSE -j drop-and-log-it

# remote interface, any source, going to permanent PPP address is valid
iptables -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -j ACCEPT

# Allow any related traffic coming back to the MASQ server in
iptables -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT


#  OPTIONAL:  Uncomment the following two commands if plan on running
#             an Apache Web site on the firewall server itself
#
#echo -e "      - Allowing EXTERNAL access to the WWW server"
#iptables -A INPUT -i $EXTIF -m state --state NEW,ESTABLISHED,RELATED -p tcp -s $UNIVERSE -d $EXTIP --dport 80 -j ACCEPT


# Catch all rule, all other incoming is denied and logged.
iptables -A INPUT -s $UNIVERSE -d $UNIVERSE -j drop-and-log-it


echo -e "     - Loading OUTPUT rulesets"

#######################################################################
# OUTPUT: Outgoing traffic from various interfaces.  All rulesets are
#         already flushed and set to a default policy of DROP.
#

# loopback interface is valid.
iptables -A OUTPUT -o lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT

# local interfaces, any source going to local net is valid
iptables -A OUTPUT -o $INTIF -s $EXTIP -d $INTNET -j ACCEPT

# local interface, any source going to local net is valid
iptables -A OUTPUT -o $INTIF -s $INTIP -d $INTNET -j ACCEPT

# outgoing to local net on remote interface, stuffed routing, deny
iptables -A OUTPUT -o $EXTIF -s $UNIVERSE -d $INTNET -j drop-and-log-it

# anything else outgoing on remote interface is valid
iptables -A OUTPUT -o $EXTIF -s $EXTIP -d $UNIVERSE -j ACCEPT

# Catch all rule, all other outgoing is denied and logged.
iptables -A OUTPUT -s $UNIVERSE -d $UNIVERSE -j drop-and-log-it


echo -e "     - Loading FORWARD rulesets"

#######################################################################
# FORWARD: Enable Forwarding and thus IPMASQ
#          Allow all connections OUT and only existing/related IN

iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

# Catch all rule, all other forwarding is denied and logged.
iptables -A FORWARD -j drop-and-log-it

# Enable SNAT (MASQUERADE) functionality on $EXTIF
iptables -t nat -A POSTROUTING -o $EXTIF -j SNAT --to $EXTIP

echo -e "    Firewall server rule loading complete\n\n"



1 novembre

今天研究了发动机

发动机带给这个世界的力量是在是如此的巨大,以至于当我发现原来发动机的基本原理是如此的简单的时候,我不愿意相信。我宁愿相信这个奇妙的机器的原理有着如爱因斯坦相对论一般的难度,世界上只有几个牛人才能够窥其全貌。但是事实上,发动机的基本构造是如此的简单而明确,设计者的原始想法是如此得单纯和容易理解。虽然这样,但是却如此强烈的风驰电掣般的改变了一百多年前的整个世界,以强硬的姿态为这个星球装上了神奇的轮子。
至此以来的一百多年,发动机的发展日新月异,新技术,新发明层出不穷,但是这个四冲程原理还是隐藏在各种新技术的背后,发挥着决定性的作用。尽管它看起来很简单。
于是我想,想要改变世界,并不一定需要多么复杂的的理论,有时候一个简单而实用的想法已经足够了。
四冲程原理就是一个简单而绝妙地将能源装化为机械能的手段。能够做到关键的这一步,其他的次要方面都能够在它的基础上建立起来了。
迄今为止,其他种类的发动机虽然也有应用,但是起到决定性影响的还是这个几百年前的古老而简单的想法。
所以一番重要的是想法,想法的实现那才需要用到技术。
所以做个有技术的人重要,做个有想法的技术人员更加的实用。
17 août

在Linux下配置TCP/IP(zz)

关键文件和脚本

网络接口初始化的实际过程(有时也称做“启动接口”)是由一组配置文件和脚本控制的,这些文件和脚本大多数在/etc 目录下。这些配置文件告诉 Linux 它的 IP 地址、主机名和域名;脚本则负责网络接口的初始化。
遗憾的是,不同分发版(distribution)中文件位置和命名约定至今还没有统一的标准。为给本文提供具体的示例,将基于广泛使用的 Red Hat 7.0 包做出描述。请记住,若您的分发版不是使用 Red Hat 或不是基于 Red Hat 约定(如 Mandrake 分发版),在此所引用的一些文件会位于别的目录中或有其它的名称。然而,网络效果和实际效果是一样的 ― 将存储在一系列配置文件中的网络信息传递给脚本,然后用脚本初始化接口和网络路由。
涉及初始化和配置网络接口的关键文件有:
/etc/hosts (将主机名映射到 IP 地址)
/etc/networks (将域名映射到网络地址)
/etc/sysconfig/network (打开或关闭联网,设置主机名和网关)
/etc/resolv.conf (设置名称服务器或 DNS 服务器的 IP 地址)
/etc/rc.d/rc3.d/S10network (在引导时激活已配置的以太网接口,由运行级别目录 /etc/rc.d/rcN.d/ 中的符号链接调用)
/etc/sysconfig/network-scripts 中一些文件的集合。这些文件包括用于网络连接的主要配置,以及提供接口状态和控制功能的符号链接。

/etc/hosts

/etc/hosts 是将 IP 地址和主机名联系起来的简单文本文件。 TCP/IP 网络中的每台计算机都必须有唯一的 IP 地址。hosts 文件只允许用户将主机名与 IP 地址联系起来,以便当访问计算机时使用该名称,而不用输入一长串数字。/etc/hosts 中的每一项都依次包含一个 IP 地址、空白和主机名和/或别名。井号(#)表示注释开始。例如:
# /etc/hosts
# last updated 12/3/2000

127.0.0.1 loopback localhost # loopback (lo0) name/address

192.168.1.5 janus.syroidmanor.com janus
192.168.1.6 thumper.syroidmanor.com thumper
192.168.1.7 donovan.syroidmanor.com donovan
192.168.1.8 raidserver

192.168.1.20 phoenix.syroidmanor.com phoenix
192.168.1.15 hydras.syroidmanor.com hydras
在上面显示的 Hosts 文件中,IP 地址 192.168.1.5 映射到主机 janus.syroidmanor.com ,并且分配给它一个备用主机名(或别名)janus。尽管 DNS 已经取代了这个主机文件,但出于以下原因仍然使用它:
大多数系统都有一个包含本地网络上的关键主机的名称和地址信息的小主机表。当 DNS 未运行时,例如,在最初系统启动期间,则使用该表。即便本地 DNS 服务器正在运行,在每个系统上也应该有一个小 hosts 文件,该文件包含一个主机本身项、一个 localhost 项以及局域网上任何主要的网关和服务器项。
未连接到因特网或其他网络的小网络不需要 DNS 服务。然而,这些网络上的主机也需要知道如何定位同一网络上的其它主机。

/etc/networks

就如主机有名称和地址一样,为方便起见,也可以为网络和子网命名。 /etc/networks 文件在布局上与 /etc/hosts 很相似,只不过名称和地址互换了一下。
# /etc/networks for syroidmanor.com

localnet 127.0.0.0 #loopback
syroid-C1 192.168.1 #development, class C
syroid-C2 192.168.2 #support, class C
在上面的示例中,可将网络名称 syroid-C1 用于脚本或任何命令行实用程序中来引用 192.168.1 这个 C 类网。

/etc/sysconfig/network

将 /etc/sysconfig/network(注意与 /etc/networks 文件不同,这个 network 是单数而不是复数)用于指定所期望的网络配置信息;在引导时,有几个脚本要使用它。该文件可以包含下列所示的一个或多个关键字/值对:
NETWORKING=YES|NO -- YES 表示需要配置网络;NO 表示不需要配置网络。
HOSTNAME=hostname ― 主机的全限定域名;为与较老的程序兼容,这应该与在 /etc/hosts 中的主机项相匹配。
GATEWAY=gw-ip ― 网络网关的 IP 地址。
GATEWAYDEV=gw-dev ― 网关设备的名称(例如 eth0)。
NISDOMAIN=dom-name ― 表示 NIS 域,如果有的话。
下面是 /etc/sysconfig/network 最小配置的示例:
NETWORKING=yes
HOSTNAME=phoenix.syroidmanor.com
GATEWAY=192.168.1.1

/etc/resolv.conf 和 /etc/rc.d/rc3.d/S10network

/etc/resolv.conf 是网络用来确定主机解析的关键文件之一。在此可以标识最多三个名称服务器;如果列在第一位的服务器未对查询做出响应,则后面两个起到备用的作用。 domain 项定义缺省域名。解析器(顺便提一下,该解析器不是一个单独的进程,而是由网络进程调用的例程库)将这里所列出的域名附加在任何不包含句点的主机查询上。
# /etc/resolv.conf
# domain name resolver config file
domain syroidmanor.com

nameserver 192.168.1.7
nameserver 192.168.1.10
nameserver 165.142.268.19
在上面所显示的示例中,如果提交给解析器的查询是想要查询找主机 phoenix(注意,没有点),则将该域附加到这个请求之后,这会将该查询扩展为 phoenix.syroidmanor.com。若需要了解更多详细信息和可以使用的选项,请输入 man resolv.conf 。
/etc/rc.d/rc3.d/S10network 是指向 /etc/rc.d/init.d/network 脚本的符号链接。当系统达到运行级别 3 时,它负责初始化所有已配置的网络接口。在这里我们不想花时间来详细讨论该文件后面的逻辑,因为该文件主要是调用本节中所提到的其它脚本和程序。但是,如果您对 S10network 中初始化各种网络组件和服务的顺序感兴趣的话,则可以使用 less /etc/rc.d/rc3.d/S10network 命令来仔细研读它。

/etc/sysconfig/network-scripts/

最后,通常可在 /etc/sysconfig/network-scripts/ 目录中查找到下列文件:
/etc/sysconfig/network-scripts/ifup
/etc/sysconfig/network-scripts/ifdown
/etc/sysconfig/network-scripts/network-functions
/etc/sysconfig/network-scripts/ifcfg-interface-name
/etc/sysconfig/network-scripts/ifcfg-interface-name:clone-name
/etc/sysconfig/network-scripts/chat-interface-name
/etc/sysconfig/network-scripts/dip-interface-name
/etc/sysconfig/network-scripts/ifup-post

……/network-scripts/,第一部分
/etc/sysconfig/network-scripts 中的 ifup 和 ifdown 项实际是分别指向 /sbin/ifup 和 /sbin/ifdown 的符号链接。这两个脚本是在该目录下唯一应该直接调用的脚本,并且它们按需要调用所有其它脚本。
ifup 和 ifdown 通常只带一个参数:设备名(例如 eth0)。系统在引导过程期间用参数“boot”调用它们,以便于不激活没有被配置成在系统启动时初始化的设备(请参阅下面关于 interface-name 描述中的 ONBOOT=no)。
network-function 不是公共文件。它包含这个目录中的几个脚本所需的函数。具体地说,它包含了用于处理替代接口配置的大多数代码。

……/network-scripts/,第二部分

配置文件 ifcfg-interface-name 和 ifcfg-interface-name:clone-name 包含了初始化接口所需的大部分详细信息。第一个文件定义接口,而第二个文件仅包含与“别名”(或替代)接口相关的部分定义。例如,网络地址或许不同,但其它可能会一样。
在 ifcfg 文件中定义的各项目取决于接口类型;下列值很常见:

DEVICE=name ,其中 name 是物理设备名
IPADDR=addr ,其中 addr 是 IP 地址
NETMASK=mask ,其中 mask 是网络掩码值
NETWORK=addr ,其中 addr 是网络地址
BROADCAST=addr ,其中 addr 是广播地址
GATEWAY=addr ,其中 addr 是网关地址
ONBOOT=answer ,其中 answer 是“yes”(引导时激活设备)或“no”
USERCTL=answer ,其中 answer 是“yes”(非 root 用户可以控制该设备)或“no”
BOOTPROTO=proto ,其中 proto 取下列值之一:“none”(引导时不使用协议)“bootp”(使用 BOOTP 协议)或“dhcp”(使用 DHCP 协议)

此外,下列值对所有的 SLIP(串行线 IP)文件是公共的:

PERSIST=answer ,其中 answer 是“yes”(即使调制解调器已经挂断连接,也保持设备处于激活状态)或“no”(不保持激活状态)
MODEMPORT=port ,其中 port 是调制解调器端口的设备名(例如,/dev/modem)
LINESPEED=baud ,其中 baud 是调制解调器的线路速度
DEFABORT=answer ,其中 answer 是“yes”(当创建/编辑该接口的脚本时,插入缺省的异常终止字符串)或“no”(不插入缺省的异常终止字符串)


……/network-scripts/,第三部分

chat-interface-name 文件是用于 SLIP 连接的交谈脚本(chat script)。它的功能是启动 SLIP 连接。对于 SLIP 设备,DIP 脚本是根据这个交谈脚本编写的。
chat-interface-name 是只写脚本,它由程序 netcfg 根据交谈脚本创建的。不要修改该文件。
当初始化任何网络设备(除了 SLIP 设备)时,调用 /etc/sysconfig/network-scripts/ifup-post。它调用 /etc/sysconfig/network-scripts/ifup-routes 以启动依赖于该设备的静态路由,它还启动为该设备配置的任何别名,并且,如果还没有设置主机名,则设置主机名 ― 这样找到与该设备 IP 地址匹配的主机名。最后,ifup-post 给请求通知网络事件的任何程序发送信号(SIGIO)。

配置网络接口和路由

ifconfig 程序
ifconfig 命令设置、检查或监控网络接口的配置值。它还可以用于设置接口的“状态”― 即“up”(启动)或“down”(关闭)。一个对 ifconfig 简单的调用是:
ifconfig interface-name ip-address up|down
这会激活指定的接口并将所提供的 IP 地址分配给它。
ifconfig 有许多个可用的选项(metric、mtu 以及 pointtopoint 等等;有关详细信息,请参阅帮助页)用于显式地设置唯一的接口参数,但一般来说,提供接口名称(例如, eth0)、IP 地址和网络掩码就足够了。例如:
ifconfig eth0 192.168.1.5 netmask 255.255.255.0 up
分配给接口 eth0 的 IP 为 192.168.1.5,网络掩码为 255.255.255.0 并“启动该接口”或将其初始化。类似的,若将接口“关闭”,则输入 ifconfig eth0 down ;不需要指定 IP 和网络掩码。

使用 ifconfig 检查接口

运行不带参数的 ifconfig 会使该程序显示所有网络接口的状态。若要检查特定接口的状态,则在 ifconfig 后附加这个接口的名称。例如:
[tom@phoenix tom]$ /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:10:5A:00:87:22
inet addr:192.168.1.20 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:9625272 errors:0 dropped:0 overruns:0 frame:0
TX packets:6997276 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:19 Base address:0xc800
以上输出显示 MAC 地址(Hwaddr)、所分配的 IP 地址(inet addr)、广播地址(Bcast)和网络掩码(Mask)。另外可以看出该接口处于 UP 状态,其 MTU 为 1500 并且 Metric 为 1。接下来的两行给出有关接收到(RX)和已发送的(TX)信息包数,以及错误、丢弃和溢出信息包数的统计。最后两行显示冲突信息包的数目、发送队列大小(txqueuelen)和 IRQ 以及这块卡的基址。

配置路由

让我们通过查看尚未配置网关的网络接口来看一下如何配置路由。正如您所见,使用不带参数的 route 命令将显示内核路由表。
[root@phoenix tom]# /sbin/route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
127.0.0.0 127.0.0.1 255.0.0.0 U 0 0 0 lo
192.168.1.0 192.168.1.5 255.255.255.0 U 0 0 0 eth0

第一项是到 localhost 的回送路由,它是在配置 lo 时自动创建的。第二项是通过接口 eth0 到网络 192.168.1.0 的路由。地址 192.168.1.5 不是远程网关地址。它是分配给 phoenix eth0 的地址。
注意每项的标志。它们都设置了 U(启动)标志,这表示准备使用它们,但它们都未设置 G(网关)标志。不设置 G 标志是因为这两个路由都是通过本地接口,而不是通过外部网关的直接路由。
上述示例仅包含一个网络路由 192.168.1.0。因而 phoenix 仅可以与位于 192.168.1.0 网络中的主机进行通信。

添加静态路由

最小的路由表仅允许在同一网络中的主机互相通信。要与远程主机通信,必须将通过外部网关的路由添加到路由表中。达到该目的的一种方法是通过使用 /sbin/route 命令。拿上页中的例子来说,我们现在就将路由 192.168.1.1 添加到网络配置中。
[root@phoenix tom]# /sbin/route add default 192.168.1.1 1
在上面这个示例中,route 命令后的第一个参数是关键字 add 。在 route 命令上的第一个关键字要么是 add 要么是 del (删除路由)。下一个值是目的地地址,它是通过该路由到达的地址。如果关键字 default 用于目的地地址,则创建缺省路由。只要没有到目的地的特定路由时,就使用缺省路由;通常,这就是您在路由表中唯一需要的项。如果网络中只有一个网关,则使用缺省路由引导所有要到远程网络的数据流量通过那个网关。
这个命令行的下一个参数是网关地址。该地址必须是直接连接本机所在网络的网关地址。在到远程目的地的网络路径中,TCP/IP 路由要指定下一跳(next-hop)。这个下一中继必须是本机可直接访问的;因而,它必须是在直接连接在本机所在的网络中。
注:因为大多数的路由都是在系统启动过程早期时添加的,所以建议用数字的 IP 地址替代主机名。这样做就可以确保路由配置不依赖于名称服务器的状态。而且要确保总是使用完整的数字地址(共 4 个字节);如果不用完整的 IP 地址,则路由只能猜想部分 IP 地址,这样可能会导致不正确的配置。
route 命令中,最后一个参数是数字 1,称之为路由度量(routing metric)。当删除路由时是不需要此 metric 参数的,但是在添加路由时许多系统都需要它。尽管需要度量,route 仅使用它来确定路由是通过直接连接的接口还是通过外部的网关。如果 metric 是 0,建立的这条路由是通过本机接口且不设置 G 标志;如果 metric 值比 0 大,则建立的这条路由带 G 标志且网关地址被认为是外部的。静态路由不使用其它 metric 值。需要真正用到多个 metric 值的是动态路由。
要显示新的路由表,输入 /sbin/route 或使用 netstat -rn 命令(我们将再下一节讨论该命令):
[root@phoenix tom]# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
最后做一个测试来证明一切都如同我们讲到的那样运行,ping 另一个网络上的主机;应该可以接收到响应。如果没有接收到响应,则重新检查您的配置。
要熟悉 route 其它的选项和参数,请输入 man route 。

netstat 程序

如果管理任意规模的 TCP/IP 网络,则 netstat 程序是一个相当有价值的工具。它可以显示内核路由表,活动网络连接的状态和每个已安装网络接口的一些有用的统计信息。
象大多数 Linux 管理命令行程序一样,netstat 可以通过其后面的附加选项或标志来选择所显示信息的细节数量和/或信息的范围。一些常用选项有:
-a ― 显示所有连接的信息,包括那些正在侦听的
-i ― 显示所有已配置网络设备的统计信息
-c ― 持续更新网络状态(每秒一次)直至被人为中止(^C)
-r ― 显示内核路由表
-n ― 以数字(原始)格式而不是已解析的名称显示远程和本地地址
-t ― 仅显示 TCP 套接字信息(不包括任何 UCP 套接字信息)
-v ― 显示 netstat 的版本信息
输入 man netstat 可获得所有可用标志的完整列表和详细说明每个标志的用途。请注意还可以组合这些标志,所以输入 netstat -rn 将以原始的 IP 地址格式显示关于本地和远程主机(n)的系统路由表(r)。

显示活动的网络连接

netstat 支持一组显示活动或非活动的套接字的选项:-t、-u、-w 和 -x 分别显示活动的 TCP、UDP、RAW 或 UNIX 套接字连接。如果加上 -a 标志,还会显示等待连接的(换句话说,就是侦听)套接字。这将为您显示现在正在系统上运行的所有服务器。
例如:在主机 phoenix 上输入 netstat -ta 会显示下列内容:
[tom@phoenix tom]$ netstat -ta
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 40 phoenix.syroidmanor:ssh 192.168.1.5:1132 ESTABLISHED
tcp 0 0 *:ssh *:* LISTEN
tcp 0 0 phoenix.syroidmano:1028 hydras.syro:netbios-ssn ESTABLISHED
tcp 0 0 phoenix.syroidmano:1027 raidserver:netbios-ssn ESTABLISHED
tcp 0 0 *:printer *:* LISTEN
tcp 0 0 *:auth *:* LISTEN
tcp 0 0 *:1024 *:* LISTEN
tcp 0 0 *:sunrpc *:* LISTEN
上述输出显示大多数的服务器仅仅在等待到来的连接(LISTEN)。但是,第一行显示主机 phoenix 和 IP 地址为 192.168.1.5 之间的连接;第三和第四行显示两个 netbios 连接(Samba SMB 共享)。

用 netstat 查看路由表

当使用 -r 标志时,netstat 显示内核中的路由表,这类似于输入 /sbin/route :
[tom@phoenix tom]$ netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0

-n 选项强制 netstat 以点分四组 IP 数字的形式,而不是主机和网络名称的形式输出地址。当您不想通过网络(例如,用 DNS 或 NIS 服务器)进行地址查询时,这个选项特别有用。
第二列显示路由项中所指向的网关。如果没有使用网关,就会显示星号。第三列是路由的网络掩码。内核在将信息包的 IP 地址与路由的目的地 IP 地址进行比较之前,将 Genmask 值与信息包的 IP 地址逐位进行“与”操作,从而使路由“通用化”。
第四列显示路由的标志:U 表示处于活动状态,H 表示主机,G 表示网关,D 表示动态路由,而 M 表示已经修改过。

[tom@phoenix tom]$ netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
接下来的三列显示 MSS、Window 和 irtt,它们将被应用于通过该路由建立的 TCP 连接。MSS(Maximum Segment Size)表示“最大分段尺寸”,也是内核所构建以通过该路由发送的数据报的最大尺寸。Window 表示系统一次从远程主机接收突发的最大量数据。
首字母缩写词 irtt 代表“初始往返时间(initial round trip tim)”。TCP 协议确保主机间可靠地发送数据,如果数据已经丢失,则重新发送。TCP 协议一直对发送给远程端点的数据报和接收到的确认所花费的时间进行记数,以便知道假定要重发数据报前需要等待的时间;这个过程称为往返时间。TCP 协议将使用第一次建立连接时所用时间作为初始往返时间的值。对于大多数类型的网络,用缺省值就够了,但对某些速度较慢的网络(特别是某些业余的分组无线网络),这个时间太短了,会造成不必要的重发。可以使用 route 命令设置 irtt 值。在上面这个路由表中,这些字段均为零值,这表明正在使用缺省值。
最后,最后这个字段表示的是所显示的路由使用的网络接口。

用 netstat 显示一些网络接口使用的统计信息

用 -i 选项调用 netstat 可以显示所有已配置接口的一些有用的统计信息 ― 这是一个用于排除网络故障的非常有用的工具。有了该命令,很容易检查连接的状态以及连接是否“正常”。
[tom@phoenix tom]$ netstat -i
Kernel Interface table
eth0 Link encap:Ethernet HWaddr 00:10:5A:00:87:22
inet addr:192.168.1.20 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:10554374 errors:0 dropped:0 overruns:0 frame:0
TX packets:8528339 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:19 Base address:0xc800

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:3924 Metric:1
RX packets:5612 errors:0 dropped:0 overruns:0 frame:0
TX packets:5612 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0

RX packets 和 TX packets 行分别显示了已经接收到的信息包或已经发送了的信息包数目以及出错的信息包、丢失的信息包以及溢出的 RX/TX 统计信息。最常见的接口错误都是源于不正确的配置,所以,如果遇到了某些困难,最好再三检查所有的设置来进行诊断。
假使接口已经启动,则应该没有信息包排队等候发送(txqueuelen)― 如果有,则可能是由于网络电缆或网卡有问题。首先换一根备用电缆,然后重新检查连接。RX/TX 错误应该近乎为零。如果 TX 错误过多,则表示网络已经饱和或物理连接有问题;如果 RX 错误过多,则表示网络已经饱和、物理连接有问题或主机过载。如果遇到过高的冲突率(冲突率是输出信息包(output packet)的百分比,而不是从发送/接收信息包的总数中计算得出),它可能也表示网络已经饱和;通过从同一子网上的另一台主机执行 netstat -i 命令并比较结果来证实这一点。
要解决网络中错误,一定要仔细地以及系统地分析接口的所有方面(硬件和软件),这是必要的。不要匆忙行事,……啊……我们提到了总是要先检查网络电缆。在这一点,相信我。