ラズパイでVPNを構築しよう

Linux
スポンサーリンク

はじめに

こんにちは!過去の記事で少し触れていましたが、前々から外から家の中のパソコンを使いたいなーと思っていろいろやっております。

PCを電源ボタン押さずに念力(ラズパイ)で起動させてみた
はじめに 前回の記事から引き続きラズパイ回となります。 実は前々からやりたいことがありまして、それは外から家のパソコンを使うということ。今回は、そのためにローカルでパソコンの電源のオンとオフを行えるようにしましたので紹介します。 なお電源の...

上記の記事では、パソコンをローカルから起動させるということを行いました。今回は外部のネットワークからローカルのネットワークにアクセスしたいということで仮想プライベートネットワーク(VPN:Virtual Private Network)を構築しましたのでその紹介をします

IPアドレスなどの設定について

解説のためにネットワークは次のようになっているとします。

VPNサーバーのグローバルIPアドレス hoge.natade.net (変動IPアドレスのためDDNSで設定済み)
VPNサーバーのローカルIPアドレス 192.168.11.101/24
VPN上のVPNサーバーのアドレス 10.20.30.1/24
クライアント1のVPN上のアドレス 10.20.30.2/24
クライアント1のローカルIPアドレス 192.168.200.10/24
クライアント2のVPN上のアドレス 10.20.30.3/24
クライアント2のローカルIPアドレス 192.168.200.11/24

図で説明するとこんな感じです。ちょっとネットワーク環境の事情がややこしいです。

VPNを構築する(サーバー)

サーバーを準備する

今回は、サーバーにRaspberry Pi 4を使用してみます。まだまだ高いのですが、販売サイトの中で最も安かった秋月電子で以下の製品を購入しました。

さらに、ケースやSDカードも購入します。ケースはファンの掃除を行わなくてもいいファンレスを選択。

SDカードは書き換え可能回数が多そうなドライブレコーダー対応と記載されたものを選択しました。

OS及び基本ソフトを入れる

サーバーに以下のようにOSを入れます。今回は Raspbian 64bit のCUI版を入れました。

久しぶりに Raspberry Pi をセットアップしたら超楽になっていた
はじめに これまで何度も Raspberry Pi をセットアップしてきたのですが、久しぶりに行おうとしたら圧倒的に楽になっていたので、紹介もかねて記事にしました。 今回は、なんと次のような制約でセットアップを進めていきます。 Raspbe...

セキュリティ対策を行う

世界にサーバーを公開するためセキュリティ対策を行う必要があります。

fail2ban

外部から不正にアクセスがあったときに自動でBANするアプリfail2banを入れます。

sudo apt-get install fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

/etc/fail2ban/jail.localを新規作成して設定を書き込みます。私は次のように設定しました。

[DEFAULT]
# BAN除外
ignoreip = 127.0.0.1/8 192.168.0.0/16 10.20.30.1/24

# バンする時間(1年)
bantime = 8760h

# 監視スパン(600秒)
findtime = 600

# 最大パスワード失敗回数(デフォルト5回)
maxretry = 3

# SSHD のBANを有効化
[sshd]
enabled = true

# 再発した場合は重くする
[recidive]
enabled = true

SSHのログイン情報は/var/log/auth.log、BANの状況は/var/log/fail2ban.logのログから確認が行えます。

実際にBANされたIPアドレスは以下から確認が可能です。

sudo fail2ban-client status sshd

unattended-upgrades

自動的にOSをアップデートするソフトunattended-upgradesを入れます。

sudo apt install unattended-upgrades

/etc/apt/apt.conf.d/50unattended-upgradesを編集して設定を変更します。

すべてのファイルを更新対象にしました。

Unattended-Upgrade::Origins-Pattern {
	"o=*,a=*";
};

他に以下の設定は有効にしました。

// 自動的にインストールされた未使用のカーネル関連パッケージの削除する
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

// アップグレード後、新たに使用されなくなった依存関係を自動削除する。
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";

// アップグレード後に未使用のパッケージを自動削除する。
Unattended-Upgrade::Remove-Unused-Dependencies "true";

// アップグレード時にリブートが必要な場合にリブートする
Unattended-Upgrade::Automatic-Reboot "true";

// 自動リブート有効時にユーザーがログイン中であってもリブートする
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";

// 自動リブート有効時にいつリブートするか
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

IPアドレス、ポート開放、DDNSの設定をする

ラズパイのIPアドレス固定します。ここでは説明のために、ラズパイのIPアドレスを192.168.11.101とします。IPアドレスの固定方法は、ラズパイのsudo nano /etc/dhcpcd.confを編集するか、DHCPサーバー側で指定したMACアドレスに固定IPアドレスを割り振るといった機能などで設定してください。

次に外から、ラズパイにアクセスできるように、SSHとVPNのポート開放をします。今回は以下のポートを開けておきます。ポート開放した瞬間にあらゆるIPアドレスからSSHでログインしてこようとするので必ず、ユーザー名を設定し、パスワードは推測されないようなものにしてください。

  • SSH用
    • TCP:22
  • VPN(WireGurad)用
    • UDP:51820

次に外部からアクセスしやすいようにダイナミックDNSの設定もしておきます。今回はhoge.natade.netとしました。このあたりの話は以下の過去の記事にも記載があるので分からない場合は読んでみてください。

VPNサーバーを入れる

pivpn のインストール

pivpnを用いてWireGuardを導入します。pivpnはRaspbian用ではありますが、Ubuntuでも動作します。

curl -L https://install.pivpn.io | bash

VPNサーバーを選択する際はWireGuardを選択してください。適当に設定していけば設定できます。

  • IPアドレスの質問
    • すでに上記でIPアドレスを固定化済みなのでDHCPの選択をしておくとよい。おそらくIPアドレスを固定化したい場合、ここでも設定が行えるものだと思われる。
  • ポートの設定
    • デフォルトの51820を選択する、
  • DNS Provide の設定(サーバーが名前解決するときに使う設定)
    • Googleの8.8.8.8を選択する。選択項目にない場合は下にスクロールすると出てくる。
  • Public IP or DNS
    • VPNクライアントが接続先のVPNサーバーのIPアドレスを設定するときに使うアドレス。外部からアクセスできるようにhoge.natade.netを指定する。後述のようにVPNクライアントを追加する際に「~/configs/*.conf」が作成されるのですが、ここで設定したアドレスが自動設定されます。

参考サイト

ラズパイダ – ラズパイとPiVPNで、手軽にVPNサーバーを手に入れる

ブリッジの設定

VPNサーバーを設置するネットワーク内のインターフェースとブリッジ接続をする場合は次のように、/etc/wireguard/wg0.confの設定のInterfaceに、PostUpPostDownの設定します。

sudo nano /etc/wireguard/wg0.conf
--------------------------------------
[Interface]
PrivateKey = xxx
Address = 10.20.30.1/24,1234:567:89a:bcde::1/64
MTU = 1420
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -A POSTROUTING -s 10.20.30.0/24 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -D POSTROUTING -s 10.20.30.0/24 -j MASQUERADE
...
### begin client1 ###
[Peer]
PublicKey = ...

PostUpは起動時に実行される設定、PostDown は終了時に実行されます。この行を追加することで、eth0とプライベートネットワークをブリッジ接続します。wifiのデバイスと接続する場合は、eth0ではなくwlan0となります。(ifconfigで表示されるネットワークのデバイス名)

参考サイト

クライアントの設定用ファイルを作る

以下でVPNに参加するクライアントを追加できます。以下のコマンドを入力すると、~/configsのフォルダ内にクライアント設定用のclient1.confが作られます(ここでは説明用にclient1というユーザー名としています。)また今回は、client1とclient2の2つを作っておきたいと思います。

pivpn add --name client1
pivpn add --name client2

サーバーとクライアントにスタティックルートの設定を行う

WireGuardを導入した各端末でどのIPアドレスの場合に仮想ネットワークを経由させるかスタティックルートのように設定する必要があります(WireGuard公式サイトではCryptokey Routing Tableと呼んでいる)。デフォルトでも一応適当に設定はされていますが、指定したIPアドレスの場合に仮想ネットワークを使用して通信を行うといった設定が行えます。

設定を行うファイルは、/etc/wireguard/wg0.conf~/configs/*.confAllowedIPsの設定となります。ここで、色々な設定ファイルをいったん整理しておきます。

  • pivpnの設定
    • /etc/pivpn/wireguard/setupVars.conf
    • pivpn関係のコマンドpivpnで使用するwireguardの設定
    • デバイス名の設定、使用するポートの設定、DNSの設定、サーバーが使用するIPアドレスの範囲など
  • WireGuardのサーバー側のクライアントとの設定
    • /etc/wireguard/wg0.conf
    • サーバーはどのクライアントと接続するか、クライアントとの鍵の情報、どのIPアドレスの場合はどのクライアントへ通信が必要かの設定(AllowedIPs)など
    • pivpn add ****を実行するたびにクライアントの情報が追記される
  • WireGuardのクライアント用の設定
    • ~/configs/*.conf
    • クライアント側で設定する情報。サーバーとの鍵の情報、クライアント内部でどのIPアドレスの場合がVPNのネットワークを指しているかの設定(AllowedIPs)など
    • pivpn add ****を実行するたびに作成される

この中で今回設定するのは、AllowedIPsとなります。例えば、VPNサーバー側からは各VPNクライアントへアクセスする際は、そのIPアドレスの場合に対象へルーティングする必要がありますし、VPNクライアント側の目線からは、VPNサーバーのネットワークを通したいIPアドレス、例えばVPNサーバーがあるアドレス空間をIPアドレス/サブネットマスクのCIDR表記を設定する必要があります。

図で説明すると、以下のようになります。例えば、クライアント配下から、サーバーがあるネットワーク192.168.11.1/24​へアクセスできるように、クライアントのconfファイルのAllowedIPsに​設定しています。逆にAllowedIPsに設定しないIPアドレスへは、VPNを経由せずにアクセスするということになります。​

クライアント側の設定にキープアライブの設定を記載しておく

WireGuardは端末同士の接続後は、通信を明示的にしなければ通信が全くない状態を継続するため、クライアント側のNATが長期間通信しない接続のポートを閉じてしまいます。それを防止するために、/etc/wireguard/wg0.confの各Peer設定に、PersistentKeepalive = 25の設定します。この25秒という設定は公式サイトにも書かれている数値となります。

sudo nano ~/configs/client1.conf
​[Interface]
PrivateKey = xxx
Address = 10.20.30.10/24,1234:567:89a:bcde::2/64
DNS = 8.8.8.8, 8.8.4.4

[Peer]
PublicKey = xxx
PresharedKey = xxx
Endpoint = hoge.natade.net:51820
AllowedIPs = 10.20.30.1/24,1234:567:89a:bcde::2/64,192.168.11.101/24
PersistentKeepalive = 25

キープアライブをしないとサーバーからクライアントへ接続できなくなる理由はUDPのNAT超えを検索してみると分かります。

参考サイト

サーバーを有効化する

以下でVPNサーバーの連続稼働を有効化できます。

sudo systemctl enable wg-quick@wg0

設定変更後であれば、次で更新されます。

sudo systemctl restart wg-quick@wg0

サーバーの状態を確認する

サーバーでwgコマンドを実行することで各ピアー(クライアント)の状態を確認することが出来ます。

sudo wg

VPNを構築する(クライアント)

Raspbianの場合

Raspbianの場合は次のようにVPNクライアントを設定します。

クライアントソフトをインストールします。

sudo apt install wireguard

VPNサーバーで作成したclient1.confのファイルを以下のファイルと差し替えします。

/etc/wireguard/wg0.conf

以下で起動して連続稼働を有効化します。

sudo systemctl start wg-quick@wg0
sudo systemctl enable wg-quick@wg0

NAT塞ぎをふせぐ

ちょっとよくわかりませんが、Raspbianを再起動すると、NATが塞がって外部からアクセスできなくなることがあります。前述のPersistentKeepaliveを設定していれば問題ないと思いますが、それでは不安という方は、crontabで設定しておくと定期的なpingを実行するようにしておくと安心です。

sudo crontab -e

以下は、1日に1回リブート、10分に1回はWireGuradサーバーへPINGで開通させる設定となります。

0 2 * * * reboot
*/10 * * * * ping -c2 -W4 -qn 10.20.30.1

Windowsの場合

Installation – WireGuard からインストーラをダウンロードしてインストールします。

アプリを起動したら「ファイルからトンネルをインポート」を選択して、サーバー側で作成した「~/configs/client2.conf」を選択します。

あとは自動で接続が開始します。

ファイアウォールの解除

VPNのネットワーク空間からのアクセスについて、ファイアーウォールにかかる場合があるので、許可をしておくとよいです。

  1. Windows + R を実行
  2. wf.msc を入力
  3. 左のツリービューから「受信の規則」を選択
  4. 右側から「新しい規則」を選択
  5. 「カスタムの規則」を選択
  6. 「すべてのプログラム」を選択
  7. プロトコルの種類は「任意」を選択
  8. 「この規則を適用するリモートIPアドレスを選択してください」の欄に10.20.30.1/24を入力する。

おわりに

これでVPNの構成が終わりです。お疲れ様です。

それ以外の設定について

以下はそれ以外の設定について紹介していきます。

クライアントの全データを暗号化する

これまでの説明ではVPN内の特定のアドレスのデータのみを通信する方法をお伝えしました。ここでは、クライアントで行う通信を全てサーバーへ流しデータを暗号化する方法です。

サーバー側の設定

​サーバ側の設定にTable = offを追加します。この設定を入れることでクライアントがサーバーを踏み台にして外部へ通信することが可能になります。これがonのままだと自分のサーバー内にデータがループしてしまうそうです。

あとはクライアント側の通信を全て受け入れるように、0.0.0.0/0, ::/0と設定します。

[Interface]
PrivateKey = xxx
Address = 10.20.30.1/24,1234:567:89a:bcde::1/64
MTU = 1420
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -A POSTROUTING -s 10.20.30.0/24 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -D POSTROUTING -s 10.20.30.0/24 -j MASQUERADE
Table = off

...
### begin client1 ###
[Peer]
PublicKey = xxx
PresharedKey = xxx
AllowedIPs = 0.0.0.0/0, ::/0
### end client1 ###

クライアント側の設定

サーバー側への通信を0.0.0.0/0, ::/0と設定することで、全通信をサーバーを通すようにします。

[Interface]
PrivateKey = xxx
Address = 10.20.30.1/24,1234:567:89a:bcde::1/64
DNS = 8.8.8.8, 8.8.4.4

[Peer]
PublicKey = xxx
PresharedKey = xxx
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = hoge.natade.net:51820
PersistentKeepalive = 25

AllowedIPs で許可しないアドレスを指定する

WireGuardは許可するIPアドレスのAllowedIPsは指定できるものの、許可しないIPアドレスは設定機能がなく、DisallowedIPsのような指定は行えません。

ここで活用できるのが、WIREGUARD ALLOWEDIPS CALCULATORというツールです。

例えば、 0.0.0.0/0, ::/0の指定からクラスB(172.16.0.0/12)とクラスC(192.168.0.0/16)のプライベートアドレスはVPNから除外したいとした場合

AllowedIPs = 0.0.0.0/0, ::/0
DisallowedIPs = 172.16.0.0/12, 192.168.0.0/16

のように入力してCalculateを押すと次のように設定するべきアドレスが計算できます。

AllowedIPs = 0.0.0.0/1, 128.0.0.0/3, 160.0.0.0/5, 168.0.0.0/6, 172.0.0.0/12, 172.32.0.0/11, 172.64.0.0/10, 172.128.0.0/9, 173.0.0.0/8, 174.0.0.0/7, 176.0.0.0/4, 192.0.0.0/9, 192.128.0.0/11, 192.160.0.0/13, 192.169.0.0/16, 192.170.0.0/15, 192.172.0.0/14, 192.176.0.0/12, 192.192.0.0/10, 193.0.0.0/8, 194.0.0.0/7, 196.0.0.0/6, 200.0.0.0/5, 208.0.0.0/4, 224.0.0.0/3, ::/0

これを入力することで疑似的にDisallowedIPsの指定が可能となります。

コメント

タイトルとURLをコピーしました