パート1.受信したアドレスの検証
かつて、アカドはpppoeの認証に問題がありました。
また、システムをロードするときに、一部のデーモンは受信したIPアドレスに関連付けられていたため、システムのブートプロセスを何らかの方法で自動化し、ダウンタイムの状況を排除する必要がありました。
アイデアは、pppdの起動後にプロバイダーから受信したアドレスを確認することでした。
スクリプト自体は次のとおりです。
i=0
pppip="<my_ip>"
echo -e "waiting pppoe connection"
until [ "$i" -eq "30" ]
do
iconf=`/sbin/ifconfig tun0 | awk '/inet/ {print $2}'`
if [ "$iconf" = "$pppip" ]
then
echo -e "successful"
i="30"
break
else
i=`expr $i + 1`
echo -n "."
sleep 5
fi
done
if [ "$iconf" != "$pppip" ]
then
echo -e "pppoe not connected!\nSystem will be reboot"
reboot
fi
/etc/rc.d/pppに追加されました。
必要なアドレスを取得できなかった場合は、マシンを再起動するよう送信します。
pppデーモン自体を再起動しようとしないのはなぜですか?
検証の時点ではまだ多くは開始されていないため、再起動に時間がかかるバージョンを除外します。プロセスが停止するまで、設計を複雑にすることは本当にしたくありませんでした。
パート2.接続チェック
上記の状況に加えて、接続損失の問題が発生する場合があります。
パケットの飛行が続くことを予約したいです。 方法:
- ローカルネットワークの作業には、dhcpプロバイダーサーバーから発行されたアドレスが使用されます。
- pppoeは外に出るために使用されます。
スクリプトは10分間クラウンで実行され、内部アドレスへのpingが失敗した場合、dhcpから外部アドレスへのアドレスの取得を試みます。pppdを再起動します。
#!/ usr / bin / perl 厳格な使用; 警告を使用します。 スレッドを使用します。 タッチを使用します。 Netを使用:: Ping; Use Net :: Ifconfig :: Wrapper qw(Ifconfig); 私の@check_hosts = qw / ya.ru google.com/; 私の@check_ips = qw / 172.18.1.1 172.18.1.2/; 私の$ int_if = 're0'; 私の$ ext_if = 're1'; sub get_ips { my($ iface)= @_; 私の@ifaces =(); my $ info = Ifconfig( 'list'、 ''、 ''、 ''); (定義済み($情報-> {$ iface})){ die "$ ifaceでIPアドレスが見つかりませんでした\ n"; } for(sort keys%{$ info-> {$ iface} {'inet'}}){ push(@ ifaces、$ _); } if(スカラー(@ifaces)> 0){ return \ @ifaces; } その他{ undefを返します。 } } sub ping_state { my($ dst_src、$ proto、$ iface)= @_; die「サブping_stateのパラメーターをチェック」 場合を除き(定義済み($ dst_src)&& ref($ dst_src)eq 'ARRAY'); $ proto = '' (定義($ proto))しない限り、 my $ p = Net :: Ping-> new($ proto); 私の$ int_ips = undef; $ int_ips = get_ips($ iface) if(定義済み($ iface)); $ p-> bind($ int_ips-> [0]) if(defined($ int_ips)); 私の$ i = 0; $ソース(@ {$ dst_src}){ if($ p-> ping($ sources、10)){ $ i ++; 最後; } } $ p-> close(); if($ i> 0){return 1; } else {0を返す; } } sub do_log { my($メッセージ、$ log_file)= @_; $ log_file = '/var/log/ifaces.log' (defined($ log_file)); (-e "$ log_file"){ touch($ log_file)またはdie( "failed touch $ log_file"); } open(LOG、 ">> $ log_file"); my($秒、$分、$時間、$ mday、$ mon、$年)=現地時間(時間); LOG '['を出力します。 ($年+ 1900)。 「-」。 (($ mon <10)?( '0'。$ mon):$ mon)。 「-」。 (($ mday <10)?( '0'。$ mday):$ mday)。 」。 (($時間<10)?( '0'。$時間):$時間)。 「:」。 (($ min <10)?( '0'。$ min):$ min)。 「:」。 (($秒<10)?( '0'。$秒):$秒)。 ']'。 「$メッセージ\ n」; ログを閉じます。 } 私の$ thr = threads-> create(sub { 場合を除き(ping_state(\ @ check_ips、 'tcp'、$ int_if)){ do_log(「LANリソースへの接続の確認:失敗」); system( "dhclient $ ext_if"); } }); 場合を除き(ping_state(\ @ check_hosts、 'icmp')){ do_log( "WANリソースへの接続を確認:失敗"); opendir(RUN、 '/ var / run'); for(grep {/tun\w+\.pid/} readdir(RUN)){ open(PID、 '/ var / run /'。 "$ _"); ローカル$ / = undef; 私の$ pid = <PID>; 閉じる(PID); チョップ($ pid); kill(9、$ pid); } closedir(RUN); system( "ppp -ddial akado"); } foreach my $ t(threads-> list(threads :: all)){ $ t-> join(); }
チェックされた内部リソースの値を置き換えることを忘れないでください(@check_ips配列の定義を参照)。
/var/log/ifaces.logで問題を追跡できます。
もちろん、Touchモジュールの使用を削除し、操作を部分的に別の方法で説明することもできましたが、この記事を書いている時点では、まさにそれをしたかったのです。
PS:FreeBSD、Perl 5.10で使用されます。
Pearl 5.8は、threads-> list(threads :: all)を使用して誓います。