VPN(L2TP/IPsec)サーバの設定

ALL
スポンサーリンク

2018.5.3 更新
2019.5.29 更新

VPN(L2TP/IPsec)サーバの構築方法です。
OpenVPN の場合は、次の記事です。

OpenVPNで ID/パスワード認証する パソコン鳥のブログ
OpenVPNの設定(通信をVPNサーバ経由にする設定も) パソコン鳥のブログ

スポンサーリンク

ここで構築するVPN

・VPNサーバは CentOS6/7
・VPNサーバのVPN側アドレスは 192.168.11.99
・VPNクライアントのアドレスは 192.168.11.128-192.168.11.254
・VPN接続後、クライアントの全ての通信は VPNサーバ経由で行われます。
・VPNの暗号化は事前共有鍵方式、ユーザ/パスワードは、サーバ内のファイルで指定
・VPNクライアント同士は接続できません
・Windows,スマホ(Android)から接続可能(iOS10も可能なはずですが未確認です)

必要パッケージのインストール

初めにEPELリポジトリを使用できるようにします。
次の記事の手順をおこなってください。

CentOS6/7でEPELリポジトリを利用する設定 パソコン鳥のブログ

必要パッケージをインストールします。

yum --enablerepo=epel install xl2tpd
yum install libreswan

l2tpの設定

次の個所を修正します。

/etc/xl2tpd/xl2tpd.conf

ip range = 192.168.11.128-192.168.11.254
local ip = 192.168.11.99

ip range : VPNクライアントに割り振られるIPアドレス
local ip : VPNサーバに割り当てるIPアドレス

ここで設定するIPアドレスは、VPNサーバで使用しているアドレスとは異なるサブネットにする必要があります。

次の各パラメータを設定します。

/etc/ppp/options.xl2tpd

ms-dns  8.8.8.8
#crtscts
#lock
mtu 1358
mru 1358

ms-dns の行は、DNSサーバを指定します。
指定可能なDNSサーバがあれば、それを指定ます。
無い場合は、Google Public DNS である 8.8.8.8 を設定しておきます。

また、crtscts と lock をコメントアウトします。
コメントアウトしないと、xl2tpが起動に失敗します。

mtu , mru は、ここではとりあえず 1358 を指定します。

ネットワーク上を流れるパケットは、MTU と呼ばれる一定サイズに分割されています。
VPN では、このパケットに加えて、VPN用のヘッダー(IPsec等のヘッダー)が付加されます。

この VPN用のヘッダーが付いたパケットのサイズが MTU を超えると、通信効率が悪くなります。
そこで、大方のネットワークの MTU より 小さくなる値が、先の値 1358 です。
この値を指定しておけば、多くのネットワークで問題ないでしょう。

次の各パラメータを追加します。

/etc/ppp/options.xl2tpd

refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
name xl2tpd

これらの設定は、認証方式 MSChap-v2 のみを許可しています。

name の値は、自由に設定してもOKです。
ここで指定した name の値は、後述の /etc/ppp/chap-secrets で使用します。

VPN接続時に要求されるユーザID、パスワードを次のファイルに設定します。
複数ユーザIDを用意する場合は、複数行記述します。

/etc/ppp/chap-secrets

user          xl2tpd        "pass"  *

user の個所にユーザ名、pass にダブルクォーテーションでくくったパスワードを指定します。
xl2tpd の個所は、先述の options.xl2tpd ファイルの name で指定した値を記述します。
最後の * は接続可能なアドレスを指定する個所ですが、どこからでも接続可能にするために * を指定しています。

管理者以外は見えないようにします。

chmod 600 /etc/ppp/chap-secrets

IPsec の設定

次のファイルの virtual_private で列挙されているネットワークアドレス以外を、xl2tpd.conf の ip range パラメータで指定していた場合は、virtual_private に追加します。
今回の例では、xl2tpd.conf で記述した 192.168.11.128-192.168.11.254 は、192.168.0.0/16 内なので、このままにします。

/etc/ipsec.conf

virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10

次のファイルを、次の内容で新規作成します。

/etc/ipsec.d/l2tp-ipsec.conf

conn L2TP-PSK-NAT
  dpddelay=10
  dpdtimeout=20
  dpdaction=clear
  rightsubnet=0.0.0.0/0
  forceencaps=yes
  also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
  authby=secret
  pfs=no
  auto=add
  keyingtries=3
  rekey=no
  ikelifetime=8h
  keylife=1h
  type=transport
  left=%defaultroute
  leftprotoport=17/1701
  right=%any
  rightprotoport=17/%any

以下は l2tp-ipsec.conf の設定の詳細ですが、読み飛ばしても構いません。
その場合は、後述の default.secrets の個所から進めて下さい。

パラメータに left~ と right~ がありますが、remote/local やサーバ/クライアントの設定というような位置づけです。
left~ と right~ をつなげる、という認識でOKです。

left,right のどちらが remote/local や サーバ/クライアント かは決まりはありません。
leftprotoport/rightprotoport でポート番号を記述した方が、サーバと考えて下さい。

今回の例では、left~ がサーバ側の設定、right~がクライアント側の設定です。

一部のパラメータについて以下に説明します。
conn の行は、conn セクション名 の書式です。セクション名は自由に決めてOKです。

conn L2TP-PSK-NAT
  rightsubnet=0.0.0.0/0
    どこからでも接続できるようにする。right側(クライアント側)がNAT環境でも可。
  
  forceencaps=yes
      ESP プロトコルを強制的にカプセル化するかどうかの指定で、yes にしておきます。
  also=L2TP-PSK-noNAT
      also=セクション名 の書式で、指定されたセクション名のパラメータがセットされる。
      この例では、conn L2TP-PSK-noNAT で記述されている内容をセットします。
conn L2TP-PSK-noNAT
  authby=secret
    共有秘密鍵方式を指定する
  
  pfs=no
    PFS(Perfect Forward Security)は相手側がIKEv1が使えることが前提であるため、ここではnoを指定しておく。
  
  auto=add
    IPsec接続で、自動キーリングで接続待ちで起動する。
    VPNサーバとして起動するので、addを指定。
  
  type=transport
    IPsecのモードを指定する。ホスト間で接続するので transport を指定する。
  
  left=%defaultroute
    サーバ側なので %defaultroute を指定する。%defaultroute で、サーバのデフォルトルートインタフェースのIPアドレスが指定される。
  
  leftprotoport=17/1701
    プロトコル番号17番(UDP)、ポート番号 1701 を指定する。
  
  right=%any
    クライアント側なので、IPアドレスは何でもOKにするために %any を指定する。
  rightprotoport=17/%any
    プロトコル番号17番(UDP)、クライアント側なので、ポート番号は何でもOKにするために %any を指定する。

VPN接続時に使用する、事前共有鍵を、ファイル default.secrets に設定します。
下記の PSKで事前共有鍵方式であることを指定しています。
“test” の個所が事前共有鍵です。

/etc/ipsec.d/default.secrets

: PSK "test"

管理者以外は見えないようにします。

chmod 600 /etc/ipsec.d/default.secrets

Linuxカーネルパラメータの設定

VPN接続が可能になるように、ネットワークに関するカーネルパラメータを設定します。

/etc/sysctl.conf の末尾に以下の内容を追加します。
以下で enp0s3 や eth0 の個所は、各自の環境に合わせて下さい。

CentOS7の場合

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.enp0s3.accept_redirects = 0
net.ipv4.conf.enp0s3.send_redirects = 0
net.ipv4.conf.enp0s3.rp_filter = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.lo.send_redirects = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.ip_vti0.rp_filter = 0

CentOS6の場合

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.lo.send_redirects = 0

CentOS6/7 とも、次のコマンドで設定を反映します。

/sbin/sysctl -p

ファイアウォール設定

ファイアウォールの設定を行います。

CentOS7の場合
firewalld の設定を行います。iptables を使用している場合は、”CentOS6/iptablesの場合” の方の作業を行ってください。

2019.5.29 追記
下記ルール の FORWARD の個所を追加しました。
このようにしないと、VPNクライアント同士が通信可能でした。

firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 1 -i ppp+ -o ppp+ -j DROP
firewall-cmd --permanent --add-service=ipsec
firewall-cmd --permanent --add-port=1701/udp
firewall-cmd --permanent --add-port=4500/udp
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload

CentOS6/iptablesの場合
/etc/sysconfig/iptables の –dport 22 の次の行あたりに、以下の内容を追加します。

2018.5.3 追記
下記ルールに -I INPUT -i ppp+ -j ACCEPT を追加しました。
VPNサーバがWEBサーバ等の場合、VPNサーバ自身に接続する場合に必要です。

2019.5.29 追記
下記ルールに「-A FORWARD -i ppp+ -o ppp+ -j DROP」を追加しました。
このようにしないと、VPNクライアント同士が通信可能でした。
また、誤ったフィルタ(ACCEPT_FILTER)を正しく(ACCEPT)訂正しました。

*filter
-A INPUT -p esp -j ACCEPT
-A INPUT -p ah -j ACCEPT
<del>-A INPUT -p udp -m udp --dport 1701 -j ACCEPT_FILTER
-A INPUT -p udp -m udp --dport 500 -j ACCEPT_FILTER
-A INPUT -p udp -m udp --dport 4500 -j ACCEPT_FILTER</del>
-A INPUT -p udp -m udp --dport 1701 -j ACCEPT
-A INPUT -p udp -m udp --dport 500 -j ACCEPT
-A INPUT -p udp -m udp --dport 4500 -j ACCEPT
-I INPUT -i ppp+ -j ACCEPT
-A FORWARD -i ppp+ -o ppp+ -j DROP
-A FORWARD -i ppp+ -j ACCEPT
-A FORWARD -o ppp+ -j ACCEPT
*nat
-A POSTROUTING -s 192.168.11.128/25 -j MASQUERADE

設定を反映させます。

/etc/init.d/iptables restart

起動設定・確認

CentOS7の場合
systemctl enable xl2tpd
systemctl enable ipsec
systemctl restart ipsec
systemctl restart xl2tpd
CentOS6の場合
/etc/init.d/ipsec restart
/etc/init.d/xl2tpd restart

設定を確認します。

次のコマンドを実行し、出力結果に FAILED が無ければOKです。

ipsec verify

以上、VPNサーバの設定でした。

これで、Windows,スマホ(Android)から接続可能(iOS10も可能なはずですが未確認)です。

Windows,スマホ(Android)での接続方法が不明な場合は、次回に説明します。

参考

FreeS/WANによるIPSECサーバの構築
【Linux】CentOS7でVPN(L2TP/IPsec)サーバーを構築してみる | Happy Life Hacking
linuxでVPNサーバ – Qiita
CentOS7でl2tp方式のVPNサーバーを建てる – Qiita
iOS10からPPTPが非対応になったのでCentOSでVPNサーバを作ってみた | 蒲田ネット
ipsec.conf(5): IPsec config/connections – Linux man page
iptablesにVPN用記述を追記するのを忘れてた | Scribble
L2TP/IPsec(AndroidやiPhoneからのVPN接続)を経路を用意すべくVPSにL2TP/IPsecサーバを設置するとき、ネットにある情報だとなかなかつながらないから、標準環境としてAWSのCentOS 6.3 x86_64 Release Media(ami-3fe8603e)の起動直後から最短距離で設定する方法をまとめた。 · GitHub
VPN接続後、ローカルのデフォルト ゲートウェイを利用したい場合の対処法 – 元「なんでもエンジニ屋」のダメ日記
IPsec L2TP VPN サーバ – Gentoo Wiki
openswanでIPsec VPN(トランスポート・X.509認証) [Fedora14]
IPsecの基礎知識を身につけつつ、AWSのVPN接続設定を読む – Qiita
VPNガイダンス:IPsecとは?
suz-lab – blog: Openswanの”ipsec.conf”の”auto”
CentOS7 VPNサーバ構築 L2TP/IPSec

コメント