作者:H2KILL 本文所論述的是怎樣在Linux下不花一分錢就解決問題。本文將從最基本的接入方法開始,一步步的教你實現將使用私有IP的局域網帶入Internet的方法。 1.概述 通常我們所遇到的問題是這樣的:一個使用私有IP的局域網,一台聯入Internet的機器,然後要你通過一定的手段將整個局域網聯入Internet。其實,該方案的實現手段很多,比如在Windows下,你可以用諸如wingate、winroute以及MS Proxy等等代理軟件實現,但是本文所論述的是怎樣在linux下不花一分錢就解決問題。本文將從最基本的接入方法開始,一步步的教你實現將使用私有IP的局域網帶入Internet的方法。 2.接入方法: 常用的接入方法有撥號上網和專線上網。通常,個人用戶使用撥號上網方式,而單位用戶則使用專線上網方式。並且,撥號方式可以分為PSTN和ISDN撥號,專線則可以分為ISDN專線和DDN專線。 ISDN撥號方式一般用外置TA適配器,相當於模擬MODEM,Linux下的使用方法與外置MODEM一樣,內置的一般叫ISDN PC卡,Linux下一般較難配置,單位用戶也最好不買內置的,普通MODEM外置的也比內置的好。所以外置TA撥號上網可以歸入外置MODEM一樣,確實是一摸一樣。其實ISDN撥號方式就是數字式的MODEM,專線方式就是在路由器內部自己撥號,通過撥號聯接建立起來的類DDN方式。 ISDN的專線方式必須使用ISDN路由器,專線方式128K電信部門一般給8個合法的IP地址,ISDN路由器撥號是在路由器中進行的,另外ISDN路由器一般還帶4個網口,本身集成了PPP Server的功能,又相當於一台撥號服務器,ISDN專線方式還支持回撥功能,由局方向用戶撥號,建立聯接,聯接建立之後就相當於DDN了,Linux不涉及撥號,線路聯接設置等,就是路由器提供靜態IP。其實ISDN撥號方式就是數字式的MODEM,專線方式就是在路由器內部自己撥號,通過撥號聯接建立起來的類DDN方式。 DDN即數字數據網,DDN的專線方式通常是這樣實現的,路由器的廣域網口用V.35連接到基帶Medom,再由基帶Medom連接到DDN線路。 PSTN也就是我們通常所說的公用電話網。使用電話撥號上網也是目前個人用戶最常用的上網方式。但是在linux下要實現電話撥號上網並不是一件輕松的事,因為雖然在linux下的撥號工具很多,但是好多都得進行復雜的配置。在這裡,我們向讀者介紹一種最具智能化的撥號工具--wvdial,並用wvdial和ppp實現輕松上網。 wvdial是linux下的智能化撥號工具,利用wvdial和ppp可以實現linux下的輕松上網。在整個過程中wvdial的作用是撥號並等待提示,並根據提示輸入相應的用戶名和密碼等認證信息;ppp的作用是與撥入方協商傳輸數據的方法並維持該連接。 2.1.wvdial及其相關配置 wvdial的功能很強大,會試探著去猜測如何撥號及登錄到服務器,同時它還會對常見的錯誤智能的進行處理,不象chat一樣,要求你去寫登錄腳本。wvdial只有一個配置文件 /etc/wvdial.conf。wvdial的啟動過程是這樣的:首先載入wvdial.conf配置文件,然後再初始化modem並撥號,撥號後等待撥入方的響應,收到撥入方響應後則啟動pppd。 可以用wvdialconf程序自動生成wvdial.conf配置文件,自行該程序的格式為: wvdialconf /etc/wvdial.conf 在執行該程序的過程中,程序會自動檢測你的modem的相關配置,包括可用的設備文件名,modem的波特率,初始化字符等等相關的撥號信息,並根據這些信息自動生成wvdial.conf配置文件。如果/etc/wvdial.conf文件已經存在時,再次執行該命令只會改變其中的 Modem、Band、Init等選項。 wvdial的執行格式為: wvdial --help --version section 相關的說明如下: --help:顯示簡單的幫助信息 --version:顯示wvdial的版本號 section:這裡的section有點象windows裡的ini文件,一個wvdial.conf配置文件可以有好多個section,每一個section由一些變量組成,即由 變量=值 的語句組成,如上所示。使用wvdialconf自動生成配置文件時將會自動生成一些常用的變量說明如下: Inherits=InheritedSection: 使用wvdialconf自動生成配置文件時將會自動生成[Dialer Defaults],除此之外,你還 可以自定義你自己的section。程序運行時,首先載入[Dialer Defaults],然後再用指 定的section的相應選項覆蓋[Dialer Defaults]的相應選項。比如,我們在 wvdial.conf中還有[Dialer Tom],假如我們運行wvdail Tom,則系統將先讀入[Dialer Defaults],然後再用[Dialer Tom]覆蓋[Dialer Defaults]的相應選項。如果除了以上 的section之外還有[Dialer 169]並且內容如下: [Dialer Tom] Username=tom PassWord=xxx Inherits=169 [Dialer 169] Phone=169 如果這時候我們執行wvdial Tom則系統將先讀入[Dialer Defaults],然後再用[Dialer Tom]覆蓋[Dialer Defaults]的相應選項,最後再用[Dialer 169]的相應選項來覆蓋前二者的相應選項。由此可見,利用wvdial,我們可以很方便地在不同的ISP或modem之間來回移動(假如你有幾個ISP或medom的話)。 Medom=/dev/ttySx:用於指定是用的medom,缺省的為/dev/medom。當然,在這裡我們的medom是由wvdialconf自動檢測並配置的,所以我們可以忽略該變量。 Dial Prefix=x: 假如你正在使用分機,撥外線需撥9時,可設該值為9。 Username=xxxx:登錄時的用戶名 Passwd=xxxxxx:登錄密碼 Phone=xxxxx: 所撥的號碼 PPPP Path=:設置pppd所在的路徑,缺省為/usr/sbin/pppd New PPPD= 1 or 0: pppd 2.3.0及其以上版本需要/etc/ppp/peers/wvdial文件,如果你的pppd是2.3.0以上版本請設為1. Auto Reconnect=on :斷線時是否自動重新連接,缺省設為是。 以上只是wvdial.conf中的常用選項,具體情參考wvdial手冊。 2.2.pppd及其相關配置 pppd的配置選項相對要復雜得多,你可以用命令行的形式引用有關的選項,也可以把要引用的選項寫到/etc/ppp/options中進行引用。 下面的示例文件包含了最常用的選項及其相關的說明: # /etc/ppp/options # 如果指定了"noipdefault" 選項, pppd將使用撥入方提供的ip地址 noipdefault # 選定該選項, pppd 將接受撥入方自己的ip地址 ipcp-accept-remote # 設置缺省網關 defaultroute # 在傳輸數據包之前,讓撥入方先自我認證,注意一般的ISP(如169、163) #都不包含該機制,故應選中noauth noauth # 如果連接空閒了n秒後自動斷線 idle n 以上只是options中的常用選項,具體情參考pppd手冊。 3.實現手段 3.1.原理 從原理上,我們可以將實現的手段分為兩種。其一是通過IP欺騙,也就是通過網絡地址轉換(NAT)來實現;其二是通過代理軟件來實現,而通過代理的方法又可以分為傳統代理方法和透明代理方法。 3.1.1.IP欺騙的工作原理: IP欺騙技術已經出現好幾年了,現在linux下的IP欺騙技術已經很成熟了。 可以這樣說:IP欺騙技術已經支持大多數的常用協議。那麼IP欺騙是怎樣工作的呢,原理很簡單:客戶機將進行IP欺騙的linux機器設置為缺省網關,當進行IP欺騙的linux機器收到客戶機的請求包時,它對其進行改寫,將源地址替換為自己的合法IP地址,將源端口換成一個新的端口號,並且對該過程進行記錄;當收到Internet主機的響應包時,如果其端口號正是先前所指定的端口號則再對該包進行改寫,將其目的IP及目的端口號替換為原來記錄的客戶機IP和端口號,然後再發送給客戶機。 3.1.2.代理的工作原理: 在TCP/IP網絡中,傳統的通信過程是這樣的:客戶端向服務器請求數據,服務器響應該請求,將數據傳送給客戶端。在引入了代理服務器以後,這一過程變成了這樣:客戶端向服務器發起請求,該請求被送到代理服務器;代理服務器分析該請求,先查看自己緩存中是否有請求數據,如果有就直接傳送給客戶端,如果沒有就代替客戶端向該服務器發出請求。服務器響應以後,代理服務器將響應的數據傳送給客戶端,同時在自己的緩存中保留一份該數據的拷貝。這樣,再有客戶端請求相同的數據時,代理服務器就可以直接將數據傳送給客戶端,而不需要再向該服務器發起請求。 3.2.IP欺騙的實現 在內核版本2.2.x以上的linux中,我們可以通過ipchains來實現IP欺騙。 3.2.1.配置系統內核 確定你的內核已經配置了支持IP欺騙的相關特性,如果沒有,請你重新編譯內核。一般在RedHat6.x以上,系統已經缺省配置了這些特性。 3.2.2.裝載所需模塊 你可以在系統啟動時裝載所需模塊。可以在/etc/rc.d/rc.local文件中添加下列語句來在系統啟動時自動裝載所需模塊。 /sbin/depmod -a /sbin/modprobe ip_masq_FTP /sbin/modprobe ip_masq_raudio /sbin/modprobe ip_masq_irc /sbin/modprobe ip_masq_cuseeme /sbin/modprobe ip_masq_vdolive 等等。 3.2.3.啟用IP轉發 在2.2.x以上的版本中,IP轉發缺省是禁止的,你可以通過以下語句來啟用IP轉發。 echo "1" > /proc/sys/net/ipv4/ip_forwarding 如果你用的是Redhat的發行版本, 你也可以將/etc/sysconfig/network文件中的 FORWARD_IPV4=false改為FORWARD_IPV4=true來啟用IP轉發。然後重新啟動系統。 3.2.4.配置客戶端 步驟一、將客戶機的缺省網關設置為進行IP欺騙的機器的局域網口的IP; 步驟二、設置客戶機的DNS服務器為你真實的DNS服務器; 步驟三、設置浏覽器為直接與Internet相連; 3.2.5.設置ipchains規則 關於ipchains的詳細語法,你可以參考IPCHAINS-HOWTO文檔。這裡我們只給出具體的應用。 假設你的局域網IP為192.168.1.*,eth1為局域網口,eth0為廣域網口,則你可以設置如下的ipchains規則來實現IP欺騙: #!/usr/bin /sbin/ipchians -A forward -s 192.168.1.0/24 -d 0/0 -i eth0 -j MASQ 如果你使用撥號方式並且你的關於網口為ppp0,則相應的配置為: #!/usr/bin /sbin/ipchians -A forward -s 192.168.1.0/24 -d 0/0 -i ppp0 -j MASQ 3.3.傳統代理的實現 3.3.1.安裝軟件 我們以目前最新的穩定版本squid-2.3.STABLEX為例。 rpm包的安裝 1.進入/mnt/cdrom/RedHat/RPMS 2.執行rpm -ivh squid-2.2.STABLE4-8.i386.rpm。 當然,我們也可以在開始安裝系統的過程中安裝該軟件。 3.3.2.源代碼包的安裝 1.從http://www.squid-cache.org下載squid-2.3.STABLE2-src.tar.gz。 2.將該文件拷貝到/usr/local目錄。 3.解開該文件 tar xvzf squid-2.3.STABLE2-src.tar.gz。 4.解開後,在/usr/local生成一個新的目錄squid-2.3.STABLE2,為了方便用mv命令將該目錄重命名為squid mv squid-2.3.STABLE2 squid; 5.進入squid cd squid 6.執行./configure 可以用./confgure --prefix=/Directory/you/want指定安裝目錄 系統缺省安裝目錄為/usr/local/squid。 7.執行 make all 8.執行 make install 9.安裝結束後,squid的可執行文件在安裝目錄的bin子目錄下,配置文件在etc子目錄下。 3.3.3.配置squid 由於RedHat各方面的優勢(包括易用性,穩定性等等),全世界范圍內使用該發行版的用戶比較多,所以,我們下面的說明都是以RedHat6.1環境下squid-2.2.STABLE4-8版本為主。從我的使用經驗看來,該版本的squid要比其他版本穩定的多,以前的1.1.22版本也比較穩定,但是在功能及靈活性方面有所欠缺。 squid有一個主要的配置文件squid.conf,在RedHat環境下所有squid的配置文件位於/etc/squid子目錄下。 1.常用的配置選項 因為缺省的配置文件有問題,所以我們必須首先修改該配置文件的有關內容,以便讓squid跑起來。 下面我們來看一看一些常用的選項: 1.http_port 說明:定義squid監聽HTTP客戶連接請求的端口。缺省是3128,如果使用HTTPD加速模式則為80。你可以指定多個端口,但是所有指定的端口都必須在一條命令行上。 2.cache_mem (bytes) 說明:該選項用於指定squid可以使用的內存的理想值。這部分內存被用來存儲以下對象 : In-Transit objects (傳入的對象) Hot Objects (熱對象,即用戶常訪問的對象) Negative-Cached objects (消極存儲的對象) 需要注意的是,這並沒有指明squid所使用的內存一定不能超過該值,其實,該選項只 定義了squid所使用的內存的一個方面,squid還在其他方面使用內存。所以squid實際 使用的內存可能超過該值。缺省值為8MB。 3.cache_dir Directory-Name Mbytes Level-1 Level2 說明:指定squid用來存儲對象的交換空間的大小及其目錄結構。可以用多個cache_dir命令來定義多個這樣的交換空間,並且這些交換空間可以分布不同的磁盤分區。"directory "指明了該交換空間的頂級目錄。如果你想用整個磁盤來作為交換空間,那麼你可以將該目錄作為裝載點將整個磁盤mount上去。缺省值為/var/spool/squid。"Mbytes"定義了可用的空間總量。需要注意的是,squid進程必須擁有對該目錄的讀寫權力。"Level-1"是可以在該頂級目錄下建立的第一級子目錄的數目,缺省值為16。同理,"Level-2"是可以建立的第二級子目錄的數目,缺省值為256。為什麼要定義這麼多子目錄呢?這是因為如果子目錄太少,則存儲在一個子目錄下的文件數目將大大增加,這也會導致系統尋找某一個文件的時間大大增加,從而使系統的整體性能急劇降低。所以,為了減少每個目錄下的文件數量,我們必須增加所使用的目錄的數量。如果僅僅使用一級子目錄則頂級目錄下的子目錄數目太大了,所以我們使用兩級子目錄結構。 那麼,怎麼來確定你的系統所需要的子目錄數目呢?我們可以用下面的公式來估算。 已知量: DS = 可用交換空間總量(單位KB)/ 交換空間數目 OS = 平均每個對象的大小= 20k NO = 平均每個二級子目錄所存儲的對象數目 = 256 未知量: L1 = 一級子目錄的數量 L2 = 二級子目錄的數量 計算公式: L1 x L2 = DS / OS / NO 注意這是個不定方程,可以有多個解。 4.acl 說明:定義訪問控制列表。 定義語法為: acl aclname acltype string1 ... acl aclname acltype "file" ... 當使用文件時,該文件的格式為每行包含一個條目。 acltype 可以是 src dst srcdomain dstdomain url_pattern urlpath_pattern time port proto method browser user 中的一種。 分別說明如下: src 指明源地址。可以用以下的方法指定: acl aclname src ip-address/netmask ... (客戶ip地址) acl aclname src addr1-addr2/netmask ... (地址范圍) dst 指明目標地址。語法為: acl aclname dst ip-address/netmask ... (即客戶請求的服務器的ip地址) srcdomain 指明客戶所屬的域。語法為: acl aclname srcdomain foo.com ... squid將根據客戶ip反向查詢DNS。 dstdomain 指明請求服務器所屬的域。語法為: acl aclname dstdomain foo.com ... 由客戶請求的URL決定。 注意,如果用戶使用服務器ip而非完整的域名時,squid將進行反向的DNS解析來確 定其完整域名,如果失敗就記錄為"none"。 time 指明訪問時間。語法如下: acl aclname time [day-abbrevs] [h1:m1-h2:m2][hh:mm-hh:mm] day-abbrevs: S - Sunday M - Monday T - Tuesday W - Wednesday H - Thursday F - Friday A - Saturday h1:m1 必須小於 h2:m2,表達示為[hh:mm-hh:mm]。 port 指定訪問端口。可以指定多個端口,比如: acl aclname port 80 70 21 ... acl aclname port 0-1024 ... (指定一個端口范圍) proto 指定使用協議。可以指定多個協議: acl aclname proto HTTP FTP ... method 指定請求方法。比如: acl aclname method GET POST ... 5.http_Access 說明:根據訪問控制列表允許或禁止某一類用戶訪問。 如果某個訪問沒有相符合的項目,則缺省為應用最後一條項目的"非"。比如最後一條為允許,則缺省就是禁止。所以,通常應該把最後的條目設為"deny all" 或 "allow all" 來避免安全性隱患。 3.3.4.啟動、停止squid。 配置並保存好squid.conf後,可以用以下命令啟動squid。 squid 或者,使用RedHat的啟動腳本來啟動squid. /etc/rc.d/init.d/squid start 同樣地,你也可以用下列腳本停止運行squid或重啟動squid. /etc/rc.d/init.d/squid stop /etc/rc.d/init.d/squid restart 3.4.透明代理 關於透明代理的概念我們已經在第一節將過了,下面我們看一下怎麼樣在squid中實現透明代理。 透明代理的實現需要在Linux 2.0.29以上,但是Linux 2.0.30並不支持該功能,好在我們現在使用的通常是2.2.X以上的版本,所以不必擔心這個問題。下面我們就用ipchains+squid來實現透明代理。在開始之前需要說明的是,目前我們只能實現支持HTTP的透明代理,但是也不必太擔心,因為我們之所以使用代理,目的是利用squid的緩存來提高Web的訪問速度,至於提供內部非法ip地址的訪問及提高網絡安全性,我們可以用ipchains來解決。 實現環境:RedHat6.x+squid2.2.x+ipchains 3.4.1.linux的相關配置 確定你的內核已經配置了支持透明代理解的相關特性,如果沒有,請你重新編譯內核。一般在RedHat6.x以上,系統已經缺省配置了這些特性。 3.4.2.squid的相關配置選項 設置squid.conf中的相關選項,如下所示: http_port 3218 httpd_accel_host virtual httpd_accel_port 80 httpd_accel_with_proxy on httpd_accel_uses_host_header on 說明: 1.http_port 3128 在本例中,我們假設squid的HTTP監聽端口為3128,即squid缺省設置值。然後,把所有來自於客戶端web請求的包(即目標端口為80)重定向到3128端口。 2.httpd_accel_host virtual httpd_accel_port 80 這兩個選項本來是用來定義squid加速模式的。在這裡我們用virtual來指定為虛擬主機模式。80端口為要加速的請求端口。采用這種模式時,squid就取消了緩存及ICP功能,假如你需要這些功能,這必須設置httpd_accel_with_proxy選項。 3.httpd_accel_with_proxy on 該選項在透明代理模式下是必須設置成on的。在該模式下,squid既是web請求的加速器,又是緩存代理服務器。 4.httpd_accel_uses_host_header on 在透明代理模式下,如果你想讓你代理服務器的緩存功能正確工作的話,你必須將該選項設為on。設為on時,squid會把存儲的對象加上主機名而不是ip地址作為索引。這一點在你想建立代理服務器陣列時顯得尤為重要。 3.4.3.ipchains的相關配置 ipchains在這裡所起的作用是端口重定向。我們可以使用下列語句實現將目標端口為80端口的TCP包重定向到3128端口。 #接收所有的回送包 /sbin/ipchains -A input -j ACCEPT -i lo #將目標端口為80端口的TCP包重定向到3128端口 /sbin/ipchains -A input -p tcp -d 0.0.0.0/0 80 -j REDIRECT 80 當然在這以前,我們必須用下面的語句打開包轉發功能。 echo 1 > /proc/sys/net/ipv4/ip_forward