Ubuntu Weekly Recipe

第914回IPv6オンリー環境でも家庭内にVPNを繋ぎたい⁠Pangolinのプライベートリソースを試す

第881回では、VPNを利用したトンネル型リバースプロキシPangolinを紹介しました。今回はPangolinの1.13以降で実装されたプライベートリソースを使い、インターネットからよりセキュアにLAN内のリソースへアクセスする方法を解説します。

Pangolinとは

PangolinとはVPNを利用したトンネル型のリバースプロキシです。インターネット上からアクセス可能なPangolinサーバーに対してLAN内からVPNを張り、このトンネルを経由することで、LAN内のサーバーをインターネットからアクセス可能にします。LAN内からコネクションを開始するため、⁠ルーターのポート開放が不要」⁠ファイアウォールのInboundルールの変更が不要」⁠グローバルIPv4アドレスがない環境でもサーバーを公開できる」といった特徴を持っています。

詳しくは前回の記事を参照してください。

プライベートリソースとは

前回の記事で紹介したのは、Pangolin的にはパブリックリソースと呼ばれるリソースです。これは一言で言うと「外部公開するリバースプロキシ」です。Pangolinサーバーに到達できるURLをインターネットに公開し、ブラウザやアプリからのアクセスをバックエンドへ転送します。Pangolinのユーザー認証機能を用いて、任意で認証をかけることも可能ですが、基本的にはインターネットへ公開するサービス向けのリソースとなります。

パブリックリソースのメリットは、URLさえ渡せばブラウザだけで使える点です。またNextcloudのようなアプリをモバイル環境から使う際にも便利でしょう。ただしPangolinサーバー上のURLとしてインターネットから到達可能になるため、アプリ側で認証をかけていたとしても、ログイン画面やアプリケーション自体が外部から見える状態になります。当然不正アクセスも大量にやって来ます。

対してプライベートリソースとは、専用のPangolinクライアント接続時にのみアクセスできる、ゼロトラストVPNです。PCやスマホにインストールしたPangolinクライアントを使ってPangolinサーバーに接続すると、許可されたプライベートリソース宛の通信だけをバックエンドへ流します。LAN側とモバイル端末の双方がPangolinサーバーへVPNを張り、Pangolinサーバーがアクセス権限を見た上で適切にルーティングする構成です。その特性上、Pangolinのユーザー/クライアント認証機能の利用は必須となります。

プライベートリソースは、普段からインターネットに晒す必要はないが、場合によっては外からアクセスできないと困るタイプのサービスに向いています。たとえば筆者は自宅内でVaultwardenを運用しているのですが、外出先からアクセスできないと困ることが稀にあります[1]。とはいえそんなレアケースのために、パスワードマネージャーのログイン画面をインターネットに常時晒すのは、メリットに比べてリスクが大きすぎます。そこでPangolinのプライベートリソースとして運用しています。

プライベートリソースは単一ホスト、CIDR、FQDNを対象にできるため、リバースプロキシ的な使い方だけでなく、一般的なVPNとしても使えます。グローバルIPv4アドレスを持たないご家庭であっても、外部から接続するVPNを運用できるというわけです。

Pangolinクライアントの登録とインストール

ここからは、前回の記事通りにPangolinを構築済みである前提で解説します。またPangolinは本記事執筆時点の最新バージョンである1.18.4を対象とします。

Pangolinの管理画面にログインし、⁠Clients⁠⁠→⁠Machines」を開きます。⁠Create Client」をクリックしてください。クライアントの登録画面に遷移します。

図1 クライアントの登録

「Name」にはクライアントの名前を入力します。あくまで管理上の表示名であり、あとから変更も可能です。⁠Advanced Settings」ではクライアントに割り当てるIPアドレスを指定もできますが、通常はデフォルトのままでよいでしょう。

図2 クライアントに識別用の名前をつける

「Install Machine Client」で、クライアントをインストールするプラットフォームを選択します。macOSやWindowsにも対応していますが、今回はUbuntuデスクトップにバイナリを直接インストールしますので「Unix & macOS⁠⁠→⁠All」を選択してください[2]⁠Commands」の欄にインストール用のワンライナーと、接続用コマンドも表示されますので、両方を控えておきましょう。コマンドのパラメータとして指定されているクライアントIDとシークレットは、Pangolinとのコネクションを確立するために必要な機密情報となります。第三者の目には触れないよう、くれぐれも取り扱いに注意してください。

図3 対象のシステムを選択すると、それに応じたインストール用のコマンドが表示される

最後に「Create Client」をクリックします。

サーバー側にクライアントの登録ができたら、実際にクライアントをインストールしましょう。インストール対象のマシン上で、先ほど控えた以下のコマンドを実行してください[3]。なおUbuntuデスクトップの場合、先にcurlコマンドをインストール必要があるかもしれません。

$ sudo apt install -U -y curl
$ curl -fsSL https://static.pangolin.net/get-cli.sh | sudo bash

CIDRタイプのプライベートリソースの作成

Pangolinにプライベートリソースを作成しましょう。まずは一般的なVPNのように、LAN全体にアクセスできるようCIDRをターゲットとする例を紹介します。Pangolinの管理画面にログインしたら、⁠Resources⁠⁠→⁠Private」を開きます。⁠Add Resource」をクリックしてください。リソースの追加画面に遷移します。

Nameにはプライベートリソースを識別するための名前を入力します。ここでは家庭内LANへ接続するため、⁠LAN」としました。

Siteは、リソースへの接続に使うPangolinのSiteを指定します。ここでは前回の記事で作成した、パブリックリソースへのアクセスにも利用しているNewtのコネクション(名前はHome)を指定しました。

Modeはアクセスするリソースのタイプです。今回はCIDRを選択し、対象のIPアドレスをCIDRで記述します。LAN全体にアクセスさせたいため、筆者の家庭内のネットワークアドレスである「192.168.1.0/24」を指定しました。

Port Restrictionsは、アクセスを許可するTCP/UDPのポートです。特に制限を設けたくはなかったため、デフォルトのままとしています。

図4 CIDR単位のプライベートリソースを作成する

Access Policyタブでは、このリソースへアクセスできるPangolin上のロール、ユーザー、マシンクライアントを設定します。これにより同じサイト内に存在するサーバーであっても、特定のユーザーやクライアントだけにアクセスを制限できるのです。今回は「Machine Clients」に、先ほど登録したクライアント(ubuntu-desktop)を追加してください。Pangolinクライアントは、自分自身がアクセスを許可されているリソースへのルートのみを、ホストのルーティングテーブルに追加するという挙動をします。そのためここを設定し忘れると、クライアント自体はConnectedになっていても、対象ネットワークへのルートが追加されず、リソースへアクセスできません。忘れないよう注意してください。

図5 作成したクライアントをアクセス許可リストに追加する

最後に「Create Resource」をクリックします。

プライベートリソースへのアクセス

クライアントの登録時に控えた、以下のコマンドを実行してください。これでクライアントが起動します。

$ sudo pangolin up --id クライアントID --secret シークレット --endpoint Pangolinのエンドポイント --attach

別のターミナルを起動して、ipコマンドでルートを確認してみましょう。pangolinデバイスが生えてきて、クライアント作成時に割り当てられたIPアドレスが振られていることが確認できます。またプライベートリソースで定義したCIDRである「192.168.1.0/24」へは、pangolinデバイスを経由するよう設定されていることもわかります。

$ ip r
default via 172.16.0.1 dev ens18 proto dhcp src 172.16.6.67 metric 100 
100.90.128.0/24 dev pangolin proto kernel scope link src 100.90.128.2 
100.96.128.0/24 dev pangolin 
172.16.0.0/16 dev ens18 proto kernel scope link src 172.16.6.67 metric 100 
192.168.1.0/24 dev pangolin 

Pangolinのクライアント画面を見て、クライアントがConnectedになっていることも確認しておきましょう。

図6 クライアントを接続した状態

これでUbuntuデスクトップから「192.168.1.0/24」のIPアドレスに対してアクセスが可能になりました。実際にWebアプリにアクセスしてみたり、SSH接続してみたりと、挙動を試してみてください。

図7 LAN内に閉じているWebアプリへアクセスできるようになった。SSH接続も可能な上、CIDRのIPアドレスに対してPingも送信できる。

ホストタイプのプライベートリソースの作成

CIDRタイプのプライベートリソースを使えば、LAN全体に対してアクセスできます。しかしこれはIPアドレスベースでのアクセスとなるため[4]、SSL証明書を利用しているWebサーバーへアクセスしたいような場合に問題が起きます。筆者の自宅でも、単一のDockerホスト上にNginx Proxy Managerを立て、複数のDockerコンテナでホストされるアプリを集約しているため、名前ベースでないと目的のアプリへアクセスできません。そういう時はホストタイプのプライベートリソースを作り、個別のサーバーを登録するとよいでしょう。

リソースの作成方法はCIDRタイプの時と同じです。以下のようにリソースの作成画面で、⁠Mode」「Host」を指定してください。唯一異なるのが、⁠Alias」という欄があることです。ここには、そのホストにつけたいドメイン名(www.example.comなど)を入力してください。

図8 ホストタイプのプライベートリソースには、エイリアスを設定できる

Pangolinクライアントはデフォルトで、エイリアスが有効なモードで起動します。これはコネクションを張ると、カスタムDNSサーバーを使用して、内部的にエイリアスを使ったリソースの名前解決を可能にするモードです。LAN内でのみ使用できるドメインでサーバーの名前解決を行っているような場合は、プライベートリソースに同名のエイリアスを登録しておけば、Pangolin越しでも同じ名前でアクセスが可能になります。

図9 VPN経由でアクセスさせたいLAN内の各サーバーに対し、個別にリソースを作成してエイリアスを設定した。ここでは同じIPアドレスに対し、2つのリソースを別エイリアスで作成している。
図10 異なるエイリアスでアクセスした例。プロキシ先のIPアドレスは同一だが、きちんと名前ベースでNextcloudとVaultwardenにアクセスが振り分けられていることがわかる。LAN内で使っているドメイン名と同じエイリアスをつけているため、SSL証明書のエラーも発生しない。

Pangolinクライアントのサービス化

ここでのPangolinクライアントは「--attach」オプションを付けて起動しているため、フォアグラウンドで動作しターミナルを占有します。非常に邪魔なのですが、かといってバックグラウンドで起動すると、今度は停止するのが面倒になります。そこでsystemdのサービスにしておくと管理しやすく便利です。

まず以下のコマンドを実行して、ユニットファイルを作成します。

$ sudo systemctl edit --full --force pangolin-cli.service

テキストエディタが起動するので、以下の内容を記述して保存してください[5]

[Unit]
Description=Pangolin CLI
After=network.target

[Service]
ExecStart=/usr/local/bin/pangolin up --id クライアントID --secret シークレット --endpoint Pangolinのエンドポイント --attach
Restart=always
User=root

[Install]
WantedBy=multi-user.target

以後、⁠systemctl start/stop」でPangolinへの接続/切断が可能になります。

$ sudo systemctl start pangolin-cli.service
$ sudo systemctl stop pangolin-cli.service

プライベートリソースを使えば、インターネットからアクセスしたいリソースを直接外部に晒すことなく、セキュアに運用できます。また通常のVPNと異なり、ユーザーやクライアント単位で、細かくリソースへのアクセスを制御可能です。比較的新しいPangolinの機能ですが、もしPangolinを運用しているのであれば、ぜひ試してみてください。

おすすめ記事

記事・ニュース一覧