今年2月に我が家でドコモ光10ギガを導入したが、IPoE方式のため、固有のグローバルIPv4アドレスが割り当てられず、ポート開放ができない。いろいろ調べてた中で、簡単にポートフォワーディング(DNAT)ができるfirewalldというパッケージがあるとのことで、Tailscale VPNと組み合わせたら、疑似的に自宅サーバーを公開できたのでやり方を備忘録もかねて解説する。
本記事の目的
自宅サーバーの特定ポートを開放し、netcatでテスト通信を成功させる。
使用するもの
- ubuntuのvps(パケット転送用)
- Tailscale(VPN構築)
- firewalld(ポートフォワーディング用)
- netcat(テスト通信用)
解説
まず初めに、日本特有の事情として、IPoE方式ではグローバルIPv4が与えられないため、ポート開放によるサーバー公開が不可能になる。
イメージとしては公衆電話に近く、電話を掛ける(アウトバウンド通信)場合は宛先電話番号(通信先IPv4アドレス)があるので問題なくできるが、電話をかけてもらう場合(インバウンド通信)、公衆電話は電話番号(こちらのIPv4アドレス)がないため、かけてもらうことはできないというイメージになる。
なんでIPv4アドレスがないかって?
従来のPPPoE方式では、ISPからグローバルIPv4アドレスを直接割り当てる仕組みだった。 しかしIPv4アドレスは枯渇しており、全利用者にグローバルIPv4を与えるのは不可能になった。そのためIPoE方式では、IPv6アドレスを基本として割り当て、IPv4通信は「IPv4 over IPv6」などの仕組み(MAP-EやDS-Lite)を通して行うようになった。
このとき利用者は 共用のIPv4アドレス を使うことになり、インターネット側から直接到達できるユニークなIPv4アドレスは持てない。
結果として、家庭内から外へのアクセス(アウトバウンド通信)は可能だが、外部から家庭内への直接アクセス(インバウンド通信)はできなくなった。
IPv6アドレスがあるじゃろ?って?
IPv6アドレスの場合は全ノードにユニークなアドレスが割り当てられるため、本来は双方向の通信(インバウンド/アウトバウンド)を行うことができる。 ただし現実には、Webサービスやゲーム、企業システムの多くがまだIPv6での接続を前提に設計されていない。 結果として「理屈の上ではIPv6で直接通信できるが、実際にはIPv4互換接続が必須」という状況が続いている。そこで、固定のグローバルIPアドレスを持つVPSを契約し、Tailscaleを用いて自宅の各ノードとVPNを構築する。そのうえで、VPSに届いた通信(パケット)をfirewalldでVPN経由に自宅ノードへ転送する設定を行えば、VPSを介して疑似的に自宅サーバーを公開することが可能となる。
手順
TailscaleでVPN構築
- Tailscale公式サイトで新規ユーザー登録を行う。
- 管理コンソールで「Add Device」→「Linux server」→「Generate install script」でインストール用スクリプトを取得する
- VPS(以降vps-gen01と呼称)と自宅サーバー(以降home-gen01)にそれぞれインストールを行う。
- Tailscale管理コンソールで各ノード名やIPアドレスが表示されるようになれば構築完了です。
それぞれのノードで異なるインストール用スクリプトを実行する必要がある。
firewalldでポートフォワーディング(DNAT)設定
vps-gen01でfirewalldをインストールする。
sudo apt install firewalld
カーネルでIP転送有効化 & マスカレード設定する。
sudo sysctl -w net.ipv4.ip_forward=1
sudo firewall-cmd --permanent --zone=public --add-masquerade
ポートフォワーディング設定を行う。
今回の場合、80/tcpを転送する。
sudo firewall-cmd --permanent \
--add-forward-port=port=80:proto=tcp:toport=80:toaddr=100.120.69.33
firewalldはデフォルトでは22、546ポート以外をクローズにしてしまうため、80ポートを開放する必要がある。
80/tcpの通信を許可する。
sudo firewall-cmd --permanent --add-port=80/tcp
設定反映
sudo firewall-cmd --reload
設定一覧を表示する。
sudo firewall-cmd --zone=public --list-forward-ports
ncテスト通信
home-gen01にnetcatインストールをする。
sudo apt install netcat-openbsd
home-gen01で80ポートで接続を待ち受けする。
sudo nc -l -p 80
80ポートは特権ポートのため、sudoで実行する。
その後、edgeやchromeで以下URLで通信。
http://サーバーIP:ポート番号
下記画像のようなHTTPリクエストの通信を受信できればテスト通信は成功。

最後に
近年、光回線やCATV回線は IPoE 方式が主流となり、一部のプロバイダや通信事業者ではデフォルトの接続方式として採用されている。たしかに通信のボトルネックがなく、PPPoE 方式に比べて高速である点は大きな利点だ。
しかし、自宅サーバーを運用する立場からすると、グローバル IPv4 アドレスが割り当てられないのは大きな問題となる。
今回紹介した方法であれば、回線の種類に依存せず、固定 IP アドレスやダイナミック DNS といったオプションサービスも不要になる。月額 800 円前後の RAM 2GB クラスの軽量 VPS を用意すれば、Web サイトだけでなく、ゲームサーバーやファイルサーバーの公開も可能になる。

