WireGuardでVPN環境を構築したけど、外出先から自宅のLAN内にアクセスできない。
解決方法を教えて欲しい。
こんなお悩みを解決します。
今回は、VPS+DockerによりWireGuard環境を構築している前提で話を進めます。
VPSを利用したい方やDockerによるWireGuard環境の構築方法を知りたい方は、以下の記事を参考にしてください。
【解説】VPS+VPN(WireGuard)による自宅サーバの公開方法を分かりやすく解説!(VPS契約編)
続きを見る
【解説】VPS+VPN(WireGuard)による自宅サーバの公開方法(VPN設定編)
続きを見る
外出先から自宅のLAN内へのアクセス方法について、必要な設定を順番に解説していきますので、興味がある方はぜひ最後までご覧ください。
現状整理と対応方針
現状のネットワーク構成を再確認した上で、今回のお悩みに対する対応方針を解説します。
現状整理
現状、以下のような形で、VPN Serverに対し、VPN Client(スマホ、自宅サーバ1)が接続できている状態を前提とします。
補足となりますが、VPS(VPN Server)のiptablesの設定として、以下を追加することで、クライアント同士の通信が行えるようになります。
iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
対応方針
対策として、以下の2点を実施し、自宅のLAN内へアクセスする方法を解説します。
- VPS(VPN Server)と自宅サーバ1(VPN Client2)間の通信をアドレス変換により、取り次ぎます。
- 自宅サーバ1(VPN Client2)をLAN内のネットワークにも所属させ、LAN内へのアクセスを可能にします。
イメージを持ってもらうために、スマホ(VPN Client1)、VPS(VPN Server)、自宅サーバ1(VPN Client2)間の通信内容を図解しました。
上記のうち、VPS(VPN Server)と自宅サーバ1(VPN Client2)のそれぞれで、アドレス変換による通信の取次ぎを行います。
構築するネットワークの全体構成
最終的なネットワークの全体構成は、以下のようになります。
上記の図だけでは、通信イメージがしづらいと思うので、スマホから自宅サーバ2のNginx(192.168.11.2:80)にアクセスした場合を例に取り上げ、解説します。
事例イメージ:スマホから自宅サーバ2のNginxまでの経路
スマホからリクエストを出した後、Nginxに届くまでの経路は以下のようになります。
まず、スマホ(VPN Client1)からVPS(VPN Server)にリクエストが届きます。
次に、VPS(VPN Server)で、届いたリクエストに対するアドレス変換を行い、自宅サーバ1(VPN Client2)に転送します。
最後に、自宅サーバ1(VPN Client2)からLAN内の通信を経て、Nginx(192.168.11.2:80)にリスエストの処理を依頼します。
以上のステップを経て、スマホからNginxに向けてリクエストを流すことができます。
以降では、実際にiptablesを修正し、上記を実現する方法について解説します。
事前準備
今回もDockerを用いて環境構築を行っていきます。
Dockerの環境構築がまだの方は、以下の記事を参考にセットアップを済ませておいてください。
【解説】VPS+VPN(WireGuard)による自宅サーバの公開方法(VPN設定編)
続きを見る
環境構築の詳細
今回は、以下の条件で環境構築を行います。
カテゴリ | 項目 | 値 |
---|---|---|
スマホ(VPN Client1) | VPN ClientのIPアドレス | 10.1.2.4 |
VPS(VPN Server) | VPN ServerのIPアドレス | 10.1.2.1 |
自宅サーバ1(VPN Client2) | VPN ClientのIPアドレス | 10.1.2.3 |
VPN Server経由で通信するIPアドレス(Docker ContainerのIPアドレス) | 10.0.20.2 | |
Nginx(Web) | LAN内でのIPアドレス | 192.168.11.2 |
待ち受ける際のポート番号 | 80 |
VPS(VPN Server)の設定更新
ここでは、以下の2点に対応し、VPN Serverの設定を更新します。それぞれ順に説明していきます。
- VPN Server構築時の環境変数(WireGuard)の追加・更新を行う。
- iptablesを設定する。
また、該当するコードは、GitHubの下記に保存してあります。git clone
して利用してください。
https://github.com/yuruto-free/vpnaccess-wireguard-nginx/tree/v0.2.0
環境変数の追加・更新
環境変数としてSERVER_ALLOWEDIPS_PEER_LocalServer
を追加し、PEERS
を修正します。
追加・修正後のenvs/wireguard/.env
は以下のようになります。
SERVERURL=example.vpn.com
SERVERPORT=51820
PEERS=PublicServer,LocalServer,myPhone # ←修正箇所
PEERDNS=8.8.8.8,10.1.2.1
INTERNAL_SUBNET=10.1.2.0/24
MTU=1380
KEEP_ALIVE=10
ALLOWEDIPS=10.1.2.0/24
SERVER_ALLOWEDIPS_PEER_PublicServer=10.0.16.0/24
SERVER_ALLOWEDIPS_PEER_LocalServer=10.0.20.0/24 # ←追加箇所
iptablesの設定
wireguard/iptables_script
に移動し、conf.up.d
とconf.down.d
にアドレス変換用の設定ファイルを作成し、保存します。
この設定が間違っていると通信できないため、環境に合わせて設定する際は十分注意してください。
ただ、全体像のイメージがつかめないと設定もしづらいと思うので、これから設定する内容を図解したいと思います。
まず、アドレス変換の全体像は以下のようになります。
そして、VPS(VPN Server)では、次のようなアドレス変換を行うことになります。
項目 | IPアドレス | ポート番号 |
---|---|---|
変換前 | 192.168.11.2/32 | 80/tcp |
変換後 | 10.0.20.2/32 | 80/tcp |
conf.up.dに格納するconfファイルの内容
「アドレス変換による対応表」の内容をiptablesの設定コマンドで表現すると以下のようになります。
iptables -t nat -A PREROUTING -p tcp -d 192.168.11.2/32 --dport 80 -j DNAT --to-destination 10.0.20.2:80
後は、10.0.20.2/24に対するIP Masqueradeの設定も含めたコマンドをconf.up.d/02-routing-lan-access.conf
に保存します。
この段階で、conf.up.d/02-routing-lan-access.conf
は以下のようになっていることを確認してください。
iptables -t nat -A PREROUTING -p tcp -d 192.168.11.2/32 --dport 80 -j DNAT --to-destination 10.0.20.2:80
iptables -t nat -A POSTROUTING -d 10.0.20.0/24 -j MASQUERADE
conf.down.dに格納するconfファイルの内容
conf.down.dは、ルール削除時のコマンドを記載すればよいので、以下の内容をconf.down.d/02-routing-lan-access.conf
に保存します。nat -D
となっている点に注意!
iptables -t nat -D PREROUTING -p tcp -d 192.168.11.2/32 --dport 80 -j DNAT --to-destination 10.0.20.2:80
iptables -t nat -D POSTROUTING -d 10.0.20.0/24 -j MASQUERADE
VPS(VPN Server)側で必要な設定は以上となります。
VPN Serverの起動
下記のコマンドを実行し、VPN Serverを起動します。
./wrapper.sh start
問題なく起動したら、下記のコマンドを実行し、先ほど追加したコードが出力されていることを確認してください。
./wrapper.sh logs
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE; iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
[#] /config/iptables_script/postup.sh
[#] - /config/iptables_script/conf.up.d/01-forwarding-to-public-server.conf
[#] iptables -t nat -A POSTROUTING -d 10.0.16.0/24 -j MASQUERADE
[#] - /config/iptables_script/conf.up.d/02-routing-lan-access.conf
[#] iptables -t nat -A PREROUTING -p tcp -d 192.168.11.2/32 --dport 80 -j DNAT --to-destination 10.0.20.2:80
[#] iptables -t nat -A POSTROUTING -d 10.0.20.0/24 -j MASQUERADE
また、同時にwireguard/peer_LocalServer/peer_LocalServer.conf
、wireguard/peer_myPhone/peer_myPhone.conf
というファイルが生成されていると思います。
それぞれ、VPN Client1(peer_myPhone.conf
)、VPN Client2(peer_LocalServer.conf
)で利用します。
スマホ(VPN Client1)の設定
スマホにWireGuardのアプリをインストールしてください。
そして、PC上でpeer_myPhone.conf
を開き、下記を修正します。
[Interface]
Address = 10.1.2.4
PrivateKey =
ListenPort = 51820
MTU = 1380
DNS = 8.8.8.8,10.1.2.1
[Peer]
PublicKey =
PresharedKey =
Endpoint = example.vpn.com:51820
AllowedIPs = 10.1.2.0/24,192.168.11.0/24 # ← 192.168.11.0/24を追加
PersistentKeepAlive = 10
上記の変更により、192.168.11.0/24にアクセスする際はVPNを用いて接続することとなります。
後は、メールやNAS経由で上記の設定ファイルをスマホに送り、アプリ側から読み込みます。
自宅サーバ1(VPN Client2)の設定
自宅サーバ1(VPN Client2)では、以下のコードを利用します。git clone
して利用してください。
https://github.com/yuruto-free/wireguard-local-access-client/tree/v0.2.0
ここでは、以下の2点に対応し、自宅サーバ1(VPN Client2)の設定を更新します。それぞれ順に説明していきます。
peer_LocalServer.conf
の内容を修正し、conf/wg0.conf
として保存する。- iptablesの設定をする。
注意点
上記のGitHubに格納しているdocker-compose.ymlの設定には、Dockerのversionが20.10.0以降でないと利用できないコードが含まれています。
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
# 中略
extra_hosts:
- "host.docker.internal:host-gateway" # ←この部分
Dockerのversion20.10.0以前を利用している方は、docker-compose.ymlを以下のように修正してください。
version: '3.7'
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Tokyo
networks:
backbone:
ipv4_address: 10.0.20.2
volumes:
- /lib/modules:/lib/modules
- ./config:/config
restart: always
extra_hosts:
- "host.docker.internal:10.0.20.1" # ←変更箇所
networks:
backbone:
name: backbone
driver: bridge
ipam:
driver: default
config:
- subnet: 10.0.20.0/24
configファイルの格納・修正
wireguard-local-access-client
直下にconfig
というディレクトリがあります。
このconfig直下に
の内容をpeer_LocalServer
.confwg0.conf
というファイル名で保存します。
その後、wg.conf
のInterface
の末尾に、以下の2行を追加します。
これは、VPS(VPN Server)で設定したものと同じように、iptablesを修正するために必要になります。
PostUp = /config/iptables_script/postup.sh
PostDown = /config/iptables_script/postdown.sh
上記の修正を行うと、config/wg0.conf
の内容は、以下のようになります。
[Interface]
Address = 10.1.2.3
PrivateKey =
ListenPort = 51820
MTU = 1380
DNS = 8.8.8.8,10.1.2.1
PostUp = /config/iptables_script/postup.sh # 追加部分
PostDown = /config/iptables_script/postdown.sh # 追加部分
[Peer]
PublicKey =
PresharedKey =
Endpoint = example.vpn.com:51820
AllowedIPs = 10.1.2.0/24
PersistentKeepAlive = 10
iptablesの設定
config/iptables_script
に移動し、conf.up.d
とconf.down.d
にアドレス変換用の設定ファイルを作成し、保存します。
この設定が間違っていると通信できないため、環境に合わせて設定する際は十分注意してください。また、VPS(VPN Server)側で設定した内容と揃える必要があるので、十分注意してください。
先ほど記載した、アドレス変換の全体像を再掲します。
そして、自宅サーバ1(VPN Client2)では、次のようなアドレス変換を行うことになります。
項目 | IPアドレス | ポート番号 |
---|---|---|
変換前 | 10.0.20.2/32 | 80/tcp |
変換後 | 192.168.11.2/32 | 80/tcp |
conf.up.dに格納するconfファイルの内容
「アドレス変換による対応表」の内容をiptablesの設定コマンドで表現すると以下のようになります。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.11.2:80
ここで、-d 10.0.20.2
がないのは、送信元が必ず10.0.20.2
になるためです。
後は、192.168.11.0/24に対するIP Masqueradeの設定も含めたコマンドをconf.up.d/02-routing-lan-access.conf
に保存します。
この段階で、conf.up.d/02-routing-lan-access.conf
は以下のようになっていることを確認してください。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.11.2:80
iptables -t nat -A POSTROUTING -d 192.168.11.0/24 -j MASQUERADE
conf.down.dに格納するconfファイルの内容
conf.down.dは、ルール削除時のコマンドを記載すればよいので、以下の内容をconf.down.d/02-routing-lan-access.conf
に保存します。nat -D
となっている点に注意!
iptables -t nat -D PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.11.2:80
iptables -t nat -D POSTROUTING -d 192.168.11.0/24 -j MASQUERADE
自宅サーバ1(VPN Client2)側で必要な設定は以上となります。
VPN Client2の起動
下記のコマンドを実行し、VPN Client2を起動します。
chmod +x wrapper.sh
./wrapper.sh start
問題なく起動したら、下記のコマンドを実行し、先ほど追加したコードが出力されていることを確認してください。
./wrapper.sh logs
[#] /config/iptables_script/postup.sh
[#] - /config/iptables_script/conf.up.d/02-routing-lan-access.conf
[#] iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.11.2:80
[#] iptables -t nat -A POSTROUTING -d 192.168.11.0/24 -j MASQUERADE
動作確認
スマホのWebブラウザから、Nginxが起動しているサーバのIPアドレスを入力し、LAN内で起動しているWebサーバのトップページが表示されることを確認してください。
今回の例では、以下のようになります。環境が全く同じでない限り、コチラにアクセスしても期待通りの結果は得られません。気を付けてください。
http://192.168.11.2
まとめ
今回の実装は、下記のリンク先を参考にしてください。
VPS(VPN Server)側の実装
https://github.com/yuruto-free/vpnaccess-wireguard-nginx/tree/v0.2.0
自宅サーバ1(VPN Client2)側の実装
https://github.com/yuruto-free/wireguard-local-access-client/tree/v0.2.0
注意点
上記を動作させる際は、環境変数の設定が必要になります。詳細は、同封されているREADME.md
または以下を参照してください。
制約事項
今回は、LAN内で起動しているサーバのIPアドレスやポート番号を仮置きした上で、解説しました。
実際に稼働しているサーバのIPアドレスやポート番号は、各々の環境に合わせて読み替えてください。
【追記】トラブル事例をまとめました。
【トラブル事例】VPS+VPN(WireGuard)で接続できない時の解決方法
続きを見る