リバースプロキシとは何か
リバースプロキシは、利用者からのリクエストを最初に受け取り、内側にある適切なアプリへ転送して、返ってきた応答を利用者へ返す入口です。利用者はNextcloudや開発ツールの実際のIP・ポートを直接知る必要がありません。
Nginxはホスト名やURLのパスを見て転送先を選べます。HTTPSの処理、アクセスログ、WebSocket用ヘッダーなども入口へまとめられるため、サービスごとに外部公開設定を持たせるより管理しやすくなります。
- ↳外側: https://[Tailscaleが発行した公開URL]
- ↳入口: Tailscale FunnelまたはNginx
- ↳内側: http://[転送先アプリのアドレス]:[転送先アプリのポート番号]
- ↳返答は同じ入口を通ってブラウザへ戻る
公開範囲を先に決める
Tailscale Serveは同じtailnetに参加している端末だけへ共有する方法です。Tailscale Funnelはインターネット上の誰でもアクセスできるURLを作ります。個人用の管理画面やNextcloudは、まずServeまたは通常のTailscale接続を検討し、Funnelは本当に公開が必要な場合だけ使います。
ここでは、Nginxをローカルの入口として動かし、そのNginxだけをFunnelで公開する構成を扱います。バックエンドの各ポートを直接インターネットへ開けません。
Tailscaleを導入する
Linux用の公式インストールコマンドはcurlから始まります。『sudo -fsSL』はコマンドとして成立しないため使いません。インストール後にtailscale upを実行し、表示されたURLで認証します。
FunnelにはMagicDNSとHTTPS Certificatesが必要です。管理コンソールのDNSでMagicDNSを有効にし、HTTPS Certificatesも有効にします。元メモの『HTTPS Certificatesをdisableにする』は逆なので修正しました。
EXAMPLEcurl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
# 接続を確認
tailscale status
tailscale ip -4- ↳Tailscale v1.38.3以降
- ↳MagicDNSを有効化
- ↳HTTPS Certificatesを有効化
- ↳Funnelを許可するtailnetポリシー
- ↳公開URLはtailnetの.ts.netドメイン
Nginxをローカル入口にする
Nginxは、この端末だけから接続できるアドレスと未使用のポートで待ち受け、LAN内のアプリへ転送します。Funnelが受けたHTTPS通信をNginxの待受先へ渡し、Nginxが指定したアプリへ転送する流れです。角括弧の日本語部分を、自分の環境に合う値へ置き換えます。
EXAMPLEsudo apt update
sudo apt install nginx
sudo nano /etc/nginx/sites-available/reverse-proxy
# reverse-proxy の内容
server {
listen [この端末だけを示すアドレス]:[Nginxの待受ポート番号];
server_name _;
location / {
proxy_pass http://[転送先アプリのアドレス]:[転送先アプリのポート番号];
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}設定を有効化してテストする
設定ファイルをsites-enabledから参照できるようにし、必ず構文テストを通してから再読み込みします。すでに同名のリンクがある場合はlnを繰り返さず、現在の参照先を確認します。
EXAMPLEsudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/reverse-proxy
sudo nginx -t
sudo systemctl reload nginx
# Nginx単体をローカル確認
curl -I http://[この端末だけを示すアドレス]:[Nginxの待受ポート番号]- ↳nginx -t が successful になる
- ↳Nginxの待受先が応答する
- ↳転送先アプリが起動している
- ↳Nginxのaccess.logとerror.logを確認できる
FunnelでHTTPS公開する
現在のTailscale CLIでは、公開したいローカルの転送先を最後に指定します。Funnelが対応するHTTPS公開ポートで通信を受け、同じ端末で動くNginxの待受先へHTTPで渡します。利用できる公開ポートは、実行前にTailscale公式資料で確認します。
--bgを付けると再起動後も設定が復元されます。表示された公開URLをメモし、シークレットウィンドウなどtailnet外の環境から確認します。
EXAMPLEsudo tailscale funnel --bg --https=[Tailscaleが対応するHTTPS公開ポート番号] http://[この端末だけを示すアドレス]:[Nginxの待受ポート番号]
# 現在の公開状態
sudo tailscale funnel status
# すべてのFunnel設定を解除
sudo tailscale funnel reset複数サービスを管理する
一つの端末には基本的に一つのTailscale用ドメイン名があります。同じ端末で複数サービスを扱う場合は、NginxでURLのパスを分ける、待受ポートを分けてFunnelが対応する公開ポートへ割り当てる、またはサービスごとにTailscaleノードを分けます。存在しない別端末名をserver_nameへ書くだけでは新しいURLは作られません。
EXAMPLEserver {
listen [この端末だけを示すアドレス]:[Nginxの待受ポート番号];
server_name _;
location /[一つ目のアプリを示すパス]/ {
proxy_pass http://[一つ目のアプリのアドレス]:[一つ目のアプリのポート番号]/;
}
location /[二つ目のアプリを示すパス]/ {
proxy_pass http://[二つ目のアプリのアドレス]:[二つ目のアプリのポート番号]/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}独自ドメイン+Nginxで直接公開する別案
独自ドメイン、Let's Encrypt証明書、NginxのHTTPS公開ポートを使う構成はTailscale Funnelとは別の公開方法です。DNSを自分の公開アドレスへ向け、ルーターとファイアウォールでWeb通信に必要なポートへ到達できるようにし、証明書を取得する必要があります。賃貸回線やCGNATでは使えない場合があります。
転送先がTailscale内にある場合、Nginxを動かす端末も同じtailnetへ参加させます。証明書パスはCertbotなどが実際に作成した場所を使います。
EXAMPLEserver {
listen [HTTPSで使う公開ポート番号] ssl;
server_name [自分の独自ドメイン];
ssl_certificate [発行された証明書ファイルの場所];
ssl_certificate_key [発行された秘密鍵ファイルの場所];
location / {
proxy_pass http://[転送先アプリのアドレス]:[転送先アプリのポート番号];
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}ファイアウォールは必要最小限にする
Funnelから同じ端末のNginxへ渡す構成では、Nginxの待受ポートをUFWで外部へ開ける必要はありません。待受ポートを無条件で許可すると、Nginxの設定によってはLANや公開インターフェースから直接到達でき、Funnelを通す意味が薄れます。
独自ドメインで直接公開する構成だけ、Web通信に必要な公開ポートを開けます。管理用SSHや転送先アプリのポートは送信元を限定します。
EXAMPLEsudo ufw status verbose
# 独自ドメインでNginxを直接公開する場合の例
sudo ufw allow [HTTPSで使う公開ポート番号]/tcpNginxが起動しないとき
systemdの『ExecStartPre process exited』『status=1』は、起動前の設定確認に失敗したという結果です。原因そのものはnginx -tやjournalctlの少し上に表示されます。設定を増やす前に、最初のエラー一件を修正します。
EXAMPLEsudo nginx -t
sudo systemctl status nginx --no-pager
sudo journalctl -u nginx -n 100 --no-pager
sudo ss -ltnp
# 設定ファイルと有効化リンクを確認
ls -l /etc/nginx/sites-enabled/
sudo nginx -T- ↳セミコロン、波括弧、http://の書き忘れ
- ↳同じポートを別プロセスが使用
- ↳sites-enabledのリンク切れ
- ↳同じserver_nameやlisten設定の重複
- ↳証明書ファイルが存在しない、または権限不足
- ↳proxy_pass先のアプリが停止