追記: 2018/4/22
uRPFが失敗したパケットを拒否すると、VPNクライアントにもともとプライベートアドレスが割り当てられている場合に通信ができなくなります。これは困りますので、以下の行を設定から削除しました。

block in log quick from urpf-failed    # uRPFが失敗したパケットは拒否

L2TP編では、L2TPサーバMPDのインストールと設定を行ないました。strongSwanとMPDが起動している状態で、VPNクライアントからの接続が行なわれると、クライアント―サーバ間の安全な通信路であるL2TP/IPSecトンネルが確立します。

しかし、いまのままでは、クライアントはサーバとだけしか通信ができません。クライアントがサーバ越しにインターネットと通信を行なうためには、L2TP/IPSecサーバマシンがNAT (Network Address Translation)ルータとして振る舞う必要があります。

本記事では、サーバマシンをルータ兼ファイアウォールとして動作させるための設定を説明していきます。

ルータ

では、まずルータとしての設定を行ないます。

IPSec編のブロック図に示したとおり、VPNサーバはインターネットとつながる外側インターフェイス(vtnet0)を持っています。また、VPNクライアントからの接続があると、トンネルインターフェイス(ngX)がクライアントごとに作られます。クライアントがインターネットと通信するためには、VPNサーバがこれらのインターフェイス間でパケットの転送を行なう必要があります。

デフォルトでは、インターフェイス間のパケット転送機能はオフになっていますので、以下のコマンドを実行してIPv4パケットのフォワーディング(転送)機能を有効に設定します。今回はIPv6を使いませんので、IPv4パケットの転送機能のみ有効化します。

sysrc gateway_enable=YES    # IPv4パケット転送の有効化

ルータとしての設定は以上で終了です。

NAT・ファイアウォール

次に、NATとファイアウォールの設定をあわせて行ないます。

IPSec編のブロック図に示したとおり、VPNネットワークにはプライベートアドレスを割り当てました。プライベートアドレスに対しては、インターネットからパケットを送ることができません。つまり、いまのままでは、VPNクライアントからインターネットにパケットを送り出すことができても、それに対する返事が戻ってこないということです。

そこで、プライベートアドレスを、インターネットからのパケットの送り先になれるアドレス、つまりVPNサーバの外側インターフェイス(vtnet0)のアドレスに書き換えてからパケットを送信する必要があります。このアドレス書き換えをNATといいます。

OpenVPNサーバを構築した際は、NATとファイアウォールを別々のソフトウェアで実現しました。そのときにも一部で用いましたが、OpenBSD由来のファイアウォールであるPF (Packet Filter)にはNAT機能も含まれているので、今回はPFを用いて、NATおよびファイアウォールをまとめて実現したいと思います。

ファイアウォールのルール作成に際しては以下の三記事を参考にしました。

ルール作成の際のポリシーは以下のとおりとします。

上記のポリシーにしたがって作成した、PFの設定ファイルの内容を以下に示します。コメントをつけましたので参考にしていただければと思います。

設定ファイルを作成したら、以下のコマンドを実行して機能の有効化を行ないます。

sysrc pf_enable=YES

最後にFreeBSDマシンを再起動してすべて完了です。

参考文献

  1. OpenBSD PF - Building a Router, https://www.openbsd.org/faq/pf/example1.html
  2. Securing the PF Firewall, FreeBSD Server Guide, https://www.c0ffee.net/blog/freebsd-server-guide#pf
  3. FreeBSD 9.1をIPsec対応L2TP VPNサーバにする, https://oichinote.com/plus/2013/04/l2tp-vpn-server-in-freebsd-9-1.html