Nexus Repository

Nexus Repository

はじめに

Nexus Repositoryとは何か。一言で言えば、社内共用部品倉庫です。開発で使うライブラリ、パッケージ、Dockerイメージなどを一か所に集め、必要なときに取り出して使えるよう管理するサーバーです。

現在は、開発者がそれぞれインターネットから必要なものをダウンロードしています。同じライブラリを20人が20回ダウンロードし、外部サイトが一時的に停止すると、全員のビルドも同時に止まってしまいます。Nexusはその間に立ち、一度だけダウンロードして保管し、全員に配布する役割を果たします。

Nexusが行うことは、大きく3つあります。

  • 受け取って保管する — 外部からダウンロードしたライブラリを社内にキャッシュしておきます。

  • 私たちのものを入れておく — 私たちが作成した共通モジュールやビルド成果物を保管します。

  • 一つの窓口にまとめる — 複数のリポジトリを一つのアドレスにまとめて表示します。

Repositoryの特徴

Repositoryには、代表的に3種類があります。

  1. Proxy Repository - 外部リポジトリを代わりに参照し、結果をキャッシュできます。

  2. Hosted Repository – 私たちが作成した成果物を直接Repositoryにアップロードできます。

  3. Group Repository – 複数のリポジトリを一つのアドレスにまとめて利用するときに使います。

管理者がProxy、Hosted RepositoryをGroup Repositoryにまとめてくれれば、ユーザーはRepositoryを利用する際にGroup Repositoryを使うことで、一つのRepositoryだけを利用すれば済みます。

Repository構成例

リポジトリ名

形式

タイプ

用途

maven-public

maven2

group

バックエンド開発者が参照するアドレス(以下3つをまとめたもの)

maven-releases

maven2

hosted

私たちが作成した正式リリースJAR

maven-snapshots

maven2

hosted

開発中のJAR

maven-mirror

maven2

hosted

外部から持ち込んだライブラリ

Nexusのパッケージ対応形式

Java(Maven・Gradle)、フロントエンド(npm)、Python、Dockerイメージ、Linuxパッケージまで、20種類を超える形式を1台のサーバーですべて扱える点が最大のメリットです。言語ごとにリポジトリを別々に構築する必要がありません。以下は対応しているパッケージの種類で、そのほかTerraform、Yumなどがあります。

image1.pngimage2.png

image3.pngimage4.png

内部ネットワークでの活用

ネットワーク分離環境では、大きな制約が一つ生じます。内部ネットワークのサーバーはインターネットに接続できません。そのため、「外から代わりに買ってきてくれる」Proxyリポジトリを使うことができず、代わりに外部からあらかじめ取得しておいたものを内部に持ち込む手順が必要になります。

最も広く使われている構成は、Nexusを2台設置する方式です。外部ネットワーク(またはDMZ)に1台を置いて必要なものをあらかじめ取得しておき、内部ネットワークにもう1台を置いて開発者に配布します。2台の間では、ネットワーク連携システムを使って定期的に移送します。

  [인터넷] → [외부망 Nexus · Proxy] ← 필요한 것을 미리 받아 캐싱
                    ↓ 추출 → 검증(해시·백신·취약점) → 승인
      ═══ 망분리 경계 · 망연계 시스템으로 전송 ═══
                    ↓
  [내부망 Nexus · Hosted] → [개발자 PC / CI 서버]

内部ネットワークへのNexus導入のメリット

領域

導入前

導入後

ライブラリの追加

持ち込み申請後、数日待機

すでに持ち込まれたものはすぐに使用

依存関係

不足しているものを一つずつ再申請

1回のビルドで一括取得

新規セットアップ

環境を整えるのに数日

ビルドコマンド一回で完了

持ち込み経路と監査

USB・メールなどバラバラで、証明が難しい

窓口は一つ、記録がそのまま証跡に

セキュリティの観点

内部ネットワークでNexusを使用する場合でも、外部のNexusサーバーには公開されることになるため、各アカウントおよびレポジトリのRoleとPrivilegeの設定は重要です。

Privilegeによって、ユーザーのレポジトリ使用権限を分けられるようになります。

大まかには、browse、read、add、edit、deleteの機能が代表的です。したがって、開発者に単純なダウンロード権限だけが必要な場合は、readとbrowse程度だけを付与し、アップロードが必要な場合にのみadd権限を追加する、といった構成にできます。

管理者アカウントはすべての権限を持っているため、通常のArtifactのアップロードやダウンロード作業に使用することは推奨されません。

Sonatypeも、adminアカウントは初期設定や管理作業など、すべての権限が必要な場合に限って使用し、普段は権限を制限した別のアカウントを使用することを推奨しています。

実践例(Java + Gradle)

(1) 認証情報 — gradle.properties

パスワードをソースに入れないよう、ホームディレクトリの設定ファイルや環境変数を使用します。CIでは個人アカウントの代わりに、NexusのUser Tokenを発行して使用することを推奨します。

# ~/.gradle/gradle.properties
nexusUrl=https://nexus.example.local
nexusUser=build-bot
nexusToken=xxxxxxxx-xxxx-xxxx

(2) ライブラリの取得先 — settings.gradle

Gradleはプラグインとライブラリをそれぞれ異なる経路から取得します。両方を指定する必要があります。閉鎖ネットワークでこれを見落とすと、「ライブラリは取得できるのに、プラグインで止まる」という現象が起こります。

pluginManagement {
    repositories {
        maven {
            url = uri("${nexusUrl}/repository/gradle-plugins/")
            credentials { username = nexusUser; password = nexusToken }
        }
    }
}

dependencyResolutionManagement {
    // 하위 모듈이 mavenCentral()을 임의로 선언하지 못하게 막습니다
    repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
    repositories {
        maven {
            url = uri("${nexusUrl}/repository/maven-public/")
            credentials { username = nexusUser; password = nexusToken }
        }
    }
}

(3) ビルド成果物のアップロード — build.gradle

バージョンにSNAPSHOTが付いていれば開発用リポジトリに、そうでなければリリースリポジトリに送ります。リリースリポジトリはNexusの設定で上書きを禁止しておくのがよいでしょう。同じバージョンなのに内容が異なる状況を、構造的に防止できます。

plugins { id 'java'; id 'maven-publish' }

publishing {
    publications { maven(MavenPublication) { from components.java } }
    repositories {
        maven {
            url = version.toString().endsWith('SNAPSHOT')
                ? "${nexusUrl}/repository/maven-snapshots/"
                : "${nexusUrl}/repository/maven-releases/"
            credentials { username = nexusUser; password = nexusToken }
        }
    }
}

よくある問題

  1. ファイルのビルドを実行すると、ファイルはアップロードされているのにGradleが見つけられない場合が時々ありますが、これはメタデータが更新されていないためです。NexusのRepair - Rebuild Maven repository metadataを実行するか、レポジトリでInvalidate cacheをクリックしてキャッシュを初期化します。

  2. Nexusサーバーの容量を管理する必要があります。ProxyおよびHostedレポジトリには、継続的に取り込まれたデータが蓄積され続けます。管理者はCleanup Policyの設定によって、古いスナップショットデータを整理するよう管理する必要があります。Compact blob storeを定期的に実行します。

まとめ

Nexusは華やかなツールではありません。しかし、一度構築しておけば、開発者がライブラリを待つ時間がなくなり、セキュリティ担当者は何が取り込まれたのかを一か所で確認できるようになります。セキュリティと開発速度はしばしば衝突すると言われますが、少なくともこの領域では、よく整備された一つの窓口によって両方が向上します。

参考資料

・Sonatype Nexus Repository公式ドキュメント — Repository Types / Community Edition Onboarding (help.sonatype.com)

Bang

Site footer