Cloudflare Access を使い、セルフホストの GitLab インスタンスに Zero Trust ルールを追加できます。Cloudflare Tunnel と組み合わせると、ユーザーは HTTP と SSH で接続し、チームの ID プロバイダーで認証できます。
この手順で行うこと:
- GitLab インスタンスをデプロイする
- そのインスタンスへのすべてのインバウンド接続を遮断し、Cloudflare Tunnel で Cloudflare へのアウトバウンド接続を設定する
- Cloudflare Access でポリシーを作成し、GitLab に到達できるユーザーを制御する
- Cloudflare 経由で HTTP と SSH で接続する
所要時間:
1 時間
このセクションでは、DigitalOcean に GitLab をデプロイします。すでに GitLab をデプロイ済みなら、このセクションはスキップできます。
RAM 16 GB、CPU 6 基の Droplet を作成します。GitLab のリソース推奨 ↗ に基づくと、500 ユーザー程度を支えられます。
GitLab は(当面)インターネットに公開される外部 IP を提供します。初期設定では、この外部 IP を使ってデプロイしたサーバーへ接続する必要があります。DigitalOcean アカウントに SSH キーを追加 ↗ すると、その IP への接続を保護できます。
この例では、macOS マシンで Droplet を設定します。DigitalOcean がマシンに割り当てた IP アドレスをコピーします。
ターミナルを開き、次のコマンドを実行します。IP アドレスは DigitalOcean が割り当てた値に置き換えます。
ssh root@134.209.124.123次に GitLab をインストールします。この例では Ubuntu パッケージ ↗ と GitLab ドキュメントの手順を使い、下記で示す例外だけを変えます。
次のコマンドから始めます。
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash上のコマンドは、このマシンへ GitLab ソフトウェアをダウンロードします。次にインストールします。ここが、このチュートリアルが GitLab ドキュメントの手順と初めて異なる点です。GitLab 側の次の手順では外部ホスト名を設定します。ここではソフトウェアのインストールだけを行います。
sudo apt-get install gitlab-ee1 分ほどで GitLab がインストールされます。
ただし、アプリケーションはまだ動いていません。リッスン中のポートを確認するには ss を使います。
sudo ss -lntup結果は、マシン上で現在有効なサービスだけになるはずです。
sudo ss -lntupNetid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 *:9094 *:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=29,fd=3))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=29,fd=4))GitLab を起動するには、ソフトウェアの再構成コマンドを実行します。
sudo gitlab-ctl reconfigureGitLab はコンポーネントサービスを起動します。完了したら、GitLab がポート 22 と 80 の両方でリッスンしていることを確認します。
sudo ss -lntupNetid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 *:9094 *:*
tcp LISTEN 0 4096 127.0.0.1:9236 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8150 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=29,fd=3))
tcp LISTEN 0 4096 127.0.0.1:8151 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8153 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8154 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8155 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:8060 0.0.0.0:* users:(("nginx",pid=324,fd=8))
tcp LISTEN 0 4096 127.0.0.1:9121 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9090 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9187 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9093 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:9229 0.0.0.0:*
tcp LISTEN 0 1024 127.0.0.1:8080 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=324,fd=7))
tcp LISTEN 0 4096 127.0.0.1:9168 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8082 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=29,fd=4))
tcp LISTEN 0 4096 *:9094 *:*ユーザーは SSH(ここではポート 22)と、Web アプリの HTTP(ポート 80)で GitLab に接続します。次の手順で、どちらも Cloudflare Access 経由で試せるようにします。このまま起動しておき、Cloudflare ダッシュボードへ移ります。
Cloudflare Access で Zero Trust ルールを作成し、GitLab の Web アプリケーション(HTTP)へ接続できるユーザーと、SSH で接続できるユーザーを決められます。
ユーザーが Access で保護したサイトへリクエストすると、そのリクエストはまず Cloudflare のネットワークに届きます。Access は、そのユーザーがアプリケーションに到達してよいかを確認します。Cloudflare Tunnel と組み合わせた Zero Trust の構成は、次のようになります。
アプリケーションへ到達できるユーザーを決めるため、Cloudflare Access は Okta、Microsoft Entra ID、Google などの ID プロバイダーと連携し、入口で確認する身分証を発行します。VPN は、誰かが能動的な拒否ルールを作らない限りプライベートネットワークを自由に使えます。Access は、すべてのリクエストで(設定した粒度でも)その身分確認を強制します。
GitLab では、まずポリシーを 2 つ作成します。ユーザーは Web アプリと SSH の 2 とおりで GitLab に接続します。それぞれにサブドメインを保護するポリシーを作ります。最初は Web アプリです。
ルールを作る前に、これらの手順 に従ってアカウントで Cloudflare Access を設定してください。
有効にしたら、Zero Trust の Applications ページを開きます。Create new application を選びます。
Self-hosted and private を選びます。
リソースを表すサブドメインの追加を求められます。Cloudflare アカウント内のドメインのサブドメインである必要があります。Web アプリケーションと SSH のフローには、別々のサブドメインが必要です。
この例では、Web アプリケーションに gitlab.widgetcorp.tech、SSH 接続に gitlab-ssh.widgetcorp.tech を使います。
認証を許可する ID プロバイダーを選べます。デフォルトでは、設定済みのプロバイダーがすべて許可されます。サイトへ到達できるユーザーを決めるルールを追加します。
Create を選んでアプリケーションを公開します。2 つ目のアプリケーション gitlab-ssh.widgetcorp.tech でも同じ手順を繰り返します。
Cloudflare Tunnel は、このマシンと Cloudflare のネットワークのあいだに、アウトバウンドのみの安全な接続を作ります。アウトバウンドのみのモデルでは、このマシンへの直接アクセスを防ぎ、外部に開いた入口をすべて閉じられます。ファイアウォールのポートを開ける必要もありません。
Cloudflare Tunnel は、Cloudflare の軽量デーモン cloudflared で実現します。Downloads ページの手順に従い、DigitalOcean のマシンへ cloudflared をダウンロードしてインストールします。
インストールしたら、次のコマンドで cloudflared のインスタンスを認証します。
cloudflared loginコマンドは、Cloudflare アカウントでログインするために開く URL を表示します。
アカウントに追加済みのサイトを選びます。
アカウント内のサイトを選ぶと、Cloudflare はこの cloudflared インスタンスを認証する証明書ファイルをダウンロードします。これで、Cloudflare アカウント内の Cloudflare Tunnel 接続を cloudflared で制御できます。
Cloudflare Tunnel を使い、GitLab を Cloudflare に接続できます。
- 次のコマンドを実行し、新しい Tunnel を作成します。
cloudflared tunnel create gitlabcloudflared はこの Tunnel 用の一意な ID を生成します。例: 6ff42ae2-765d-4adf-8112-31c55c1551ef。この Tunnel は SSH と HTTP の両方に使えます。
- Cloudflare Tunnel が両方の宛先へトラフィックをプロキシするよう設定します。次の構成は、Web アプリ用に作成する DNS レコードと、SSH トラフィックを表す DNS レコードのトラフィックを、正しいポートへ送ります。
お好みのテキストエディターで設定ファイルを編集します。この例では Vi を使います。
vim ~/.cloudflared/config.yml- トラフィックを処理するよう Tunnel を設定します。
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /root/.cloudflared/6ff42ae2-765d-4adf-8112-31c55c1551ef.json
ingress:
- hostname: gitlab.widgetcorp.tech
service: http://localhost:80
- hostname: gitlab-ssh.widgetcorp.tech
service: ssh://localhost:22
# Catch-all rule, which just responds with 404 if traffic doesn't match any of
# the earlier rules
- service: http_status:404
- 設定ファイルが正しいかは、次のコマンドで確認できます。
cloudflared tunnel ingress validatecloudflared は Tunnel に問題がないことを示します。これで Tunnel を実行できます。
cloudflared tunnel run
Cloudflare ダッシュボードで、GitLab 用の DNS レコードを作成できます。Web アプリケーション用と SSH トラフィック用の 2 件が必要です。
-
Cloudflare ダッシュボード ↗ にログインし、対象ドメインの DNS Records ページを開きます。
Records を開く ↗ -
Add record を選びます。レコードタイプは
CNAMEにします。 -
Name 欄に
gitlabを入力します。 -
Target 欄に、作成した Tunnel の ID のあとに
cfargotunnel.comを付けた値を入力します。この例では次の値です。
6ff42ae2-765d-4adf-8112-31c55c1551ef.cfargotunnel.com- Save を選びます。
- 同じ Target で 2 つ目の
CNAMEレコードを作成し、Name にはgitlab-sshを入力します。両方のレコードが同じ Tunnel を指します。上の設定ファイルの ingress ルールが、トラフィックを適切なポートへ送ります。
Web アプリケーションのエンドツーエンド構成を確認できます。Web アプリケーション用に作成したサブドメインを開きます。Cloudflare Access が認証を求めます。プロバイダーでログインします。
認証が完了すると、GitLab の Web アプリケーションが表示されます。
自分のアカウントを登録し、次の手順で SSH を試すための Blank プロジェクトを作成します。
GitLab は新しいプロジェクトとリポジトリを作成します。
SSH でコードを push / pull するには、クライアントマシンにも cloudflared をインストールする必要があります。この例では macOS のラップトップを使います。macOS では、次のコマンドで cloudflared をインストールできます。
brew install cloudflaredcloudflared のインストールは必要ですが、SSH コマンドを特別な形で囲む必要はありません。代わりに、SSH 設定ファイルを一度だけ変更します。
vim /Users/samrhea/.ssh/config次の値を入力します。gitlab-ssh.widgetcorp.tech は作成したホスト名に置き換えます。
Host gitlab-ssh.widgetcorp.tech
ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h先ほど作成したプロジェクトをクローンして、SSH フローを確認できます。
git clone git@gitlab-ssh.widgetcorp.tech:samrhea/democloudflared は ID プロバイダーでのログインを求め、成功するとデバイスへトークンを発行して認証できるようにします。
DigitalOcean のファイアウォールに、インバウンドトラフィックをすべてブロックするルールを 1 つ設定し、直接アクセスを防ぎます。
Cloudflare Tunnel はアウトバウンドのみの接続を続けます。このマシンが暗号通貨マイニングや、それ以上の被害に巻き込まれるのを避けられます。
許可およびブロックされたイベントのログも確認できます。Zero Trust の Logs セクションで Access ページを開きます。
Git Large File Storage(LFS)を使っている場合、cloudflared は Git LFS を自動ではサポートしません。Cloudflare Access で保護したリポジトリへアクセスするには、次のコマンドを実行して手動で認証します。
cloudflared access login <your-git-access-url><your-git-access-url> は、Cloudflare Access で保護した URL に置き換えます。