ngrokの代替 – FRPでセルフホストトンネリングを実現
ngrokと言えばhttp/httpsやTCP通信のフォワーディングが出来るサービスとして有名だが、不便だと感じたことはないだろうか。
私もこのngrokをMinecraftのサーバー用でTCP 25565の公開用で使うことがあるが、毎回公開ポートが変わったり、アドレスが変わったりで最近不便に感じている。
そこで、ngrokを自作できないか色々調べてみた。
Self-hosted ngrokを使う方法
まず初めに、Self-hosted ngrokと出会った。その名の通り自分でngrokをホストするというものだった。
それだけを聞くとSelf-hosted ngrokは最強に見えなくもないが、これはngrokの古いバージョンが使われているようで、下記の通りに公式からも実質的な非推奨を述べられていた。
この時点で、ngrokを流用する方法は途絶えてしまった。
SSH -Rを使う方法
この方法は非常に有名だが、TCPプロトコルしか使用することが出来ないためあっさり却下。
FRPとの出会い
次に、FRP(Fast reverse proxy)に出会った。どうやらこれはNATやファイヤーウォールの背後にあるローカルサーバーをインターネット上に公開することが出来る高速なリバースプロキシらしい。
また、FRPはTCP, UDP, HTTP, HTTPS, TCPMUX, STCP, SUDPのプロトコルに対応しており、めちゃめちゃ幅広いことが分かった。
というわけで、これを使ってみることにした。
ホスト方法
身構えていたのだが、FRPは驚くことに超簡単だった。
まず初めに、公式GitHubのReleasesから自分の使っているOSに適したファイルをDLする。
私の場合はサーバー側にUbuntu、クライアント側にWindowsを使用していたので、frp_バージョン_linux_amd64.tar.gz
とfrp_バージョン_windows_amd64.zip
をDLする。
まずはサーバー側から構築していく。DLから解凍までは以下のコマンドでできる。尚、このガイドではバージョン0.61.0を対象とする。
wget https://github.com/fatedier/frp/releases/download/v0.61.0/frp_0.61.0_linux_amd64.tar.gz
tar -zxvf frp_0.61.0_linux_amd64.tar.gz
次に、Ubuntu起動時にFRPSを自動起動するためのサービスを作る。(任意)
nano /etc/systemd/system/frps.service
[Unit]
Description=frps daemon
After=network.target
[Service]
Type=simple
ExecStart=/home/nomin/frp/frps -c /home/nomin/frp/frps.ini #この行は解凍したfrpsのパスを指定する。
Restart=always
RestartSec=20s
User=nobody
LimitNOFILE=infinity
[Install]
WantedBy=multi-user.target
FRPを解凍したパスに戻り、FRPSを下記のように設定する。
[common]
bind_port = 7000
token = #接続側と共有するトークン(パスワード)
dashboard_port = #ダッシュボードのポート番号(デフォルト7500)
dashboard_user = #Webダッシュポートのユーザー名
dashboard_pwd = #Webダッシュボードのパスワード
dashboard_addr = 0.0.0.0
allow_ports = #使用するポート番号 25565,19133,80など
注意点として、Minecraft統合版サーバーで使用するUDP 19132は使用できなかった。
Redditによるとこれは前からある問題のようで、おそらくFRPがデフォルトで特定のポートを使用していることが原因と見られる。
ufwなどでファイヤーウォールを設定している場合は、allowする必要がある。
sudo ufw allow 7000/tcp
sudo ufw allow 使用する全てのポート
これだけで導入は完了。サービスをEnableするだけで使用出来る。
sudo systemctl enable frps
sudo systemctl start frps
サーバー側の導入が完了したら、次にクライアント側の設定を行っていく。
今回はクライアント側としてWindowsを使用する。その為Windowsでのやり方となるが、基本的にどのOSでもやることは変わらない。
まずは先程DLしたWindows用のファイルを解凍する。
解凍後のディレクトリにあるfrpc.tomlファイルを開き、下記のように編集する。
transport.protocol = "tcp"
serverAddr = "サーバーのグローバルIP"
serverPort = 7000
auth.token = "サーバー側で設定したトークン(パスワード)"
#プロキシ設定↓
#以下の設定はMinecraftでの例。
[[proxies]]
name = "minecraft-tcp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 25565
remotePort = 25565
[[proxies]]
name = "minecraft-udp"
type = "udp"
localIP = "127.0.0.1"
localPort = 19133
remotePort = 19133
これだけで接続する準備が完了する。
実際に接続するには、下記のようにクライアント側から先ほど設定したfrpc.tomlを指定してfrpc.exeを起動する。
frpc.exe -c frpc.toml
それっぽいログが出てきたら成功だ。
ダッシュボード
ダッシュボードを参照することで、より簡単に接続テストができる。
先ほど設定したサーバー側のダッシュボードにアクセスしてみる。
URLはhttp://サーバーIP:設定したポート
となる。
アクセスすると、ログイン画面が表示される。
これも先ほど設定したsrps.iniの情報を使用してログインする。
ログイン後、左のメニューからProxyを選択し、任意のプロトコルを選択することで、以下のようにプロキシのオンラインステータスを確認できる。
あとがき
今回は、ngrokの代替として注目されているFRPについて詳しく解説した。多くの開発者が「マンションのインターネット回線でポート開放ができない」「ISPがポート開放を制限している」といった課題に直面していると思う。
そんな中で、FRPは最高な選択肢となっている。サーバー側とクライアント側の設定が比較的シンプルなうえ、TCP、UDP、HTTP、HTTPSなど複数のプロトコルに対応しているのが特徴だ。また、独自のダッシュボードで接続状態を簡単に監視できる点も便利に感じる。
確かに、レイテンシーの面では直接的なポート開放に比べて若干の遅延が発生する可能性はあるが、多くの場合では実用上問題のないレベルだと考えている。
このガイドが、皆さんの一助となれば嬉しい。