Linux 網路管理

author:Yung-Yu Chen (yungyuc) http://blog.seety.org/everydaywork/ <yyc@seety.org>
copyright:© 2006, all rights reserved

目錄

1   區域網路

本章將討論 Linux (特別是 Debian) 的網路管理能力。

現在我們所使用的區域網路 (Local Area Network, LAN) 技術多半是乙太網路 (Ethernet),這是一個年輕的網路技術,不過非常方便好用,以致於今天絕大部分的地方都使用這種技術;我們在 PC 上大多也只會接觸到這種區域網路技術。

在網際網路時代,其實所有的網路服務幾乎都已經網際網路化了,區域網路技術只是作為網際網路底層的載體。本節所指涉的「區域網路」,也應該要理解成「區域性的網際網路」才對。

本章討論的重點在於說明如何進行與系統的網際網路相關的組態及管理,以及一些與系統及網路管理相關的服務設定。至於乙太網路硬體的設定與驅動,應該是與編譯核心與操作核心模組相關的問題。

2   基本網路設定

關於網際網路的 IP 相關設定,我們在安裝基本系統的時候已經作過了基本的介紹;知道重點在於 /etc/network/interfaces 這個設定檔。當我們在 interfaces 檔裡變更了設定之後,不要忘記重新啟動網路介面 (假設是 eth0):

$ ifdown eth0
$ ifup eth0

請注意,如果你是使用 ssh 連線到遠端主機進行管理的話,當你把上述的第一個指令執行完畢後,可能沒有機會執行第二次來啟動網路。因此,在這種情況下,請把以上的兩個指令下在一行裡面:

$ ifdown eth0; ifup eth0

其實這還是有點危險;如果你的組態檔沒有寫好,那麼 eth0 沒有辦法再啟動。 如果要對區域網路介面進行調整,我建議還是在主機前面進行為宜。

除了設定 IP 的 interfaces 檔之外,當然還有許多與網路組態相關的設定檔,本節將介紹其中重要的幾個。

2.1   hosts

/etc/hosts 這個檔案的作用是提供名稱解析 (name resolution)。當我們安裝好 Debian 系統時,這個檔案一定會有以下的內容:

127.0.0.1       localhost.localdomain localhost

# The following lines are desirable for IPv6 capable hosts
# (added automatically by netbase upgrade)

::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

這些內容只設定了對本機的名稱解析;第 1 行是針對 IPv4 的設定,而第 6 到 11 行則是給 IPv6 看的設定。

何謂名稱解析?簡單來說,在網際網路上的名稱解析,就是將網域名稱與 IP 位址進行對應;這個對應工作是由作業系統的網際網路層程式自動進行的,廣義來講屬於 IP 網路規格的一部分。照以上 hosts 檔的內容來看, 127.0.0.1 會對應到 localhost.localdomainlocalhost 這兩個名稱;反之 localhost.localdomainlocalhost 這兩個名稱則會反向對應到 127.0.0.1 這個 IP 位址。

我們可以用 ping 這個程式測試一下效果:

$ ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms

但如果我們 ping notlocalhost,則會找不到這台主機。

我們可以在 hosts 檔裡面加上自訂的 IP 與名稱對應,一般我們用不到 IPv6,所以照 IPv4 的格式 (如第 1 行) 撰寫即可。

2.2   hosts.allow/hosts.deny

這一組檔案可以控制服務程式的連線,主要用於 inetd 超級伺服器裡的服務;不過,事實上它們是 TCP wrapper (tcpd) 這套工具的設定檔,只要是支援 TCP wrapper 的網路程式,就可以在這組檔案裡作控管。

3   inetd 超級伺服器

inetd 是一種執行網際網路 (IP) 程式的架構,許多如 remote shell (rsh, rlogin) 和傳統的網路程式 (fingerd, echo) 等,也都是透過 inetd 來執行的。

inetd 的設定檔位置在 /etc/inetd.conf``[#]_\ ;裡面是一行一行的設定,而 ``# 符號代表註解。inetd.conf 裡的設定格式是:

[1]RedHat 和 Fedora Core 已經沒有這個組態檔了。因為 RedHat/FC 把 inetd 換成 xinetd,所以原本的 inetd.conf 組態檔變成了一個目錄:``/etc/xinetd``。有 RedHat/FC 經驗的使用者或許會有點不習慣。
<服務名稱> <socket 型態> <協定> <旗標> <使用者> <伺服程式路徑> <引數>

我們一個個地來解釋設定行的各個元素:

在 Debian 裡有一支叫作 update-inetd 的工具程式,可以用來管理 inetd.conf;詳細的使用方式請見 update-inetd(8)

4   基本工具的使用

在這一節裡,我們要對一些基本的網路工具進行討論;這些工具可以幫助你了解你的網路。

4.1   ping

ping 程式會送出 ICMP 封包,對遠端主機進行檢測:

$ ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.1 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.1 ms

--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.1/0.1/0.2 ms

ping 後接主機名稱即可。它和 Windows 上的 ping 不同,如果不按下 Ctrl+C,會一直不斷地 ping 下去;Windows 的 ping 如果不加參數,則只會傳四個 ICMP 封包。

我們常常用 ping 來檢查網路通是不通;假設我們所處的子網路預設閘道器是 192.168.10.254:

$ ping 192.168.10.254
PING 192.168.10.254 (192.168.10.254): 56 data bytes

--- 192.168.10.254 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss

如果像上面一樣過了一會兒都沒有回應,就表示本機到閘道器不通了;通常我們會選閘道器當作測試目標,因為它應該要是最穩定的機器。得到了這樣子失敗的測試結果,我們就知道網路一定是哪裡出了問題,需要進一步的檢測。

4.2   traceroute

traceroute 這個工具預設不見得會安裝,因為不是像 ping 那麼常用;它可以送出 ICMP 封包,檢查本機到遠端間的網路狀況。你可以像這樣進行測試:

$ traceroute www.yahoo.com

4.3   arp

arp 工具的用途是維護系統內的 ARP 快取;可以找出本機有直接區域網路連線的 MAC address 與 IP 對應,如:

$ arp
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.23.1             ether   00:09:12:4C:DE:82   C                     eth0
192.168.23.23            ether   00:00:E2:32:A0:B7   C                     eth0
192.168.23.254           ether   00:00:E2:76:C1:DD   C                     eth0

我們可以由此查出某一 IP 的實體網路卡號。不過要注意,這是提供{bf區域網路}使用的工具,你不可能查得到 www.microsoft.com 的網路卡號。

4.4   netstat

netstat 是一個用來顯示目前系統的網路連線狀況、routing table 等以及其它許多資訊的工具。以一般使用者的身份執行:

$ netstat

就會看到它列出系統上的 TCP 及 Unix socket 連線狀況。如果加上 -n 參數的話,netstat 就不會嘗試作連線主機的名稱反解,可以加快列表的速度。

超級使用者可以用 -p 參數呼叫 netstat 來得知本機通訊埠是由哪個程式使用的。關於 netstat 的詳細用法,請參閱 netstat(8)

4.5   nmap

nmap 這個工具可以對網路上的任何主機進行掃瞄。一般來說,我們會用它來掃瞄自己的主機,查看通訊埠是否正確開啟,或是有沒有不正常的通訊埠被開啟。

對非由自己管轄的主機用 nmap 或其它類似的工具進行掃瞄,通常會被認定為具有攻擊性的行為;如果沒有正當的理由,請儘量避免這樣作。

nmap 需要另外用 apt 安裝:

$ apt-get install nmap

最簡單的用法就是:

$ nmap localhost

Starting nmap 3.81 ( http://www.insecure.org/nmap/ ) at 2005-06-22 16:33 CST
Interesting ports on localhost (127.0.0.1):
(The 1652 ports scanned but not shown below are in state: closed)
PORT    STATE SERVICE
21/tcp  open  ftp
22/tcp  open  ssh
25/tcp  open  smtp
80/tcp  open  http
111/tcp open  rpcbind
139/tcp open  netbios-ssn
445/tcp open  microsoft-ds
515/tcp open  printer
631/tcp open  ipp
752/tcp open  qrh
902/tcp open  iss-realsecure-sensor

可以看到本機上開啟的常用埠。

預設 nmap 只會掃瞄它預先定義好的一組常用通訊埠;如果我們想讓它掃瞄一段範圍的通訊埠,可以用:

$ nmap localhost -p 0-100

Starting nmap 3.81 ( http://www.insecure.org/nmap/ ) at 2005-06-22 16:36 CST
Interesting ports on localhost (127.0.0.1):
(The 97 ports scanned but not shown below are in state: closed)
PORT   STATE SERVICE
21/tcp open  ftp
22/tcp open  ssh
25/tcp open  smtp
80/tcp open  http

Nmap finished: 1 IP address (1 host up) scanned in 0.170 seconds

nmap 預設只用 TCP connect() 模式進行掃瞄,如果我們希望讓它掃瞄 UDP 埠的話,要加上 -sU,不過只有超級使用者可以這樣作:

$ sudo nmap localhost -sU -p 0-100

Starting nmap 3.81 ( http://www.insecure.org/nmap/ ) at 2005-06-22 16:38 CST
All 101 scanned ports on localhost (127.0.0.1) are: closed

Nmap finished: 1 IP address (1 host up) scanned in 0.279 seconds

此時在本機上的第 0 到第 100 號通訊埠上,沒有 UDP 程式。

nmap 還有許多參數可以調整,是一個非常強大的掃瞄工具。詳見 nmap(1),另外單獨下 nmap 指令不接參數,也會印出一段常用參數的使用說明。

4.6   測試技巧:以 telnet 直接連線

telnet 是一種通訊協定,它主要的用途是進行遠端登入。不過,我們之前在談遠端登入的時候,討論的是 ssh,而不是這個 telnet,為什麼呢?最早期在遠距離的 Un*x 主機之間都是用 telnet 進行遠端登入的,不過,telnet 這種通訊協定是使用未加密過的明碼進行資料傳輸,所以在網路網路兩點間的任何人都可以對連線資料進行竊聽。這造成了很大的安全性問題;尤其是系統管理員的帳號和密碼,等於是不設防地在網路上公開。

因為 telnet 的不安全,慢慢地大家就不用它來作遠端登入,而改用 ssh;Debian 預設也不會開啟 telnet。

不過,telnet 還是有它的用處。許多的網路通訊協定 (主要是 TCP) 可以直接用 telnet 進行連接,譬如我們連到本端的 SMTP 伺服器:

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 my.host.name ESMTP Postfix (Debian/GNU)
ehlo my
250-my.host.name
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250 8BITMIME
^]
telnet> quit
Connection closed.

telnet 後接欲連接的主機名稱,如果不想用預設的 telnet 通訊埠 23,則可以再接想連接的埠號,這裡是 25,也就是標準的 SMTP 通訊埠。我們可以用 telnet 來直接與伺服程式連線,傳送資料並檢視回饋的訊息。

當我們在對伺服程式進行設定或除錯的時候,可以試著使用這個技巧;詳細的使用方法則視伺服程式不同而定。

5   組態 NAT

NAT 意指網路位址轉譯 (Network Address Translation),是一種將 IP/通訊埠進行對應的技術。Linux 下的 NAT 常應用在簡易防火牆、多電腦共用 IP 或提供內部網路對外連線的單一接口;但無論是何種應用,都只是把來自於 NAT 內的連線轉由 NAT 主機發出。

在 Linux 下要啟動 NAT,先決條件是核心有編入相關的模組;如果我們使用的是 Debian 預編好的 kernel-image,那就沒有問題。在確定了核心的支援以後,你還要開啟 IPv4 forwarding 的功能。我們先檢視一下目前的設定:

$ cat /proc/sys/net/ipv4/ip_forward
0

這樣的結果表示 IPv4 forwarding 是關掉的footnote{/proc 是一個虛擬的檔案系統,用來表示目前系統裡的行程資訊;你可以在 proc(5) 裡找到詳細的說明。};我們來把它打開:

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

你可以再 cat 一下來確定。

然後,我們必須安裝 iptables 這個套件:

$ apt-get install iptables

iptables 是對 Linux 2.4 以上核心的封包過濾與 NAT 功能所提供的設定程式,地位有點像 modutils

安裝完畢之後,我們可以先檢視一下目前系統裡的 iptables (應該都是空的),注意,必須使用超級使用者執行 iptables 工具:

$ iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Linux 有三種 iptable:filter, natmangle;很明顯,nat 就是我們要使用的 iptable,而你也看到了在這個 iptable 裡有三個預設的 chain:

其它兩種 iptable 也各有內建的 chain,但此處就不贅述了。

接著要把適當的設定用 iptables 加入核心;假設我們有一個內部區域網路,要透過這台主機的 NAT 來連接外部的網路,但不讓外部網路連進內部網路。因此所需要 iptable 是 nat、chain 是 POSTROUTING;我們可以如下設定:

$ iptables -t nat -A POSTROUTING -p all -s src_ip/mask \
 -o through_interface -j SNAT --to outer_ip

指定了 iptable nat 與 chain POSTROUTING 之後,還有不少參數需要設定:

  1. -p:指定允許的通訊協定;all 代表所有的通訊協定。可以用 tcp, udp, icmp 等關鍵字、通訊埠數字號碼,或是 /etc/protocols 裡有列出的字串來進行指定。

  2. -s:指定這個規則 (rule) 的來源位址,格式是

    位址/[網路遮罩]
    

    我們可以指定單一 IP,或是一整個子網路。

  3. -o:指定封包要傳出所用的網路介面。

  4. -j:指定這條規則的目的地;我們這裡使用預先定義好的 SNAT,表示對封包的來源位址進行轉譯 (這適合於進行 IP 分享的應用)。

  5. --to:指定內部網路作 NAT 所對應到的外部 IP。

所以,我們所寫的設定指令可以這樣解釋:把 src_ip/mask 這個子網路送出的封包,用 SNAT 的方式轉譯成來自 outer_ip,交由 through_interface 傳到外部網路去。

iptables 是一個強大而複雜的工具,請參考 iptables (8) 以取得詳細的說明。

6   組態 DHCP 伺服器

DHCP 是指動態主機組態協定 (Dynamic Host Configuration Protocol);我們可以架設 DHCP 伺服器,透過區域網路來把設定資料提供給 DHCP 客戶端,從而達成組態自動化。DHCP 可以提供的組態設定相當地多樣化,不過它最主要的用途還是在於配發 IP 資訊。

DHCP 主要有兩種用法:建立一個 IP 位址庫 (pool),供區域網路任意的電腦自由使用;或者藉由各連線電腦的乙太網路路卡號來指定 IP 位址。

在 Debian 下用 apt 來安裝 DHCP 伺服器:

$ apt-get install dhcp3-server

dpkg 會詢問 dhcpd 要聽在哪一個網路介面上面;請適當地選擇。假設我要用來服務的子網路 192.168.3.0/24 是用 eth1 進行連線的話,那麼就應該聽在 eth1 上面。

dhcp3-server 的組態檔在 /etc/dhcp3/dhcpd.conf,預設的選項如下:

ddns-update-style none;
option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;
default-lease-time 600;
max-lease-time 7200;
log-facility local7;

不過,當我們安裝完畢,dpkg 嘗試啟動 dhcpd 的時候會出現錯誤:

Starting DHCP server: dhcpd3 failed to start - check syslog for diagnostics.

查看一下 /var/log/syslog,你會發現這是因為我們還沒有組態好的關係。

dhcpd.conf 的預設值裡沒有任何的 subnet 設定項,因此 DHCP 伺服器沒辦法送出組態設定 -- 在 DHCP 裡稱為租期 (lease)。以下我們舉一個用乙太網路卡號 (MAC address) 來指定網路設定的組態來當作範例:

subnet 192.168.3.0 netmask 255.255.255.0 {
  option domain-name-servers 192.168.3.254;
  option domain-name "example.org";
  option routers 192.168.3.254;
  option subnet-mask 255.255.255.0;
  option broadcast-address 192.168.3.255;
  default-lease-time 600;
  max-lease-time 7200;

  group {
    host hand01 {
      hardware ethernet 00:00:E2:76:C1:DF;
      fixed-address hand01.example.org;
      option host-name "leg01";
    }
    host hand02 {
      hardware ethernet 00:00:E2:76:C1:DA;
      fixed-address hand02.example.org;
      option host-name "leg02";
    }
    host hand03 {
      hardware ethernet 00:00:E2:76:C1:D5;
      fixed-address hand03.example.org;
      option host-name "leg03";
    }
  }
}

假設我們的子網路裡有三台主機會取用 DHCP 的設定:hand01, hand02hand03,只要知道這三台主機的 MAC address,就可以像上面這樣用 DHCP 伺服器來指定他們的網路設定。我們來解釋一下這些設定項所代表的意義:

以上的範例設定會把 hand01, hand02hand03 的 IP 位址分別設成了三個網域名稱;我們必須要有一台組態正確的網域伺服器 (DNS),其中包含了這三個名稱的 IP 才行。如果我們沒有架設 DNS,那麼 fixed-address 就應該要寫成用數字表示的 IP。

假設我們在為主機設定固定 IP 之餘,也需要一些不固定的 IP 可以提供給其它的電腦,只要在 subnet 區塊裡加上 range 設定項即可;``range`` 設定項的格式為:

range <起始 IP> <結尾 IP>;

dhcpd 的功能也是非常強大,設定項非常地多。我建議在設定之前先參考一下 dhcpd.conf (5)dhcp-options (5),你會發現非常多的花樣。

7   結語

本章我們對 Debian GNU/Linux 的基本網路組態方式,以及比較底層的網路服務作了一些簡單的介紹;接續之前章節對驅動網路介面的討論,這裡我們從最簡單的名稱解析設定檔開始,對 inetd 超級伺服器、基本的網路工具以及 NAT、DHCP 都作了說明。

這些過於簡單的介紹對於理解整個網路的構成來說,實在是不夠充分;不過它可以作為一個研究的起點,並且也會成為我們討論其它網路服務的基礎。