Linux下搭建 PPPoE Server 問題總結
注:本記錄適用于Debian系列Linux操作系統。在Ubuntu 14.10 以及 Linux Mint 17下驗證成功。
在綜合課程設計的搭建 PPPoE Server 環節中,本人以及組員碰到各種問題。在此總結,以備日后需要。
搭建過程
安裝和配置PPPoE程序
PPPoE程序在Debian操作系統中應該是自帶的。可以使用 pppoe-server -h
命令查看版本。可以使用 sudo apt-cache search pppoe
查找相關軟件。
配置文件存放在 /etc/ppp
文件夾中。先設置 options
文件:
- 設置 ms-dns的值。要設置成一個可以使用的DNS服務器的IP地址,比如
114.114.114.114
這是Windows主機撥號連接時會分配的DNS地址。 - 注釋掉+pap,取消-pap的注釋,這表示不使用pap認證方式。同時,取消+chap的注釋,表示使用chap認證方式。
接下來設置 chap-secrets
文件:
按照文件注釋的內容,分別填入:用戶名 服務器名 密碼 IP地址,例如,在最后插入一行:
testing * password *
表示用戶名為testing,服務器名為任意,密碼為password,IP為任意的IP。
下來,編輯 pppoe-server-options
文件(如果沒有,則新建一個1)
在pppoe-server-options里加入:
- 1
- 2
- 3
- 1
- 2
- 3
這樣就配置完畢了。
設置系統的ip策略
開啟ip轉發功能
使用超級用戶的身份,注意,必需是超級用戶身份,sudo都沒有這個權限,執行:
cat 1 > /proc/sys/net/ipv4/ip_forward
如果單單是執行這個命令,只會暫時開啟IP轉發功能。重啟后會自動關閉。如果想一直打開,則應該編輯 /etc/sysctl.conf
文件,取消net.ipv4.ip_forward=1
的注釋,再執行 sudo sysctl -p
就可以永久打開IP轉發功能了。
設置iptables的IP策略
以超級用戶身份執行:
iptables -A POSTROUTING -t nat -s 10.10.10.0/24 -j MASQUERADE
注:-s 參數后面的網絡地址是一會兒將要開啟的pppoe-server設置的網絡地址,這個地址可以根據需要自己設定,只要iptables和pppoe-server匹配就好。
運行PPPoE Server
輸入:
sudo pppoe-server -I wlan0 -L 10.10.10.1 -R 10.10.10.100 -N 100
注:
- -I 參數用于指定監聽哪個網絡端口。可以使用ifconfig命令查看當前工作的端口名稱。由于本人的筆記本電腦使用無線網絡,所以是wlan0端口。
- -L 參數用于指定在一個PPP連接中,PPPoE服務器的IP地址。由于本人假設的以太網網絡地址為10.10.10.0/24,所以就使用網絡地址的第一個IP地址作為服務器的地址了。
- -R 參數用于指定當有客戶連接到服務器上時,從哪個IP地址開始分配給客戶。
- -N 參數用于指定至多可以有多少個客戶同時連接到本服務器上。
如果一切順利,在Windows上建立撥號連接,用戶名和密碼分別為testing和password,應該就可以連接到linux下的PPPoE Server上并且正常上網了。
PPPoE 協議過程分析
過程圖解
PPPoE協議主要有以下幾個過程:
解釋
- 主機廣播發起分組(PADI),分組的目的地址為以太網的廣播地址0×ffffffffffff,CODE(代碼)字段值為0×09,SESSION-ID(會話ID)字段值為0×0000。PADI分組必須至少包含一個服務名稱類型的標簽(標簽類型字段值為0×0101),向接入集中器提出所要求提供的服務。
- 接入集中器收到在服務范圍內的PADI分組,發送PPPoE有效發現提供包(PADO)分組,以響應請求。其中CODE字段值為0×07,SESSION-ID字段值仍為0×0000。PADO分組必須包含一個接入集中器名稱類型的標簽(標簽類型字段值為0×0102),以及一個或多個服務名稱類型標簽,表明可向主機提供的服務種類。
- 主機在可能收到的多個PADO分組中選擇一個合適的PADO分組,然后向所選擇的接入集中器發送PPPoE有效發現請求分組(PADR)。其中CODE字段為0×19,SESSION_ID字段值仍為0×0000。PADR分組必須包含一個服務名稱類型標簽,確定向接入集線器(或交換機)請求的服務種類。當主機在指定的時間內沒有接收到PADO,它應該重新發送它的PADI分組,并且加倍等待時間,這個過程會被重復期望的次數。
- 接入集中器收到PADR分組后準備開始PPP會話,它發送一個PPPoE有效發現會話確認PADS分組。其中CODE字段值為0×65,SESSION-ID字段值為接入集中器所產生的一個唯一的PPPoE會話標識號碼。PADS分組也必須包含一個接入集中器名稱類型的標簽以確認向主機提供的服務。當主機收到PADS分組確認后,雙方就進入PPP會話階段。
- PPPoE還有一個PADT分組,它可以在會話建立后的任何時候發送,來終止PPPoE會話,也就是會話釋放。它可以由主機或者接入集中器發送。當對方接收到一個PADT分組,就不再允許使用這個會話來發送PPP業務。PADT分組不需要任何標簽,其CODE字段值為0×a7,SESSION-ID字段值為需要終止的PPP會話的會話標識號碼。在發送或接收PADT后,即使正常的PPP終止分組也不必發送。PPP對端應該使用PPP協議自身來終止PPPoE會話,但是當PPP不能使用時,可以使用PADT。
問題分析
連接時錯誤
Windows撥號連接顯示錯誤651
可能的原因是沒有正確打開服務器。通過WireShark抓包可以看到,Windows在發送了4次PADI報文而沒有得到PADO回復后,會報告引錯誤。
因此,可能是在 pppoe-server
打開時沒有指定到正確的網卡。也可能是使用虛擬機上網時沒有設置好上網模式,如果沒有使用橋接模式上網而是使用了NAT模式,則也可能遇到此問題。
同時,如果沒有pppoe-server-options
文件或者該文件沒有 auth
和 require-chap
選項設置的話,也會出現這個問題。
同時,該問題也可能是因為在Windows撥號連接時在屬性中指定了一個服務器,和linux下開啟的PPPoE Server名稱不同造成的。
pppoe-server中,-S參數用于指定服務器名稱。
Windows撥號連接顯示錯誤734
錯誤內容為
PPP鏈接控制協議終止
這個原因可能是在 pppoe-server-options
文件中加入了 login
選項。如果設置了該選項,則登陸的用戶名必需和linux系統下的一個用戶名相同,否則會出現這個錯誤。
Windows撥號連接顯示錯誤628
錯誤內容為
在連接完成前,連接被遠程計算機終止
通過WireShark抓包分析,可以看到在原理分析的四個階段完成后,立刻收到一個PADT報文。PADT報文的內容描述為:
Generic-Error: RP-PPPOE: child pppd process terminated
這個描述十分有誤導性,網上甚至有人說這個需要將pppoe編譯進內核,以便可以使用pppoe-server命令的-k參數。后來我發現終究是配置問題,出現了配置錯誤,一般是出現了程序無法識別的配置。這個錯誤很麻煩,應當結合剛剛配置的logfile以及自己注釋掉一些不確定的命令來排查錯誤。
無法識別用戶名和密碼
很可能是用戶名和密碼輸入錯誤,也可能是設置錯誤。注意,設置用戶名和密碼時,兩個星號是不能省略的。
上網錯誤
此類錯誤是Windows可以撥號連接成功,但是無法上網。主要是在linux下使用 tcpdump
或者 wireshark
程序進行排查。
使用命令:
tcpdump -i wlan0 host 10.10.10.100
2
可以看到,只有從主機10.10.10.100發出的報文,但是沒有發送給10.10.10.100的報文。
出現這個錯誤的原因,可能是沒有打開IP轉發功能。所以當網絡上的報文發送給linux主機時,linux主機不會把報文轉發給Windows主機,而是由于目的地址不是自己而直接丟棄。
同時也可能是沒有設置iptables
的POSTROUTING的nat規則。
網絡拓撲相關問題
一般是在虛擬機上安裝一個linux操作系統,搭好PPPoE Server。然后在宿主機上進行連接測試。則有以下幾個問題:
- 如果虛擬機采用NAT模式,則宿主機無法登陸。因為NAT模式下,宿主機是無法與虛擬機通信的。各種模式下的通信功能見下圖:
- 如果采用的是有線網絡,則無法使用橋接模式。因為有線網絡為固定IP,無法為橋接再分配一個IP地址。因此,最好的方法是使用無線網絡。
- 如果宿主機是linux操作系統,則可以虛擬Windows XP,同時使用Host-Only模式,設置好相應的網絡地址,不啟用DHCP服務器,在Windows XP中設置好自己的IP、子網掩碼,這樣就可以和宿主機進行通信了。在這樣的情況下,沒有撥號連接時無法上網,撥號連接好可以上網,是對實驗環境的最近似的模擬。
目前碰到的問題就是這樣了,以后碰到問題再添加吧。最重要的是理解各個步驟和協議的原理,這樣才能快速排查錯誤的原因。
- 這個問題困擾了我很久。網上說是編輯這個文件,但是在操作系統中沒有這個文件,我一直以為是版本的問題,后來才發現需要自己新建。這個和.vimrc以及.bashrc等文件是一樣的。 ↩
- -i用于指定端口,host指定的ip應該在windows用ipconfig查看得到,可能不一樣。