それがすべて始まった方法
私が働いているプロバイダーでは、クライアントネットワークがFreeBSDサーバー上で終端されており、これらのサーバーを接続するスイッチングフィールドに静的ルーティングが設定されています。 したがって、新しいネットワークを追加する場合、そのルートをすべてのサーバーに個別に登録する必要があります。 これに人的要因を追加すると、ルートを追加または変更するときに一部のサーバーが忘れられてスキップされることが判明する場合があります。 この点で、このプロセスを何らかの形で自動化することが論理的になります。
実装
FreeBSDを実行している多数のサーバーがあり、新しいルートを追加する場合(たとえば、これらのサーバーの1つで新しいクライアントネットワークが終了した場合)、これらすべてのサーバーに登録する必要があります。
最初に、各行が1つのサーバーのアドレスであるテキストファイルを作成します。これらの各サーバーについて、キーごとに承認を構成します(これを行う方法については、たとえば
ここで説明し
ます )。
サーバーリストファイルの例:
192.168.0.1
192.168.1.1
mainserver.yourdomain.ru
さらなる作業は、2つのシェルスクリプトの束によって行われます。
1)
checkroute.sh [-c]宛先ゲートウェイ 、ここで
-c-チェックのみのオプション(変更を加えずにコンプライアンスのみをチェック)、
宛先 -IPアドレスまたは宛先ネットワーク、
ゲートウェイ -宛先アドレスのゲートウェイ。
このスクリプトは、入力されたスクリプトパラメーターの有効性をチェックし、sshを介してリストから各サーバーに順番に接続し、2番目のスクリプトをコピーして実行します。
2)
checker.sh宛先ゲートウェイifcheck次に、現在のルーティングテーブルと構成ファイルをチェックし、チェックの結果を報告し、-cオプションなしで最初のスクリプトが実行された場合、宛先/ゲートウェイのペアに従って対応するエントリをもたらします。
checkroute.sh
最初に、スクリプトが実行されたオプションを確認します。 現時点では、-cオプションのみが処理されますが、この機能は類推により簡単に拡張できます。
ifcheck = "no"
getopts "c" optname
「$ optname」の場合
"c")ifcheck = "check" ;;
*)echo "使用方法:$ 0 [オプション]宛先ゲートウェイ
\ tc \ tcheckルート、修正しないでください
」
出る
;;
エサック
やった
シフト$(($ OPTIND -1))
次のステップは、スクリプトに渡されたDESTINATIONおよびGATEWAYパラメーターの有効性を確認することです。 この目的のために、IPアドレスまたはネットワークがDESTINATIONとして機能し、IPアドレスのみがゲートウェイとして機能することが必要です。
validIPregexp = "(25 [0-5] | 2 [0-4] [0-9] | [01]?[0-9] [0-9]?)\。(25 [0-5] | 2 [0-4] [0-9] | [01]?[0-9] [0-9]?)\。(25 [0-5] | 2 [0-4] [0-9] | [ 01]?[0-9] [0-9]?)\。(25 [0-5] | 2 [0-4] [0-9] | [01]?[0-9] [0-9 ]?) "
checkip(){
CHECK = $(echo $ 1 | grep -E "^ $ validIPregexp $ 2")
[! 「$?」 -eq 0]
それから
echo "誤った$ 3:$ 1、もう一度やり直してください。"
出る
fi
}
checkip $ 1 "(/([0-2]?[0-9] | 3 [0-2]))?$" "宛先IPアドレスまたはネットワーク"
checkip $ 2 "$" "ゲートウェイ"
次に、$ serverlistファイルを1行ずつ読み取り、リストからサーバーごとに、sshを介して接続を初期化し、checker.shスクリプトをコピーして実行します。 $ dir変数には、$ serverlistおよびchecker.shファイルがあるディレクトリへのパスが格納されます
serverlist = 'servers.lst'
dir = '/ usr / local / etc / your_dir'
cat "$ {dir} / $ serverlist" | サーバーを読み取りながら
する
echo "$ server:"
cat "$ {dir} / $ checker.sh | ssh -q $ server" rm -f /var/tmp/checker.sh; cat->> /var/tmp/checker.sh; sh /var/tmp/checker.sh $ 1 $ 2 $ ifcheck "
やった
checker.sh
次に、サーバーの1つで実行されたchecker.shスクリプトの動作を見てみましょう。
script.shスクリプトが-cオプションなしで実行された場合に変更を適用する関数
ifcheck = $ 3
commit(){
if [$ ifcheck!= "check"]
それから
eval "$ 1" 2> / dev / null
[! $? -eq 0]
それから
echo "次のコマンドを処理できませんでした:
1ドル
それ以外の場合はエコー「$ 2」
fi
else echo "修正するには、\なしでこのスクリプトを実行します"-c \ "次のコマンドを手動で処理するか、手動で処理します。
1ドル
」
fi
}
現在のルーティングテーブルを解析し(netstat -rnW出力)、結果を$ CurrentGWに書き込みます。
可能なオプション:
1)宛先アドレスはローカルインターフェイスで消去されます($ CurrentGW = "LOCAL")
2)宛先アドレスはどこか他の場所で消去されてルーティングテーブルに存在し、$ CurrentGWにはこのアドレスの現在のゲートウェイが割り当てられます
3)宛先アドレスは他の場所で消去され、ルーティングテーブルにはありません。 この場合、$ CurrentGWは空のままになります。
CurrentGW = `netstat -rnW | awk -v gw = "$ 2" -v src = "$ 1" '{if($ 1〜src){if($ 2〜/' $ validIPregexp '/){if($ 2!〜gw){print $ 2} else {print "OK"}} else {print "LOCAL"}}}} ''
if [-z $ CurrentGW]
それから
echo「1ドルのルートは存在しません。」
commit "sudo route add $ 1 $ 2" "Adding route。"
他に
ケース$ CurrentGW
OK)echo "現在の$ 1へのルートは$ 2:OK" ;;
LOCAL)echo "ローカルインターフェイス上にあります" ;;
*)echo "$ 1のルートは存在するが、宛先が間違っている:$ 2ではなく$ CurrentGW"; commit "sudo route change $ 1 $ 2" "それを変更します。" ;;
エサック
fi
次に、構成ファイルを解析します。これは、変数$ filenameにあるフルパスです。 これを行うには、一時ファイルへのルートの追加を記述するすべての行から選択し、宛先アドレスのエントリの存在を確認します。 上記のnetstat -rnW出力の解析と同様に実行されます。
filename = '/ usr / local / etc / rc.d / rc.script.for.adding.routes.sh'
cat "$ filename" | grep -v '^#' | sed '/ ^ $ / d' | sed 's / [\ t] + / / g' | grep -E 'route。+ add'> /var/tmp/routes_temp.lst
FileGW = `cat /var/tmp/routes_temp.lst | grep $ 1 | awk -v gw = "$ 2" '{if($ NF〜gw){print "YES"} else {print $ NF}}' '
if [$ CurrentGW = "LOCAL"]
その後[ -z $ filegw]
それから
echo "ローカルインターフェイス上にありますが、$ 1のルートが$ filenameで見つかりました。"
commit "sudo sed -Ei '' '\:route [^ \ n] + add [^ \ n] + $ 1:' $ filename" "そこから削除します。"
fi
他に
if [-z $ FileGW]
それから
echo "$ファイル名をチェック:一致なし。"
t1 = `tail -1 /var/tmp/routes_temp.lst | awk '{print $(NF-1)}' '
t2 = `tail -1 /var/tmp/routes_temp.lst | awk '{print $ NF}' '
IFS = ''
regex = "\\:ルート[^ \\ n] +追加[^ \\ n] + $ t1 [\\ t] + $ t2:a \\
/ sbin / route -nq add $ 1 $ 2
」
commit "sudo sed -Ei '' '$ regex2' $ filename" "ファイルの最後にルートを追加する"
他に
if [$ FileGW!= "YES"]
それから
echo "$ 1へのルートのレコードが見つかりましたが、ゲートウェイが間違っています:$ FileGW。"
regex = "s | $ 1 [\ t] + $ FileGW | $ 1 $ 2 | g"
commit "sudo sed -Ei '' '$ regex2' $ filename" "ゲートウェイを$ 2に変更する"
else echo "$ filenameで正しいルートが見つかりました:OK"
fi
fi
fi
最後のコードからいくつかのポイントを明確にしたいと思います。 複数行の変数$ regexを作成するには、IFSシステム変数をオーバーライドする必要がありました。これは、sed構文によって決定されます。 ファイルに行を追加するこの方法が選択されたのは、私の場合のように、いずれかの関数内で$ filenameにルートを追加できるためです。 これがあなたにとって重要でない場合は、フォームのデザインで行うことができます
commit "sudo echo '/ sbin / route -nq add $ 1 $ 2' >> $ filename"
おわりに
上記のスクリプトは他の* nixシステムに適応できますが、唯一の違いはsedキー(Debianの場合、-Ei ""の代わりに-riなど)とrouteコマンドの構文(man routeを参照)だけです。 上記のスクリプトの機能は、類推によって簡単に拡張できます。
スクリプトには多くのチェック(「ばかに対する保護」)がありますが、正しい宛先/ゲートウェイペアの責任は、スクリプトを実行する管理者にあります。 警戒してください!
両方のスクリプトの全文が添付されています:
checkroute.sh 、
checker.sh