Ubuntu Weekly Recipe

第881回IPv6オンリー環境でも家庭内サーバーをインターネットに公開できる⁠トンネル型リバースプロキシPangolinを構築する

本連載の読者であれば、家庭内にサーバーを構築して、NextcloudのようなWebアプリケーションを動かしている人も多いでしょう。そして今時のWebアプリケーションであれば、インターネットからアクセス可能にして、外出先からも利用したいと考えるのは自然なことです。従来であれば、プロバイダの固定IPアドレスサービスやダイナミックDNSを利用して、インターネットから自宅のルーターへ到達できるようにした上で、ルーターのポートを開放し、LAN内のサーバーを公開するという手順が一般的でした。

しかし昨今、こうした従来の方法が適用できない環境も増えてきています。例えば筆者はNTTのフレッツ光クロスを自宅で利用しているのですが、プロバイダの都合上、グローバルなIPv4アドレスがルーターに割り当てられていません。使用できるのはIPv6アドレスのみで、IPv4の通信はIPv6でカプセル化してプロバイダのAFTRまでトンネリングする、いわゆるDS-Lite接続となっています。こうしたキャリアグレードNATな環境では、従来のようにIPv4アドレスで家庭のルーターまで到達できません。

ルーターのポートを開放する方法には、別の欠点もあります。それは特定のポート宛ての通信をLAN内のサーバーに転送するという仕組み上、ひとつのポートがひとつのサービスでしか使えないことです。たとえばLAN内にHTTP(TCP:80)を使うアプリケーションAとアプリケーションBが動いていたとしましょう。ですがルーターの80番ポートは、どちらかのアプリケーションにしか向けられません。必然的にもう片方のサービスにアクセスするには、別のポートを割り当てる必要があり、アクセス時にポートの指定が必要となって使い勝手が悪くなります。またインターネットからLAN内への通信を許可するためには、ファイアウォールにも適切な設定が必要です。

こうした問題を解決できるのが、今回紹介するトンネル型リバースプロキシです。

トンネル型リバースプロキシとは

一般的なリバースプロキシはサーバーの前段に配置され、クライアントの代理としてバックエンドにアクセスするサービスです。複数のバックエンドサーバーにアクセスを振り分けたり、ロードバランシングやSSL終端処理などの機能も提供しています。トンネル型リバースプロキシは、これにVPNトンネルの機能を組み合わせたものです。LAN内にあるクライアントがインターネット上のリバースプロキシサーバーに対してVPNを張り、そのVPNトンネルを経由して、インターネットからの通信をLAN内のサーバーへプロキシします。

この方式の最大のメリットは、LAN内からインターネット上のサーバーに向けて接続を開始するため、ルーターのポート開放やファイアウォールの設定変更が不要な点です。VPNを張れればよいため、グローバルなIPv4アドレスが自宅のルーターに割り当てられているかも関係ありません。プロキシサーバー側でホスト名ベースのルーティングを行えるため、複数のサービスを同時に、標準的なHTTP/HTTPSポートで公開できます。

Pangolinは、このトンネル型リバースプロキシを実現するオープンソースソフトウェアです。簡単に言ってしまえば、PangolinはセルフホストできるCloudflare Tunnelのようなものです。今回はVPS上に、インターネットからの窓口となるPangolinサーバーを構築します。そしてこのPangolinにLAN内のクライアント(Newt)から接続し、LAN内で動いているWebサーバーを、インターネットからアクセス可能にする手順を紹介します。

図1 Pangolinのおおまかな構成図

Pangolinのインストール

Pangolinには大きく3つの利用形態があります。

ひとつは完全マネージドのクラウドサービスを利用する方式です。自分でサーバーを用意する必要がないため手軽ではありますが有料のサービスであり、無料プランでは様々な制限があります。もうひとつが「マネージドセルフホスト」と呼ばれる形態です。Pangolinサーバー自体はセルフホストするものの、クラウドダッシュボードを介してコントロールプレーン、データベース、バックアップなどを管理できる、ハイブリッドな構成です。トラフィックは自前のサーバーを介して流れるため、プライバシーを確保しつつ、運用上の面倒な部分をクラウドに任せられます。そして最後が、すべてを自前のサーバーでセルフホストする方式です。今回はこの方式を解説します。

当然ですが、Pangolinを動かすサーバーはインターネット上にあり、ネットワーク的に到達可能でなくてはなりません。Pangolinはそれほど重いソフトウェアではないため、安価なVPSサーバーを一台契約するのがよいでしょう。今回筆者は、Amazon Lightsailを利用しました。

図2 今回は2vCPU、1GBメモリのインスタンスを用意した

インストールに先立ってUbuntu 24.04 LTSのインスタンスを起動します。インスタンスにIPアドレスが割り当てられたら、サーバーの名前解決ができるよう、DNSにA/AAAAレコードを登録しておいてください。またファイアウォールでTCP:80、TCP:443、UDP:21820、UDP:51820の4つのポートを開いておきます。

図3 ファイアウォールのポートを開放する

PangolinのインストーラーはGoで書かれたバイナリです。最新のインストーラーをダウンロードするためのスクリプトがありますので、まずはこれを実行しましょう。なおインストーラーは、カレントディレクトリにすべてのファイルを展開するため、あらかじめディレクトリを作っておくとよいでしょう。これを忘れてホームディレクトリでうっかり実行すると、少し面倒なことになります。

$ mkdir ~/pangolin && cd ~/pangolin
$ curl -fsSL https://digpangolin.com/get-installer.sh | bash

上記のコマンドを実行すると、カレントディレクトリにinstallerというバイナリがダウンロードされています。これをsudoつきで実行しましょう。あとは対話的に質問に答えていくだけです。

$ sudo ./installer
Welcome to the Pangolin installer!
This installer will help you set up Pangolin on your server.

Please make sure you have the following prerequisites:
- Open TCP ports 80 and 443 and UDP ports 51820 and 21820 on your VPS and firewall.

Lets get started!

=== Basic Configuration ===
Do you want to install Pangolin as a cloud-managed (beta) node? (yes/no): no                           ← 今回はPangolinを完全セルフホストするためnoを入力
Enter your base domain (no subdomain e.g. example.com): example.com                                    ← 自分のドメインを入力
Enter the domain for the Pangolin dashboard (default: pangolin.example.com): pangolin.example.com      ← あらかじめDNSに登録した、PangolinサーバーのFQDNを入力
Enter email for Let's Encrypt certificates: mizuno@example.com                                         ← 自分のメールアドレスを入力
Do you want to use Gerbil to allow tunneled connections (yes/no) (default: yes): yes                   ← トンネルを利用するのでyesを入力

=== Email Configuration ===
Enable email functionality (SMTP) (yes/no) (default: no): no                                           ← メールサーバーの設定は後からでもできるため、ここではnoを入力

=== Advanced Configuration ===
Is your server IPv6 capable? (yes/no) (default: yes): yes                                              ← IPv6も使いたいため、yesを入力

=== Generating Configuration Files ===

Configuration files created successfully!

=== Starting installation ===
Would you like to install and start the containers? (yes/no) (default: yes): yes                       ← Pangolinをコンテナで動かしたいためyesを入力
Would you like to run Pangolin as Docker or Podman containers? (default: docker): docker               ← コンテナ実行にはDockerを使いたいため、dockerと入力
Docker is not installed. Would you like to install it? (yes/no) (default: yes): yes                    ← ここでDocker本体もインストールしたいため、yesを入力

(ここでDockerのインストールとコンテナの起動が行われる。省略)

=== CrowdSec Install ===
Would you like to install CrowdSec? (yes/no) (default: no): no                                         ← CrowdSecは利用しないためnoを入力

=== Setup Token ===
Waiting for Pangolin to generate setup token...
Setup token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                                                          ← 初回セットアップ用のトークンが表示されるので控えておく

This token is required to register the first admin account in the web UI at:
https://pangolin.example.com/auth/initial-setup                                                        ← セットアップ用のURLにブラウザからアクセスする

Save this token securely. It will be invalid after the first admin is created.

Installation complete!

To complete the initial setup, please visit:
https://pangolin.example.com/auth/initial-setup

ここではDockerを使用する設定としたため、インストーラーがdownload.docker.comのリポジトリを登録し、Dockerのパッケージをインストールしてくれます。またDocker Composeを使ったコンテナの起動までが自動的に行われます。

Pangolinの初期設定とSiteの作成

インストールの最後に表示された、初回セットアップ用のURLにブラウザでアクセスしましょう。すると以下のようなInitial Server Setupの画面が表示されるので、先ほど控えたトークン、メールアドレス、パスワードを入力してください。弱いパスワードは拒否されるので、強いパスワードを設定するようにしましょう。

図4 Pangolinの初期セットアップ画面

すると自動的にログイン画面に遷移するので、先ほど設定したユーザーのメールアドレスとパスワードでログインします。

図5 Pangolinのログイン画面

ログインすると、新しいOrganizationの作成画面に遷移します。PangolinにおけるOrganizationとは、複数のSite(後述)とユーザーをグループ化する単位です。企業や組織ごとに分けて管理することを想定していますが、今回は個人利用ですので、⁠home」というOrganizationをひとつ作成しました。なおOrganizationには、その組織で利用するサブネットIPアドレスを割り当てる必要があります。今回はデフォルトのまま(100.90.128.0/24)を設定しました。

図6 Organizationの作成

続いてSiteの作成画面に遷移します。PangolinにおけるSiteとは、クライアントがPangolinに対してVPNトンネルを張るためのエンドポイントです。もっと単純に、SiteとはPangolinが張るVPNコネクションの単位だと考えてよいでしょう。すべてのResource(後述)はSiteに紐づくため、Siteはサーバーを公開するための基盤となる重要なコンポーネントです。今回は家庭内からPangolinに対してひとつのVPNコネクションを張るため、Siteもひとつだけ作成します。

まずSiteの名前とIPアドレスを決めます。名前は「home」としました。IPアドレスはOrganizationのサブネット内から指定する必要がありますので、100.90.128.10を指定しました。

図7 Siteに名前をつけ、IPアドレスを割り当てる

続いてトンネルタイプを指定します。Newtの利用が推奨されていますので、これを選択しましょう。NewtはPangolinのために用意された、WireGuardクライアント兼TCP/UDPプロキシです。ちなみに選択肢を見るとわかりますが、PngolinはVPNトンネルを使わず、ローカルなリバースプロキシとして使うことも可能です。

図8 トンネルタイプの選択

NewtからPangolinへの接続に必要な、エンドポイント、ID、シークレットキーが表示されます。これらの情報は、この場で一度しか確認できないため、忘れずに控えておいてください。

図9 接続情報を控えておく

最後に、Newtのインストール方法を選択します。NewtもPangolinと同様に、Dockerで動かすのが一番手軽です。そこで「Docker」⁠Docker Compose」を選択します。すると起動用のcompose.yamlが表示されますので、こちらも控えておいてください。

図10 Docker ComposeのYAMLが表示されるので、控えておく

最後に「Create Site」をクリックすれば、Siteの作成は完了です。

Newtクライアントの起動

Pangolin側のSiteが用意できたので、次はLAN内にクライアント(Newt)を用意しましょう。ここではまっさらのUbuntu 24.04 LTSの仮想マシンを一台用意しました。前述の通り、NewtをDockerで動かしたいため、DockerとComposeをインストールしておきます。

$ sudo apt install -U -y docker.io docker-compose-v2

compose.yamlを作成し、先ほど控えた内容をペーストしてください。

$ mkdir ~/newt && cd ~/newt
$ cat > compose.yaml <<EOF
(先ほど控えたcompose.yamlの内容をペースト)
EOF

compose.yamlがあるディレクトリで、dockerを起動します。

$ sudo docker compose up -d

これでLAN内からPangolinサーバーへ、VPNトンネルが確立されました。PangolinのSitesを開き、Siteがオンラインになっていることを確認してください。

図11 Siteがオンラインになることを確認する

Resourceの作成

最後にResourceを作成します。PangolinにおけるResourceとは、プロキシの対象となるサーバーやサービスの定義です。Pangolinのダッシュボードで、左サイドバーから「Resources」を選択し、⁠Add Resource」をクリックしてください。

図12 新しいResourceを作成する

今回はLAN内のWebサーバーにHTTPアクセスをプロキシしたいため、HTTPS Resourceを選択しました。また名前はわかりやすく「www」としました。

図13 HTTPSをプロキシする

HTTPSをプロキシするため、サブドメイン名を設定します。ここもわかりやすく、サブドメインは「www」としました。ベースドメインはPangolinに設定したドメインとなります。なおユーザーがこの名前でPangolinにアクセスできる必要があるため、このタイミングでPangolinサーバーのAレコードに対して、CNAMEレコードを設定しておくとよいでしょう。

最後にTargets Configurationを設定します。これは実際のプロキシ先となる、LAN内のサーバーです。Siteは使用するVPNコネクションですので、先ほど作成した「home」を指定します。今回のMethodはhttpで、IPはプロキシ先のサーバーのLAN内でのIPアドレス、ポートはHTTPサーバーなので80になります。設定が入力できたら、忘れずに「Add Target」をクリックしてください。

図14 HTTPSとターゲットの設定

最後に「Create Resource」をクリックすると、Resourceが作成されます。

ユーザー認証の追加

リソースが作成されたら、Manage Resourcesの画面から「Edit」をクリックして、⁠Authentication」タブを開いてください。ここでResourceへの認証を設定できます。Use Platform SSOを有効にしていると、Pangolin上で作成したロールやユーザー単位でアクセスを制御できます。なおこの際、Organizationのオーナーであるユーザーは、明示的な設定をしなくても接続が許可されます。

図15 ユーザーやロール単位でアクセスを制御する

また「Add Password」「Add PIN Code」をクリックすると、ユーザーやロール単位ではなく、共通のパスワードやPINコードでの認証も可能となっています。

図16 共通パスワードやPINコードを設定できる

公開されたサーバーにアクセスする

Resourceに設定したFQDNへブラウザでアクセスしてみましょう。Authentication Requiredの画面が表示されたら、Resourceにアクセスを許可されているPangolinのユーザーでログインしましょう。

図17 Resourceにアクセスしようとすると、Pangolinの認証画面が表示される

正しく認証を突破できると、Apache2のWebサーバーの画面が表示されました。ファイアウォールやルーターに設定を入れることなく、LAN内のサーバーをインターネットに公開できたことが確認できました。またPangolinによって、柔軟なアクセスの制限も可能なことがわかったのではないでしょうか。

図18 LAN内にあるUbuntuのApache2のデフォルトページが表示された

Pangolinは、内部的にLet's Encryptを使って自動的にSSL証明書を取得します。そのため追加したResourceにも、正規のSSL証明書を使ってセキュアにアクセスが可能です。


Pangolinを使えば、IPv4グローバルアドレスが利用できない環境でも、家庭内にあるサーバーを公開できます。またそれだけに留まらず、Web UIベースでユーザーやリソースを管理でき、シングルサインオンも実現できます。セキュリティを保ちながら、複数のサービスを標準ポートで公開できる点も魅力です。

個人的にWebアプリをホストしたり、あるいは開発目的で家庭内サーバーをインターネットに公開する際は、Pangolinが有力な選択肢となるでしょう。トンネルが不要な環境であっても、高機能なリバースプロキシとして導入する価値があると筆者は考えています。筆者は現在、コンテナの前段にNginx + Certbotでリバースプロキシを構築しています。ですが自分でSSL証明書を取得したり、Nginxの設定ファイルを手で書き換えるのは面倒なため、これをPangolinに置き換えようかなと検討中です。

図19 筆者の自宅内で稼動しているProxmox VEの管理画面に、Pangolinを経由してアクセスした例。こうしたLAN内のリソースにも、外部からセキュアにアクセスが可能になるため、非常に便利だ

おすすめ記事

記事・ニュース一覧