TT Lab
はじめる
学ぶ 学習パス コース

閉域網のミラーとプライベート CA

閉域網に社内 DNS と時刻サーバを立てる

TT Labで続きを見る

このラボは本物のVM上で動きます

Ubuntu 24.04のVM 1台です。準備ステップが、ネットワークネームスペースclientを作っておきました。同じVMの中ですが、ネットワークとしては別の、「エアギャップ環境の中の別のサーバー」で、VM(10.203.0.1)とvethでつながっています(10.203.0.2)。その中でコマンドを実行するには、ip netns exec client <명령>です(プレースホルダーはコマンドです)。dnsmasq・chrony・digがインストールされています(dnsmasqサービスは、ポート53の衝突で失敗したままです。その診断は、network-basicsコースで扱います)。採点は、外部からVMの8899ポートに入ってくるエージェントが行うので、すでに確立した接続をふさぐと、採点が切れます。

目標

インターネットに届かないネットワークに、社内DNSと時刻サーバーを立てて、別のサーバーにそれを使わせたあと、引き継ぎ用の点検スクリプトで終えます。

なぜ重要なのか

社内ミラーは、名前で呼ぶことで証明書と合い、その名前を解決するDNSが必要です。ところが、エアギャップ環境のDNSが、知らない名前を外部に問い合わせに行くと、毎回タイムアウトを待ちます。社内ゾーンは、権威を持って、すぐに答えるようにする必要があります。時間も同じです。インターネットの時刻サーバーに届かないサーバーの時計は、互いに離れていき、数分ずれるだけで、証明書の有効期間の確認とログの突き合わせが壊れます。エアギャップ環境には、基準の時計が1つ必要です。

所要時間は50分ほどです。セッションが終わるとVMが消えるので、残したいファイルは、終了前に別に保管してください。

ステップ

  1. 再実行しても、ルールが1セットだけ残るスクリプトで、外部への送信をふさいでください(スクリプト: /root/infra/egress.sh)。チェーンAIRGAP-EGRESSを、OUTPUTで1回使います。ループバック・確立済みの接続・社内のアドレス範囲10.203.0.0/24は通します。ふさぐ前とふさいだ後に、curl -s -o /dev/null -w '%{http_code}' https://ubuntu.comを測って、before=・after=として書いてください(記録先: /root/infra/egress-proof.txt)。
  2. 設定ファイル(/etc/dnsmasq.d/airgap.conf)で、dnsmasqが10.203.0.1でだけ待ち受け、上位なしで、airgap.internalゾーンを権威として答えるようにしてください。名前のファイルは(/etc/airgap/hosts)に置き(registry・pypi・ntpの3つの名前 → 10.203.0.1)、addn-hostsで読みます。サービスを起動して、起動時にも立ち上がるようにしてください。
  3. clientが、そのDNSと検索ドメインairgap.internalを使うように、ファイルを書いてください(ファイル: /etc/netns/client/resolv.conf)。clientで、短い名前registryが解決できる必要があります。
  4. 名前のファイル(/etc/airgap/hosts)に、nexus.airgap.internal → 10.203.0.1を追加して、dnsmasqを再起動せずに反映してください。反映の前後の、dnsmasqのメインプロセスのPIDを、pid_before=・pid_after=として書いてください(記録先: /root/infra/reload.txt)。
  5. 設定ファイル(/etc/chrony/conf.d/airgap-server.conf)で、chronyが社内のアドレス範囲に時間を出し、上位がなくても、ストラタム8で基準になるようにしてください。
  6. clientで、時計を変えずに、10.203.0.1に時間を問い合わせて、その出力を保存してください(保存先: /root/infra/ntp-query.txt)。
  7. 引き継ぎ用の点検スクリプトを書いてください(スクリプト: /root/infra/check.sh <네임스페이스>、プレースホルダーはネームスペースです)。そのネームスペースで、registry・pypi・ntpが解決でき、時刻サーバーが答えれば0、そうでなければ0ではない値で終わります。

参考

外部への送信をふさいで、エアギャップ環境にする

スクリプトで外部への送信をふさぎ(スクリプト: /root/infra/egress.sh、チェーンAIRGAP-EGRESS)、ふさぐ前後のhttps://ubuntu.comのステータスコードを、before=・after=として書いてください(記録先: /root/infra/egress-proof.txt)。

新しいチェーンを作って、OUTPUTの先頭からそこへ送れば、空にして埋め直す方式で、何度実行しても同じ形になります。通すもの(ループバック、確立済みの接続、採点エージェント、社内のアドレス範囲)を、先にRETURNで書いて、最後にふさぎます。

上位のない社内DNS

設定ファイル(/etc/dnsmasq.d/airgap.conf)で、dnsmasqが10.203.0.1でだけ待ち受け、上位なしで、airgap.internalを権威として答えるようにして、名前のファイルは(/etc/airgap/hosts)に置いて読ませてください。サービスを起動して、起動時にも立ち上がるようにしてください。

待ち受けるアドレスを1つに絞る2行、上位を切る1行、ゾーンをローカルとして宣言する1行、名前のファイルを読む1行が必要です。ない社内の名前が、すぐに「ない」と答えられるかを、digのstatusで確認してください。

別のサーバーに、社内DNSを使わせる

clientが10.203.0.1と検索ドメインairgap.internalを使うように、ファイルを書いてください(ファイル: /etc/netns/client/resolv.conf)。

ip netns execは、/etc/netns/<名前>/resolv.confがあれば、そのネームスペースの中で、/etc/resolv.confの場所にはめ込んでくれます。nameserverとsearchの2行で済みます。確認は、clientの中で、短い名前でdig +searchです。

再起動なしで名前を追加する

/etc/airgap/hostsにnexus.airgap.internal → 10.203.0.1を追加して、dnsmasqを再起動せずに反映してください。反映の前後のメインプロセスのPIDを、pid_before=・pid_after=として書いてください(記録先: /root/infra/reload.txt)。

dnsmasqは、SIGHUPを受け取ると、キャッシュを空にして、/etc/hostsとaddn-hostsのファイルを読み直します(設定ファイル自体は読み直しません)。systemdのreloadが何を送るかも、確認してみてください。

上位のない社内の時刻サーバー

設定ファイル(/etc/chrony/conf.d/airgap-server.conf)で、chronyが10.203.0.0/24に時間を出し、上位がなくても、ストラタム8で基準になるようにしてください。

chronyは、デフォルトでは、どのクライアントも受け付けません。受け付けるアドレス範囲を許可するディレクティブと、上位なしで自分の時計を基準として出すディレクティブが必要です。Ubuntuのchrony.confは、conf.dを読みます。変更したあと、サービスを再起動して、trackingのStratumを見てください。

別のサーバーから時間を問い合わせる

clientで、時計を変えずに10.203.0.1に時間を問い合わせて、出力を保存してください(保存先: /root/infra/ntp-query.txt)。

chronydには、設定ファイルの代わりに、コマンドラインのディレクティブで一度だけ問い合わせて、時計は変えずに、差だけを出力して終わるモードがあります。ネームスペースの中で実行し、数秒待つように、タイムアウトを指定してください。

引き継ぎ用の点検スクリプト

点検スクリプトを書いてください(スクリプト: /root/infra/check.sh <네임스페이스>、プレースホルダーはネームスペースです)。そのネームスペースで、registry・pypi・ntpが解決でき、時刻サーバーが答えれば0、そうでなければ0ではない値で終わります。

採点は、このスクリプトを、clientと、社内ネットワークにつながっていない空のネームスペースの、2か所で実行します。前者は0、後者は0ではない必要があります。digとchronyd -Qに、短いタイムアウトを指定してください。