通常我們所遇到的問題是這樣的:一個使用私有IP的局域網,一台聯入Internet的機器,然後要你通過一定的手段將整個局域網聯入Internet。其實,該方案的實現手段很多,比如在Windows下,你可以用諸如wingate、winroute以及MS Proxy等等代理軟件實現,但是本文所論述的是怎樣在Linux下不花一分錢就解決問題。本文將從最基本的接入方法開始,一步步的教你實現將使用私有IP的局域網帶入Internet的方法。
二、接入方法:
常用的接入方法有撥號上網和專線上網。通常,個人用戶使用撥號上網方式,而單位用戶則使用專線上網方式。並且,撥號方式可以分為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的作用是與撥入方協商傳輸數據的方法並維持該連接。
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.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手冊。
三、實現手段
1.原理
從原理上,我們可以將實現的手段分為兩種。其一是通過IP欺騙,也就是通過網絡地址轉換(NAT)來實現;其二是通過代理軟件來實現,而通過代理的方法又可以分為傳統代理方法和透明代理方法。
1.1 IP欺騙的工作原理:
IP欺騙技術已經出現好幾年了,現在linux下的IP欺騙技術已經很成熟了。
可以這樣說:IP欺騙技術已經支持大多數的常用協議。那麼IP欺騙是怎樣工作的呢,原理很簡單:客戶機將進行IP欺騙的linux機器設置為缺省網關,當進行IP欺騙的linux機器收到客戶機的請求包時,它對其進行改寫,將源地址替換為自己的合法IP地址,將源端口換成一個新的端口號,並且對該過程進行記錄;當收到Internet主機的響應包時,如果其端口號正是先前所指定的端口號則再對該包進行改寫,將其目的IP及目的端口號替換為原來記錄的客戶機IP和端口號,然後再發送給客戶機。
1.2 代理的工作原理:
在TCP/IP網絡中,傳統的通信過程是這樣的:客戶端向服務器請求數據,服務器響應該請求,將數據傳送給客戶端。在引入了代理服務器以後,這一過程變成了這樣:客戶端向服務器發起請求,該請求被送到代理服務器;代理服務器分析該請求,先查看自己緩存中是否有請求數據,如果有就直接傳送給客戶端,如果沒有就代替客戶端向該服務器發出請求。服務器響應以後,代理服務器將響應的數據傳送給客戶端,同時在自己的緩存中保留一份該數據的拷貝。這樣,再有客戶端請求相同的數據時,代理服務器就可以直接將數據傳送給客戶端,而不需要再向該服務器發起請求。
2. IP欺騙的實現
在內核版本2.2.x以上的linux中,我們可以通過ipchains來實現IP欺騙。
2.1配置系統內核
確定你的內核已經配置了支持IP欺騙的相關特性,如果沒有,請你重新編譯內核。一般在RedHat6.x以上,系統已經缺省配置了這些特性。
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
等等。
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轉發。然後重新啟動系統。
2.4 配置客戶端
步驟一、將客戶機的缺省網關設置為進行IP欺騙的機器的局域網口的IP;
步驟二、設置客戶機的DNS服務器為你真實的DNS服務器;
步驟三、設置浏覽器為直接與Internet相連;
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.1 安裝軟件
我們以目前最新的穩定版本squid-2.3.STABLEX為例。
rpm包的安裝
1.進入/mnt/cdrom/RedHat/RPMS
2.執行rpm -ivh squid-2.2.STABLE4-8.i386.rpm。
當然,我們也可以在開始安裝系統的過程中安裝該軟件。
3. 源代碼包的安裝
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.2 配置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啟動、停止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
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
4.1 linux的相關配置
確定你的內核已經配置了支持透明代理解的相關特性,如果沒有,請你重新編譯內核。一般在RedHat6.x以上,系統已經缺省配置了這些特性。
4.2squid的相關配置選項
設置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地址作為索引。這一點在你想建立代理服務器陣列時顯得尤為重要。
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
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
3.httpd_accel_with_proxy on
該選項在透明代理模式下是必須設置成on的。在該模式下,squid既是web請求的加速器,又是緩存代理服務器。
4.httpd_accel_uses_host_header on
在透明代理模式下,如果你想讓你代理服務器的緩存功能正確工作的話,你必須將該選項設為on。設為on時,squid會把存儲的對象加上主機名而不是ip地址作為索引。這一點在你想建立代理服務器陣列時顯得尤為重要。
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