人生を簡素化するスクリプトの例はhabrakatの下にあります:)
パート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)を使用して誓います。