CentOS7 VPNサーバ構築 L2TP/IPSec

シェアする

外から接続をする際、自宅にあるルータ(BHR-4RV)のVPN(PPTP)を利用していましたが、PPTPベースのVPN接続は脆弱性もあるということなので、L2TP/IPSecにすることにしました。

脆弱性があるからと言って、自宅サーバ利用のデータに興味を持つ人なんていないと思いますけど。。。

VPN接続をするにあたり、L2TP単体でも実現できますが、暗号化されません。
そこで、L2TP/IPSecとの組み合わせで、通信経路を暗号化します。
とりあえず、これぐらいの知識があれば、定義ファイルも理解がしやすいと思います。

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

L2TP/IPsecの環境を作るには、3つのパッケージをインストールしますが、「xl2tpd」というパッケージは標準リポジトリにありませんので、「EPEL」からインストールします。

# yum info xl2tpd --enablerepo=epel <LF> <= L2TPのパッケージ
    :
Available Packages
Name        : xl2tpd
Arch        : x86_64
Version     : 1.3.6
Release     : 7.el7
Size        : 359 k
Repo        : installed
From repo   : epel
    :
# yum -y install xl2tpd --enablerepo=epel <LF>
   :
Installed:
  xl2tpd.x86_64 0:1.3.6-7.el7
 
Complete!
# yum info libreswan <LF> <= IPSecのパッケージ
    :
Available Packages
Name        : libreswan
Arch        : x86_64
Version     : 3.8
Release     : 6.el7_0
Size        : 883 k
Repo        : updates/7/x86_64
     :
# yum -y install libreswan <LF>
    :
Installed:
  libreswan.x86_64 0:3.8-6.el7_0
 
Dependency Installed:
  ldns.x86_64 0:1.6.16-7.el7
  libevent.x86_64 0:2.0.21-4.el7
  unbound-libs.x86_64 0:1.4.20-19.el7
 
Complete!
# yum info lsof <LF> <= lsofパッケージ(これがないと後でエラーになります)
    :
Available Packages
Name        : lsof
Arch        : x86_64
Version     : 4.87
Release     : 4.el7
Size        : 331 k
Repo        : base/7/x86_64
     :
# yum -y install lsof <LF>
    :
Installed:
  lsof.x86_64 0:4.87-4.el7
 
Complete!

L2TPの設定

L2TPの設定を行ないます。

# cp -p /etc/xl2tpd/xl2tpd.conf /etc/xl2tpd/xl2tpd.conf.original <LF>
# cat /dev/null > /etc/xl2tpd/xl2tpd.conf <LF>
# vim /etc/xl2tpd/xl2tpd.conf <LF> <= l2tpd定義ファイルの編集
[global]
; 認証情報の書かれたファイルを指定する
auth file = /etc/ppp/chap-secrets
; デーモンがリッスンしているインタフェースのIPアドレスを指定する
listen-addr = 192.168.1.101
 
[lns default]
; リモート接続のクライアントに割り振るIPアドレスの範囲を指定する
ip range = 192.168.1.11-192.168.1.20
; リモート接続のサーバに割り振るIPアドレス(xl2tpd自身のIPアドレス)を指定する
local ip = 192.168.1.100
; pppdの設定ファイルのパスを指定する
pppoptfile = /etc/ppp/options.xl2tpd
; L2TPパケットのペイロード(実データ)にあるビット長ヘッダーを確認する
length bit = yes
# cp -p /etc/ppp/options.xl2tpd /etc/ppp/options.xl2tpd.original <LF>
# cat /dev/null > /etc/ppp/options.xl2tpd <LF>
# vim /etc/ppp/options.xl2tpd <LF> <= pppd定義ファイルの編集
# リモート側にDNSアドレスを提供する
ms-dns 192.168.1.101
ms-dns 192.168.1.1
# CCP(圧縮制御プロトコル)を無効にする
noccp
# リモート側に認証を求める
auth
# IPパケットの無通信時間(秒)を過ぎた時に切断する
idle 1800
# MTU(最大転送単位)値を指定する(サンプルの値をそのまま指定)
mtu 1410
# MRU(最大受信単位)値を指定する(サンプルの値をそのまま指定)
mru 1410
# リモート側接続をデフォルトゲートウェイとして経路追加しない
nodefaultroute
# シスログに接続のデバッグ情報を出力する
debug
# 代理ARPを有効にする(リモート接続のIPがローカルネットワークにあるように見える)
proxyarp
# 認証のために使用するローカルシステム名(何でも良いが認証情報ファイルで合わせる必要あり)を設定する
name xl2tpd
# 認証でのPAPは拒否する
refuse-pap
# 認証でのCHAPは拒否する
refuse-chap
# 認証でのMS-CHAPは拒否する
refuse-mschap
# 認証でのMS-CHAPv2を許可する
require-mschap-v2
# vim /etc/ppp/chap-secrets <LF>
"UserName"    "xl2tpd"    "PASSWORD"    *

IPSecの設定

IPsecの設定を行ないます。設定ファイル内は「configセクション」と「connセクション」に分かれます。
configセクションには動作に関する全体の設定を行ない、connセクションには個別のネットワークに関する設定を行ないます。

# cp -p /etc/ipsec.conf /etc/ipsec.conf.original <LF>
# cat /dev/null > /etc/ipsec.conf <LF>
# vim /etc/ipsec.conf <LF> <= IPsec定義ファイルの編集(configセクション関連を定義)
config setup
  protostack=netkey <= カーネル鍵管理(サンプル設定に従う)
  nat_traversal=yes <= NAT-Tを有効
  virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
include /etc/ipsec.d/*.conf

下記の設定ファイルで「left」と「right」というものがありますが、ネットワーク上で、左と右が決められているわけではありません。どちらが左でも右でも問題ありません。
但し、どちらかを左と決めると対向側(相手側)は右となります。

# vim /etc/ipsec.d/l2tp-psk.conf <LF> <= IPsec定義ファイルの編集(connセクション関連を定義)
conn L2TP-PSK-LEFT
    leftsubnet=0.0.0.0/0 <= left側(VPNクライアント)のサブネット 
 
    dpddelay=10 <= 10秒間隔(iphoneの再接続対応)
    dpdtimeout=30 <= 30秒で応答がなければタイムアウト(iphoneの再接続対応)
    dpdaction=clear <= タイムアウトで接続情報をクリア(iphoneの再接続対応)
 
    forceencaps=yes <= ESPを強制的にカプセル化するかどうか
 
    left=%any <= left側(VPNクライアント)のIPアドレス(何でもこい)
    leftprotoport=17/%any <= left側(VPNクライアント)のプロトコル17(UDP)でポート番号(何でもこい)
 
    also=L2TP-PSK-RIGHT <= インクルードみたいな感じ
 
conn L2TP-PSK-RIGHT
    authby=secret <= 認証方式は共通鍵方式
    pfs=no <= PFS(Perfect Forward Security)は相手側がIKEv1が使えることが前提となるため
    auto=add <= 接続待ち状態
    keyingtries=3 <= 接続を3回までリトライ
 
    type=transport <= ホスト間のIPSec-VPNなので
 
    right=192.168.1.101 <= right側(VPNサーバ)のIPアドレス
    rightprotoport=17/1701 <= right側(VPNサーバ)のプロトコル17(UDP)でポート番号(1701)
# vim /etc/ipsec.d/default.secrets <LF> <= 共通鍵
: PSK "password"

カーネルパラメタ

通信まわりのカーネルパラメタを変更します。

# sysctl -a > /tmp/sysctl_a.20141212.old <LF>
# sysctl -a | grep -e net.ipv4.conf.*send_redirects \
> -e net.ipv4.conf.*accept_redirects\
> > /etc/sysctl.d/10-sysctl_ipsec.conf <LF>
# vim /etc/sysctl.d/10-sysctl_ipsec.conf <LF>
net.ipv4.ip_forward = 1 <= IPv4転送を有効にする
net.ipv4.conf.all.accept_redirects = 0 <= ICMPリダイレクトを受信しない
net.ipv4.conf.all.send_redirects = 0 <= ICMPリダイレクトを送信しない
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.enp1s0.accept_redirects = 0
net.ipv4.conf.enp1s0.send_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.c2sub-titleonf.lo.send_redirects = 0
# sysctl -p <LF>

サービスの起動

サービスを起動します。

# systemctl enable xl2tpd <LF>
ln -s '/usr/lib/systemd/system/xl2tpd.service'
 '/etc/systemd/system/multi-user.target.wants/xl2tpd.service'
# systemctl enable ipsec <LF>
ln -s '/usr/lib/systemd/system/ipsec.service'
 '/etc/systemd/system/libreswan.service'
ln -s '/usr/lib/systemd/system/ipsec.service'
 '/etc/systemd/system/pluto.service'
ln -s '/usr/lib/systemd/system/ipsec.service'
  '/etc/systemd/system/multi-user.target.wants/ipsec.service'
# systemctl start ipsec <LF>
# systemctl start xl2tpd <LF>
# ipsec verify <LF> <= [Failed]がないこと
Verifying installed system and configuration files
 
Version check and ipsec on-path                       [OK]
Libreswan 3.8 (netkey) on 3.10.0-123.13.1.el7.x86_64
Checking for IPsec support in kernel                  [OK]
 NETKEY: Testing XFRM related proc values
         ICMP default/send_redirects                  [OK]
         ICMP default/accept_redirects                [OK]
         XFRM larval drop                             [OK]
Pluto ipsec.conf syntax                               [OK]
Hardware random device                                [N/A]
Checking rp_filter                                    [ENABLED]
 /proc/sys/net/ipv4/conf/default/rp_filter            [ENABLED]
 /proc/sys/net/ipv4/conf/enp1s0/rp_filter             [ENABLED]
  rp_filter is not fully aware of IPsec and should be disabled
Checking that pluto is running                        [OK]
 Pluto listening for IKE on udp 500                   [OK]
 Pluto listening for IKE/NAT-T on udp 4500            [OK]
 Pluto ipsec.secret syntax                            [OK]
Checking NAT and MASQUERADEing                        [TEST INCOMPLETE]
Checking 'ip' command                                 [OK]
Checking 'iptables' command                           [OK]
Checking 'prelink' command does not interfere with FIPSChecking for obsolete ipsec.conf options              [OK]
Opportunistic Encryption                              [DISABLED]

最後にインターネット接続ルータでは、500/udp,4500/udpをVPNサーバに向けて許可する必要があります。
また、VPNサーバ自体にファイアウォールがあれば、VPNサーバには、上記に加えて、1701/udpも許可する必要があります。

今回の設定で、iphone7.1.2とWindows7,ubuntu14.04での接続を確認取れました。(追記:androidも問題おまへんでした)

やっぱり、VPNは専用機の方がいいのかも。