FreeBSDサーバーのネットワーク上の静的ルートを使用した作業の自動化

それがすべて始まった方法



私が働いているプロバイダーでは、クライアントネットワークが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.shchecker.sh



All Articles