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

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

Maven 社内ミラーを HTTPS で、JVM に信頼させる

TT Labで続きを見る

目標

接続された側で、依存関係とプラグインを集めて、社内Mavenリポジトリを、HTTPSで立て、settings.xmlのmirrorで、すべてのリクエストを回します。JVMにプライベートCAを信頼させて、エアギャップ環境側の新しいローカルリポジトリでビルドし、持ち込み一覧から抜けたプラグインを、追加で持ち込む手続きまで終えます。

なぜ重要なのか

Javaビルドのエアギャップ環境での失敗は、3重です。リポジトリのアドレス、証明書、そして、持ち込み一覧の穴。アドレスはmirror 1行が、証明書はJVMのトラストストアが、穴は、「実際に実行するgoalで一覧を作る」という習慣が防ぎます。このPodは、インターネット(80/443)に届くので、ダウンロード側の役割を果たし、エアギャップ環境側は、mirrorOf *が、すべてのリクエストを社内リポジトリに回して、外部を使えなくします。採点は、ローカルリポジトリの_remote.repositoriesと、社内サーバーのアクセス記録で、どこから取得したかを確認します。

ステップ

  1. /root/mvn/appに、pom.xml(gson 2.11.0、プラグインのバージョンを固定)とsrc/main/java/demo/App.javaを作成して、新しいローカルリポジトリ/root/mvn/outside-repoでpackageを実行してください。
  2. /root/mvn/outside-repoを/srv/mavenに移して、_remote.repositories・*.lastUpdated・resolver-status.propertiesは取り除いてください。
  3. /root/pkiに、CNがAirgap Internal Root CAのルート(ca.crt・ca.key)と、maven.airgap.internalのサーバー証明書(maven.crt・maven.key、SAN)を作成して、/etc/hostsに名前を追加してください。
  4. /root/mvn/nginx.confでnginxを起動して、https://maven.airgap.internal:8443/が/srv/mavenを公開するようにしてください。アクセス記録は/root/mvn/access.logです。
  5. ~/.m2/settings.xmlに、idがairgap-internal、mirrorOfが*のmirrorを書いてください。ダウンロード側の役割を果たすときに使う、空の設定/root/mvn/outside-settings.xmlも作成してください。
  6. エアギャップ環境側の新しいローカルリポジトリ/root/mvn/inside-repoでpackageを実行して、失敗する出力を/root/mvn/pkix.logに保存してください。
  7. JVMがプライベートのルートを信頼するようにしてください(検証をオフにするオプションは使いません)。
  8. 同じコマンドで、エアギャップ環境側のビルドを通してください。
  9. mvn clean packageが失敗する原因となった、アーティファクトの座標を、/root/mvn/missing.txtに書いて(groupId:artifactId:version)、接続された側で取得して社内リポジトリに追加したあと、エアギャップ環境側でclean packageを通してください。

参考

ダウンロード側: 新しいローカルリポジトリでビルドして集める

/root/mvn/appにpom.xmlとApp.javaを作成して、新しいローカルリポジトリ/root/mvn/outside-repoでpackageを実行してください。

ローカルリポジトリの場所は、システムプロパティで変えられます。新しいディレクトリを指定すれば、このビルドが実際に取得したものだけが積まれます。プラグインのバージョンをPOMで固定しないと、このMavenのデフォルトのcompilerは、JDK 21の設定を知りません。

追跡ファイルを取り除いて、社内リポジトリにする

/root/mvn/outside-repoを/srv/mavenに移して、追跡ファイル(_remote.repositories・*.lastUpdated・resolver-status.properties)は取り除いてください。

社内リポジトリは、ファイルの配置のままで十分です。追跡ファイルは、取得した側のローカルリポジトリが、「どこから取得したか」を書いた記録なので、リポジトリに残してはいけません。findで名前を選んで、削除できます。

プライベートCAで、ミラーの証明書を発行する

/root/pkiに、ルート(ca.crt・ca.key、CN Airgap Internal Root CA)と、maven.airgap.internalの証明書(maven.crt・maven.key、SAN)を作成して、/etc/hostsに名前を追加してください。

ルートは、自己署名でCA:TRUE、サーバー証明書は、ルートで署名しながら、拡張ファイルでSANを指定します。プライベートCAのモジュールで行ったのと、同じ手順です。

nginxでHTTPSの社内リポジトリを起動する

/root/mvn/nginx.confでnginxを起動して、https://maven.airgap.internal:8443/が/srv/mavenを公開するようにして、アクセス記録を/root/mvn/access.logに残してください。

Mavenリポジトリは静的ファイルなので、rootが1つあれば十分です。このPodでは、1024未満のポートを開けず、pidやログのパスは、書き込める場所に移す必要があります。-tで先に検査してください。

mirrorOf *で、すべてのリクエストを回す

~/.m2/settings.xmlに、idがairgap-internal、mirrorOfが*、urlがhttps://maven.airgap.internal:8443/のmirrorを書いて、空の設定/root/mvn/outside-settings.xmlを作成してください。

ユーザー設定ファイルは、ホームディレクトリの.m2の下にあります。mirrorOfにアスタリスクを指定すれば、POMが宣言したリポジトリまで、すべて横取りします。外部の役割に使う設定は、mirrorがない、最小限のsettings要素で済みます。

JVMが知らないCA。PKIXエラーを記録する

新しいローカルリポジトリ/root/mvn/inside-repoでpackageを実行して、失敗する出力を/root/mvn/pkix.logに保存してください。

curlにルートを教えたことと、JVMがルートを信頼することは、別のことです。失敗する出力の全体を保存して、エラーの行から、証明書のパスに関する言葉を探してみてください。

JVMのトラストストアに、ルートを入れる

JVMがプライベートのルートを信頼するようにしてください(検証をオフにするオプションは使いません)。

JDKには、トラストストアを扱うツールがあり、デフォルトのストア(cacerts)を直接指すオプションがあります。ドキュメントに書かれた、初期パスワードがあります。Ubuntuなら、OSのストアの更新が、JVMのストアまで更新する道もあります。

エアギャップ環境側のビルドを通す

ステップ6と同じコマンド(/root/mvn/inside-repo、package)で、ビルドを通してください。

JVMがルートを信頼するようになったあとなら、同じコマンドが通るはずです。通ったあと、エアギャップ環境側のローカルリポジトリの追跡ファイルが、どのリポジトリidを書いたかを見てください。

cleanの一言が呼んだ追加の持ち込み

mvn clean packageの失敗の原因となった座標を、/root/mvn/missing.txtにgroupId:artifactId:versionの形式で書いて、接続された側で取得して社内リポジトリに追加したあと、エアギャップ環境側でclean packageを通してください。

エラーの行が、どのプラグインが見つからなかったかを教えてくれます。外部の役割は、空の設定ファイルと、外部用のローカルリポジトリで、同じgoalを実行すれば、そのプラグインが集まります。もう一度移したあとも失敗するなら、エラー文を最後まで読んでみてください。以前の失敗が記録されています。