はじめに
GitLab を AWS EC2 上に構築する際、多くの例ではインターネット経由でのアクセスを前提とした構成が紹介されています。しかし、企業のセキュリティポリシーや特定のシステム要件においては「パブリックアクセスを完全に遮断した GitLab 環境」が求められるケースもあります。
本記事では、パブリックアクセスを一切許可せず、AWS SSM のポートフォワーディング機能のみでアクセス可能な GitLab 環境を EC2上に構築する手順を紹介します。
エンタープライズ利用を想定して、EC2はRHEL9で構築します。
構成概要
- EC2:RHEL 9 系、パブリック IP 無し
- VPC:プライベートサブネットのみ
- アクセス方法:AWS SSM セッションマネージャー + ポートフォワーディング
- GitLab:gitlab-ce-16.10.3-ce
1. EC2 環境と前提条件
- EC2 に SSM Agent がインストール済みであること
- インスタンスに適切な IAM ロール(
AmazonSSMManagedInstanceCore
)が付与されていること - SSM 用のエンドポイントが構成されている(VPC エンドポイントまたは NAT 越し)
- マシンのメモリは8GB以上が望ましい(筆者の場合はt3.largeを使用・小さい場合はGitLabの初期構築途中にハングアップする可能性があります)
セキュリティグループでは、インバウンドルールをゼロに設定しても動作可能です。
VPCエンドポイントを経由し、閉域でSSMと疎通するには下記のVPCエンドポイントを作成しておく必要があります。STSはEC2がクレデンシャルを取得するために必要です。
com.amazonaws.${AWS::Region}.ssm
com.amazonaws.${AWS::Region}.ssmmessages
com.amazonaws.${AWS::Region}.ec2
com.amazonaws.${AWS::Region}.ec2messages
com.amazonaws.${AWS::Region}.sts
2. GitLab のインストール
sudo dnf update
sudo dnf install -y curl openssh-server ca-certificates tzdata perl
curl -LO https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/9/gitlab-ce-16.10.3-ce.0.el9.x86_64.rpm/download.rpm
sudo dnf install -y ./download.rpm
上記はcurlを使って手動でパッケージをダウンロードしています。構成スクリプトを利用する方法もありますが、OSバージョンによっては起動に失敗します。
インストールが完了すると、下記のような画面になります。
この時点ではまだ外部からのアクセス手段はありません。
3. GitLabの初期構成
ポートフォワードして接続するため、external_urlをlocalhostに変更します。
今回は下記のようにポートフォワードしたいため、次のような設定を行います。
ローカル端末 8080ポート → GitLab(nginx) 80ポート
# /etc/gitlab/gitlab.rb
external_url 'http://localhost:8080'
nginx['listen_port'] = 80
設定を行ったらGitLabの初期構成を実施しましょう。
sudo gitlab-ctl reconfigure
初期構成後にGitLabのrootパスワードが生成されるので、控えておきましょう。(パスワードファイルは24時間後に削除されます)
sudo cat /etc/gitlab/initial_root_password
4. ポートフォワーディングの構成(クライアント端末側)
ここからはクライアント端末側の設定です。
まずはAWS CLIとSSMセッションマネージャのプラグインをインストールしましょう。AWS Systems Manager Session Manager Plugin の公式ドキュメントは こちら を参照してください。(Windows端末向け)
SSMセッションマネージャへのアクセスは複数通りありますが、下記のようにセッションキーを取得して、AWS CLIから呼び出せるようにしておく方式が安全だと思います。
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/sts:AssumeRoleを許可したロール --role-session-name AWSCLI
取得したセッションキーでAWS CLIのcredentialsを構成しておきましょう。
aws_access_key_id = (省略)
aws_secret_access_key = (省略)
aws_session_token =(省略)
SSMセッションマネージャでポートフォワーディングを開始するには、Windows 環境から PowerShell 経由で以下のように実行します。
aws ssm start-session `
--target i-xxxxxxxxxxxxxxxxx(EC2インスタンス) `
--document-name AWS-StartPortForwardingSession `
--parameters '{\"portNumber\":[\"80\"],\"localPortNumber\":[\"8080\"]}' `
--region ap-northeast-1
⚠ 注意:10080 や 666 など一部ポートはブラウザでブロックされるため、8080 などのセーフなポート番号を選びましょう。
ローカルブラウザで http://localhost:8080
にアクセスすると GitLab の画面が表示されます。
5. トラブルシューティング
下記のようにGitLabが起動待ちの画面が続く場合は、以下2点を確認しましょう。
①GitLabのステータス
②ステータスが正常でないプロセスのログ
①GitLabのステータス
下記の場合は一見正常に見えますが、pumaプロセスの経過時間が37sと短く、再起動を繰り返しているものと推定されます。
sudo gitlab-ctl status
run: alertmanager: (pid 54154) 6549s; run: log: (pid 53938) 6608s
run: gitaly: (pid 54112) 6553s; run: log: (pid 53247) 6740s
run: gitlab-exporter: (pid 54129) 6552s; run: log: (pid 53825) 6626s
run: gitlab-kas: (pid 53504) 6726s; run: log: (pid 53521) 6723s
run: gitlab-workhorse: (pid 54096) 6554s; run: log: (pid 53698) 6644s
run: logrotate: (pid 57057) 3155s; run: log: (pid 53144) 6754s
run: nginx: (pid 54104) 6553s; run: log: (pid 53729) 6638s
run: node-exporter: (pid 54121) 6553s; run: log: (pid 53791) 6632s
run: postgres-exporter: (pid 54162) 6549s; run: log: (pid 53975) 6600s
run: postgresql: (pid 53313) 6732s; run: log: (pid 53375) 6729s
run: prometheus: (pid 54139) 6551s; run: log: (pid 53898) 6614s
run: puma: (pid 59705) 37s; run: log: (pid 53615) 6656s
run: redis: (pid 53182) 6749s; run: log: (pid 53210) 6746s
run: redis-exporter: (pid 54131) 6551s; run: log: (pid 53860) 6620s
run: sidekiq: (pid 53631) 6653s; run: log: (pid 53641) 6649s
②ステータスが正常でないプロセスのログ
上記pumaプロセスが再起動を繰り返していた時に、pumaのログに出力されていたエラーは下記の通りです。
# /var/log/gitlab/puma/current
2025-xx-xx_xx:xx:xx.xxxxx /opt/gitlab/embedded/lib/ruby/gems/3.1.0/gems/puma-6.4.0/lib/puma/binder.rb:334:in `initialize': Address already in use - bind(2) for "127.0.0.1"port 8080 (Errno::EADDRINUSE)
ポート8080がサーバ内で既に使用中になっていたため、アプリの起動に失敗しています。「3. GitLabの初期構成」でnginxのポートを明示的に指定していない場合、nginxがexternal_urlに記載されたポート8080で立ち上がってくるため、上記のような衝突事象が発生していました。
6. まとめ
- GitLab は
external_url
に厳密に従ってリダイレクトされる - SSM セッションマネージャーとポートフォワーディングにより、完全に非公開の GitLab が構築可能
SSM によるセキュアアクセスと合わせて、閉域構成での GitLab 利用を検討している方の参考になれば幸いです。