PCZONE 討論區

PCZONE 討論區 (https://www.pczone.com.tw/vbb3/)
-   -- FreeBSD & Linux 討 論 版 (https://www.pczone.com.tw/vbb3/forum/41/)
-   -   【教學】自動重撥 PPPoE ADSL 連線 (For Linux & FreeBSD) (https://www.pczone.com.tw/vbb3/thread/41/102355/)

dekuo 2004-10-17 06:51 PM

【教學】自動重撥 PPPoE ADSL 連線
 
不管是 Linux 或是 BSD 下所使用的 PPPoE 撥號程式,在遇到很多奇怪的斷線狀況似乎並不能很自動的自己重撥,所以我寫了這個 Script , 相信很多人都用的上.

[quote]
星期六, 三月 19, 2005
FreeBSD 的 PPPoE ADSL 斷線自動重撥

不管是 Linux 或是 BSD 下所使用的 PPPoE 撥號程式,在遇到很多奇怪的斷線狀況似乎並不能很自動的自己重撥,所以我寫了這個 Script , 相信很多人都用的上.

因為後來新版的 Perl 對 system/exec 等指令的傳回值處理方式似乎已經不同,最好的偵測方式是用 Perl Module,而不是呼叫系統指令,所以需要先裝 Net::Ping::External

用 CPAN 來安裝的話請依照以下步驟 ( CPAN 還沒設定過的請先設定):

perl -MCPAN -e shell

cpan shell -- CPAN exploration and modules installation (v1.7601)
ReadLine support enabled

cpan> install Net::Ping::External

裝好用就可以使用下面這個 script . 我使用的環境是 FreeBSD , 如果不是這個環境請自行修裡面有用到的系統指令的路徑,還有修改 $PPPoE_command 變數.

在跟 PC Zone 阿土站長 討論過以後,我稍微改了一下程式並附上我自己的 ppp.conf
不使用 killall 來砍掉 ppp 的 pid 是顧慮到這個 command 在 Linux 可能沒有,所以我採用比較傳統的方式處理.

-------------------------------------------------------------
以下是我的 /etc/ppp.conf 內容 (參考 FreeBSD Handbook):


default:set log Phase tun command # you can add more detailed logging if you wishset ifaddr 10.0.0.1/0 10.0.0.2/0hinet:set device PPPoE:rl0set authname 你的帳號@hinet.netset authkey 你的密碼set dialset loginadd default HISADDRnat enable yes
啟動 PPPoE 的方式我是建議寫在 /etc/rc.local ,加上一行:

/usr/sbin/ppp -ddial hinet

---------------------------------------------------------
以下為 Script 內容:
##############################################
#!/usr/local/bin/perl

$|=1;

#=============================================
# Programming by Dekuo Kuo in 2005/02/13
# [url]http://www.dekuo.com/[/url]
#
# This script is running on FreeBSD.
# When you run it on other Unix like OS,
# modify below variable $PPPoE_command and
# system command path used in this script

$PPPoE_command = '/usr/sbin/ppp -ddial hinet';
#=============================================


if (ping_basic('168.95.1.1') != 1 && ping_basic('192.72.80.36') != 1) {
$pid_reference = get_pid("$PPPoE_command");
print "ADSL Link Down\n";

foreach $pid (@$pid_reference) {
print "Kill pid=$pid ...\n";
system("/bin/kill $pid") if $pid != '';
}

system("$PPPoE_command");
system("/bin/date >> /var/log/check_pppoe.log");
} else {
print "ADSL Link Up\n";
}

sub get_pid {
$process_string = $_[0];
$process_string = "\'" . $process_string . "\'";
@ps_data = grep {!/grep/} `ps -ax | grep $process_string`;

my @pid_list;
foreach (@ps_data) {
@ps_line = grep { $_ ne ''} split(/\s+/,$_);
push(@pid_list,$ps_line[0]);
}

return \@pid_list;
}

sub ping_basic {
use Net::Ping::External qw(ping);
my $device_ipv4 = $_[0];
my $alive = ping(hostname => "$device_ipv4", timeout => 5, count => 5, size => 1024);
return $alive;
}
##############################################

最後 ,當然不要忘了在 crontab 裡加一行 ... 大概 5 分鐘檢查一次應該夠了

crontab 範例 (當然要先建立 /root/script 這個目錄) :
*/5 * * * * /root/script/check_pppoe.pl


如果您用的是 FreeBSD 5.x 的版本, 請在 crontab 最上面放下面這兩行敘述:
SHELL=/bin/tcsh
PATH=/etc:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin

否則會讓 perl 找不到相關 module

也就是說,如果您用的是 FreeBSD 5.x 以上的版本, 您的 crontab 內容就必須是這樣:
SHELL=/bin/tcsh
PATH=/etc:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
*/5 * * * * /root/script/check_pppoe.pl

為什麼 FreeBSD 5.x 不能夠使用 /etc/crontab 的 Shell 參數,這點我還不明白,如果有人瞭解的還請麻煩留言告知

另外, 如果有人在 Linux 環境下使用, 也請告訴我, 我想知道 Linux 下的 Command 路徑有沒有變
[/quote]

阿 土 2004-10-17 11:13 PM

這幾天找了不少 PPPoE in FreeBSD 的資料 (ppp / mpd)
但很少看到有人討論到斷線重連部分
dekuo 的這篇教學剛好可以拿來研究一下 , Thanks!:)

dekuo 2004-10-18 01:21 PM

[QUOTE][i]最初由 阿 土 發表[/i]
[B]這幾天找了不少 PPPoE in FreeBSD 的資料 (ppp / mpd)
但很少看到有人討論到斷線重連部分
dekuo 的這篇教學剛好可以拿來研究一下 , Thanks!:) [/B][/QUOTE]

我查過 ppp 的 Man page 說明, -ddial 應該就是會一直保持連線的參數,
但是我還是發現會有斷線沒自動重撥的現象 ... 所以不管我的 script 是否多此一舉(或許有更正確的系統設定方式?) ,但是至少可以保證用了之後必定能夠自動重撥 .... 但是 ATU-R 當掉的大概就沒辦法了 .. :D

阿 土 2004-10-18 02:08 PM

[QUOTE][i]最初由 dekuo 發表[/i]
[B]我查過 ppp 的 Man page 說明, -ddial 應該就是會一直保持連線的參數,
但是我還是發現會有斷線沒自動重撥的現象 ... 所以不管我的 script 是否多此一舉(或許有更正確的系統設定方式?) ,但是至少可以保證用了之後必定能夠自動重撥 .... 但是 ATU-R 當掉的大概就沒辦法了 .. :D [/B][/QUOTE]

沒錯 , 這幾天測試下來 ppp 當斷線時有時並不會自動重撥
使用您這個 script 測幾天看看 :)

我用 ppp 撥接上 ftp.nsysu.edu.tw 抓幾百 MB 的 ISO 檔
隨著抓取檔案的速度越來越快 , ppp 的 cpu usage 也持續爬升
改用 mpd 撥接後 , cpu usage 比 ppp 少了許多
不過不知為何 , 有時會發生無法撥上線的狀況 , 所以還是改回 ppp 撥接
因為以上傳為主的 SERVER , 其 ppp 的 usage 並不會太高

dekuo 2004-10-18 04:28 PM

[QUOTE][i]最初由 阿 土 發表[/i]
[B]沒錯 , 這幾天測試下來 ppp 當斷線時有時並不會自動重撥
使用您這個 script 測幾天看看 :)

我用 ppp 撥接上 ftp.nsysu.edu.tw 抓幾百 MB 的 ISO 檔
隨著抓取檔案的速度越來越快 , ppp 的 cpu usage 也持續爬升
改用 mpd 撥接後 , cpu usage 比 ppp 少了許多
不過不知為何 , 有時會發生無法撥上線的狀況 , 所以還是改回 ppp 撥接
因為以上傳為主的 SERVER , 其 ppp 的 usage 並不會太高 [/B][/QUOTE]

若是使用其它 PPP 撥號程式也可以用我吶 script ..

只要改掉這兩行就行:

$pid = get_pid("/usr/sbin/ppp -ddial $PPPoE_profile");
這行是你程式用 ps 查到的字串,可以改成你在用的 mpd

system("/usr/sbin/ppp -ddial $PPPoE_profile");
這行是您要啟動的 PPP 撥號程式指令

阿 土 2004-10-19 12:44 AM

又斷線了 , 以 ps -aux | grep ppp 找到很多筆 ppp 的資料

[quote]
root 61858 0.0 0.1 2704 1744 ?? Ss 12:32AM 0:00.10 /usr/sbin/ppp -d
root 61837 0.0 0.1 2704 1744 ?? Ss 12:31AM 0:00.11 /usr/sbin/ppp -d
root 61701 0.0 0.1 2704 1748 ?? Ss 12:27AM 0:00.17 /usr/sbin/ppp -d
root 530 0.0 0.1 2836 1836 ?? Ss 8:39AM 11:38.01 /usr/sbin/ppp -d[/quote]

script 改成 "killall ppp" 直接把所有 ppp 停掉再做重撥是否會比較好?

dekuo 2004-10-19 01:27 PM

[QUOTE][i]最初由 阿 土 發表[/i]
[B]又斷線了 , 以 ps -aux | grep ppp 找到很多筆 ppp 的資料



script 改成 "killall ppp" 直接把所有 ppp 停掉再做重撥是否會比較好? [/B][/QUOTE]

因為你執行 ppp 的指令跟我不同 ...所以要改成這樣:

$pid = get_pid("/usr/sbin/ppp -d");

你會發現很多支 ppp 是因為沒砍掉又重複執行 ...
只要把餵給 get_pid 的識別字串打對,應該都找的出來
用 killall 當然很棒 ...可是在 Linux 下好像就沒這個指令了
所以我才用比較基礎的方式來比對

我找時間在改一下 Script ,然後公佈我自己用的 ppp.conf 好了 ...
這樣大家比較看的懂我的 script 怎麼用

阿 土 2004-10-19 01:44 PM

[QUOTE][i]最初由 dekuo 發表[/i]
[B]因為你執行 ppp 的指令跟我不同 ...所以要改成這樣:

$pid = get_pid("/usr/sbin/ppp -d");[/B][/QUOTE]

是我 key 錯了 , 其實也是 "ppp -ddial hiet"

不過開機後的第一個 ppp process 卻是 "/usr/sbin/ppp -quiet -ddial -nat hinet"

不過 ppp.conf 並沒有設定 nat , 也不知道怎麼會跑出來的

[quote]
我的 ppp.conf

default:
set log phase tun command
enable dns

hinet:
set device PPPoE:fxp1
set mtu 1492
set mru 1454
set speed sync
enable lqr
set cd 5
set dial
set ctsrts off
set ifaddr 10.0.0.1/0 10.0.0.2/0
set login
add default HISADDR
set authname hinet-id
set authkey password
set timeout 0
set redial 3 5
set lqrperiod 5
set reconnect 5 10000[/quote]

[quote]
rc.conf 的設定

ppp_enable="YES"
ppp_mode="ddial"
ppp_profile="hinet"[/quote]

dekuo 2004-10-19 03:25 PM

[QUOTE][i]最初由 阿 土 發表[/i]
[B]是我 key 錯了 , 其實也是 "ppp -ddial hiet"

不過開機後的第一個 ppp process 卻是 "/usr/sbin/ppp -quiet -ddial -nat hinet"

不過 ppp.conf 並沒有設定 nat , 也不知道怎麼會跑出來的 [/B][/QUOTE]

你 config 檔寫太複雜了 ...看看我的 ..
我已經改過重新 Post 了

[URL=http://dekuo.blogspot.com/2004/10/pppoe-adsl-perl-script-linux-bsd-pppoe.html]新版自動撥號 Script[/URL]

如果您有啟動 natd 也要關掉 ...用 ppp 的 NAT 就好了

dekuo 2004-10-19 11:04 PM

[QUOTE][i]最初由 dou0228 發表[/i]
[B]剛寫了一個用 TCP 連 Port 80 的 PHP script

Ping 其實有的時候會被 ISP 無端的檔下來..
用 Ping 用一定的風險在

TCP 連 HTTP 也不是沒風險..
只是較不會像 ICMP 那樣常被欄下來.. :eye:

他會亂數的取 Server 列表去連網頁
萬一發現 連不上, 它會試三次, 不行才會重新啟動 ppp

註: killall 在 Linux Distro. 裡會有, 請放心 ;) [/B][/QUOTE]

嗯嗯 ..您這程式寫的更完善 ... 真是不錯 ^_^

不過我不用 killall 的原因是其實我的 script 也可以用在其它 Unix ...例如 Solaris 就沒有內建 killall 這個指令

而且我用 Perl 寫的原因是因為 Perl 應該是所有 Unix Like OS 都會內建的程式,但是 PHP CLI 卻得靠 User 自己另外做 (或者是 RedHat 完整安裝也會做出 PHP CLI ? 但不見得每個 User 都會完整安裝)

另外我相信 Hinet 也沒那個狗膽去擋 ICMP ... :D 其它夠種的 ISP 我就懶的管了

當然啦 ... 我的看法是用 Perl 來寫出您那個程式的版本是最理想的啦 ... ^_^

dekuo 2004-10-23 02:20 PM

真是慚愧 ... 我之前手賤改過這支 script 就沒再全程測試一遍 ...
今天才發現我自己的 bsd 斷了但是 ppp 不但沒砍掉還累積了一堆 ppp process ...

我有再度採用比較嚴謹的方式改寫 script .. 這次確定可以用 ...
不過我猜要用在 Linux 可能得確認一下 ps 指令取得的結果 ... 否則我抓的 pid 欄位會不準 ...

等我想到比較好的方式再來修改好了 ..

[URL=http://dekuo.blogspot.com/2004/10/pppoe-adsl-perl-script-linux-bsd-pppoe.html]2004/10/23 版 script[/URL]

dekuo 2004-10-26 05:49 PM

[QUOTE][i]最初由 dou0228 發表[/i]
[B]ps 在 Linux/FreeBSD 命令還算有相關性, 如果到了 Solaris 可就( 沒記錯的話是 ps -ef )
我的建議是根本不要用 ps 去判斷, 因為有 portable 問題

解法則是:
1. 不要用 Script 啦, 用 C 寫, 以 EXEC(3) 那類的執行, 自然可以控制 pppd, 但是要小心使用 EXEC(3) 那類的函式, 否則會有安全性問題
2. 以 pppd 的 pidfile 來做不就得了, 這樣解起來就容易的多

pppd 有一個選項: linkname <name>
因此, pppd 會建立 /var/run/ppp-<name>.pid 或是 /etc/ppp/ppp-<name>.pid
如此, 該檔案內容自然就是 pid 囉
而且這樣可以同時跑兩個 pppd 也不須要 killall 砍掉其它的 pppd [/B][/QUOTE]

ccc ... 我承認我的 script 現在只適合 FreeBSD Only ... 因為我真的沒 Linux 的環境可以測試,也懶的測

我是認為這種東西用 C 寫就太累了 .... 偵測 process 這種事情並沒有啥 performance 方面的問題,至於 /var/run/xxx.pid 的機制也不是每種 Unix 都會乖乖的產生

所以我還是喜歡 perl or php 寫出來的版本,比較好散布 ...
在處理 PID 的部份,的確有更精準的方式 ...但是 ... 目前來看應該夠準了啦 ... 如果這是用於企業重要的 ADSL ... 自然還有很多方法可以寫的超嚴謹

至於您提到的同時 Run 兩個 ppp 的問題,我的確沒考慮過 ...不過一般人應該比較少用到 ...

這是我的看法 ... 很高興跟您討論

可以 PM 我斯小討論技巧,交換心得 :D

dshyi 2005-02-11 11:42 PM

感謝阿...我一改完...
測速就快了10kbps左右...

是幻覺嗎!?

dekuo 2005-02-13 02:31 PM

[URL=http://dekuo.blogspot.com/2005/03/freebsd-pppoe-adsl-linux-bsd-pppoe.html] FreeBSD 的 PPPoE ADSL 斷線自動重撥 2005/03/19 Update[/URL]

阿 土 2005-03-31 07:04 PM

[QUOTE=dekuo][URL=http://dekuo.blogspot.com/2005/03/freebsd-pppoe-adsl-linux-bsd-pppoe.html] FreeBSD 的 PPPoE ADSL 斷線自動重撥 2005/03/19 Update[/URL][/QUOTE]

又有新版程式 , 有新增哪些功能嗎 ?
這支程式對於以 linux or FreeBSD 搭配 ADSL 架站的朋友來說 , 真的是超實用的
以下是我錯誤的 log 檔 , 今天也有發揮幾次作用 , 減緩當站的時間 :)
[quote]
Wed Dec 29 12:00:06 CST 2004
Wed Dec 29 12:05:06 CST 2004
Sat Jan 22 10:55:05 CST 2005
Sat Jan 22 11:00:05 CST 2005
Mon Feb 7 16:50:05 CST 2005
Mon Feb 7 16:55:05 CST 2005
Wed Mar 2 08:35:05 CST 2005
Wed Mar 2 08:40:06 CST 2005
Wed Mar 2 08:45:05 CST 2005
Wed Mar 2 08:55:06 CST 2005
Wed Mar 2 09:00:05 CST 2005
Fri Mar 11 18:15:05 CST 2005
Fri Mar 11 18:20:05 CST 2005
Thu Mar 24 22:55:06 CST 2005
Thu Mar 24 23:00:05 CST 2005
Thu Mar 31 17:10:05 CST 2005
Thu Mar 31 17:15:06 CST 2005
Thu Mar 31 17:20:05 CST 2005
Thu Mar 31 17:25:05 CST 2005
[/quote]

dekuo 2005-04-02 03:16 PM

[QUOTE=ADMIN]又有新版程式 , 有新增哪些功能嗎 ?
這支程式對於以 linux or FreeBSD 搭配 ADSL 架站的朋友來說 , 真的是超實用的
以下是我錯誤的 log 檔 , 今天也有發揮幾次作用 , 減緩當站的時間 :)[/QUOTE]

我看您的 log 好像 5 分鐘就斷一次 .. 您應該沒改成最新的版本 ...
這篇程式我改過三次, 第一版的會判斷 PID 錯誤 ... 所以會每次執行每次誤砍 ppp
第二版的程式才是改成可以正確執行的 ..
至於第三版, 程式沒啥問題, 我是加了下面這段文字:
[code]
如果您用的是 FreeBSD 5.x 的版本, 請在 crontab 最上面放下面這兩行敘述:
SHELL=/bin/tcsh
PATH=/etc:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin

否則會讓 perl 找不到相關 module

也就是說,如果您用的是 FreeBSD 5.x 以上的版本, 您的 crontab 內容就必須是這樣:
SHELL=/bin/tcsh
PATH=/etc:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
*/5 * * * * /root/script/check_pppoe.pl

為什麼 FreeBSD 5.x 不能夠使用 /etc/crontab 的 Shell 參數,這點我還不明白,如果有人瞭解的還請麻煩留言告知
[/code]

詳細的全文還是到 我 [url=http://dekuo.blogspot.com/2005/03/freebsd-pppoe-adsl-linux-bsd-pppoe.html]blog[/url] 上看比較準

selfhu 2007-07-27 04:53 AM

回覆: 【教學】自動重撥 PPPoE ADSL 連線 (For Linux & FreeBSD)
 
[QUOTE=dekuo;782329][URL=http://dekuo.blogspot.com/2005/03/freebsd-pppoe-adsl-linux-bsd-pppoe.html] FreeBSD 的 PPPoE ADSL 斷線自動重撥 2005/03/19 Update[/URL][/QUOTE]

((不好意思...檔案已經找不到了))

之前我也有調整過相關的設定
但有時候我故意去把小烏龜的線拔掉來製造斷線的狀況(電話線端)
發現會偵測不出來

到最後我就直接改成每天固定在清晨的時候自動重撥一次(開始變懶了:fd: )

artsppdaniel 2009-01-20 10:09 PM

回覆: 【教學】自動重撥 PPPoE ADSL 連線 (For Linux & FreeBSD)
 
這script 真是太棒囉,又學到不少知識,先謝過各位囉.:D


所有時間均為 +8。現在的時間是 07:51 PM



 XML   RSS 2.0   RSS 
本站使用 vBulletin 合法版權程式
站務信箱 : [email protected]

本論壇所有文章僅代表留言者個人意見,並不代表本站之立場,討論區以「即時留言」方式運作,故無法完全監察所有即時留言,若您發現文章可能有異議,請 email :[email protected] 處理。