はじめまして、ほぼ年中ネックウォーマーを巻いている「K」と申します。
今回はクラウドのSaaSの波の狭間に浮かび上がったことを体験談とともにお伝えします。
なお、文中のIPアドレスやドメイン名は全て仮のものです。
さてさて、タイトルにある通りネットワーク機器のスクリプトで課題解決をしたお話ですが、まずは背景から説明します。
その時に構築したシステムはWebアプリケーションで、基盤はAWSを利用していました。
ユーザはインターネットVPNを介して接続します。
また、Webアプリケーションはアプリケーションロードバランサ(ALB)+ECS Fargateであり、サーバレス構成としています。
通信は全てプライベートIPアドレスで行います。
概要はコチラ。
システムで使うIPアドレスは仮で10.0.0.0/24としておきます。
まぁよくある構成なのかなと思います。
しかし、今回の構成で課題に挙がったのは「ユーザはDNSによるALBの名前解決が出来ない」という点でした。
ユーザが所属しているのはシステムとは異なるアドレス帯だったので、名前解決をしてもユーザネットワーク内の「10.0.0.0/24」に行ってしまうわけですね。
そもそもこちらのユーザに対してシステムを公開するには、内部ドメインとIPアドレスの払い出しをしてもらい、ユーザネットワーク内のルータ(構築範囲外)で宛先NAT変換してシステム用ネットワークに接続する、というルールがありました。
絵にすると下記の通り
①「hogehoge.com」の名前解決
②「192.168.1.1」を返答
③宛先「192.168.1.1」にアクセス
④ユーザネットワーク内のルータで宛先IPアドレスを「10.0.0.10」に変換
⑤宛先「10.0.0.10」でALBにアクセス
ここで問題となってくるのはALBのIPアドレスです。
利用されたことがある方は判ると思いますが、ALBはIPアドレスが変わるのでDNS名で接続するのがセオリーです。
つまり「ユーザがアクセスしてくるのはIPアドレス【10.0.0.10】固定。DNS名での接続は出来ない」
と
「ALBのIPアドレスは変わる」で仕様が相反していたわけですね
長くなりましたが、課題の背景は以上です。
プライベートアドレス空間でAWS ALBを使う際は比較的あるあるな課題でもあると思います。
それでさて、どうしよう、となった時に案はいくつかありました。
案1:ALBの前に固定IPのNLBを配置する。Lambdaで定期的にALBのIPアドレスを確認して変更があればNLBのターゲットIP(ALBのIP)の設定を変更する。
※WAFの利用があるのでNLB1本化は不可
案2:データセンタ設置のルータに宛先NAT設定を入れる(※このルータは構築範囲内なので自由に触れる)かつ、Lambdaで定期的にALBのIPアドレスを確認して変更があればルータのNAT設定の「10.0.0.10→[ALBのIPアドレス]」の部分を書き換える
案2:案2の方式で、動的IPの確認とNAT設定の書き換えを運用端末からタスクスケジューラ+テラタームマクロで定期的にやる。
案3:案1、案2のLambdaの部分をECS Fargateのサービスでやる(デーモン化はナシでスケジュール実行)。
ほうほうLambdaですか・・・そうですか、そろそろいい加減Pyhton覚えようかなぁぁ、なんて思っていたところに急浮上してきたのが、データセンタ設置のYAMAHA RTXルータのluaスクリプトでの解決案でした。
このluaスクリプト、恥ずかしながらこれまで存在すら知りませんでした。
方式としては案2ですね。そして、動的IPへの追随をLambdaではなくルータ自身でやろう、という方法です。
Luaスクリプトの詳細は割愛しますが、CLIのコマンドが打てて、変数が使えるだけで十分でした。実際、実装したスクリプトで主要なコマンドはたった4行(例外処理などは記載割愛)
///////////////////////////
—名前解決
flag,outputs = rt.command(“nslookup [ALBのDNS名]“)
—名前解決結果の整形
address = string.match(outputs,/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$/)
—コマンド整形
cmd = “nat descriptor static 1 1 10.0.0.10=” .. address
—コマンド実行
rt.command(cmd)
///////////////////////////
これをファイルにしてルータにtftpなりscpで転送。
あとは、毎分実施するためにconfigにcron的なコマンドを投入するだけでした。
///////////////////////////
schedule at 1 */* *:* * lua /lua/NameCheck.lua
///////////////////////////
いや~簡単!
Lambdaでも実際のコマンド部分の分量は変わらないと思いますが、認証回りが不要でしたし実装がお手軽でした。
このスクリプト、なんだか他にも色々使い道はありそうだし、すごく便利そうなのに、、、逆になぜ今まで存在すら知らなかったんだろう?と逆に不思議に思いました。
調べたらCiscoにも似たようなスクリプト(tcl)はあるけど、CCNA~CCNPでは触れられもしていない。。。なぜスクリプト君はこんなに冷遇されているのか(笑)
僕の知り合いのネットワーク技術者に聞いてみましたが、実装経験はなかったとのこと。
ネットワーク屋さんはスクリプトアレルギーなのかしら…と邪推してみたりしました。
これは推測ですが、これまではこういった痒い所を掻く時はサーバからスクリプトを叩いてたんじゃないかなぁ、と。テラタームマクロなんか割と使いますしね。
だからこれまでほとんど日の目を見なかったんじゃないかなと。
ところが今回はサーバレスだったので実行環境がないわけですね。
風が吹けば桶屋が儲かるようにサーバレス構成にするとNW機器のスクリプトが脚光を浴びるという意外な現象が起きた、というお話でした。
以上となります。
また僕のPythonデビューは機会を逃してしまいましたが(笑)
こういう課題解決手段の選択肢が増える知識は嬉しいなと思い、ブログで共有させていただいた次第です!
最後までお読みいただきありがとうございます!