#目的
家などからインターネットアクセスする際の、固定のグローバルIPアドレスが欲しかった。
例えばWebシステムの管理画面にIPアドレス制限をかけて、自分しかアクセスできなくするなどの用途で。
しかしプロバイダの固定IPアドレスオプションのコストが結構高いので、他の用途で契約していたVPSにVPNサーバを立てて、VPSに割り当てられたグローバルIPアドレスを自分の「固定IPアドレス」として使うことにした。
#前提
VPSは以下。
- GMOクラウドVPS
- CentOS 6.8 x86_64
- SELinuxは使わない
典型的なLAMP環境が動いている何の変哲もないVPS。
せっかくだからWindows, Mac, iOS, Androidの各デバイスから接続できるようにしたいので、「L2TP/IPsec PSK」対応とする。
#セットアップ
##epelリポジトリを登録
yumの標準リポジトリに入っていないパッケージを使うので。
yum install epel-release
##SELinuxを無効にする
セキュリティ上望ましくないかとは思うが、参考にしたサイトであらかた無効にしていたのと、何より既にシステムを動かすために無効にしてあったので、このままで行く。
setenforce 0
:(略)
SELINUX=disabled
:(略)
##IPsec, L2TPのパッケージをインストール
IPsecはopenswan、L2TPはxl2tpdで対応することに。
yum -y --enablerepo=epel install openswan xl2tpd lsof
(lsofはあとで設定の確認に必要になるだけで本質ではない)
##xl2tpdの設定
[lns default]
ip range = 192.168.1.128-192.168.1.254
local ip = 192.168.1.99
require chap = yes
refuse pap = yes
require authentication = yes
name = oreorevpnserver
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
上記設定を追加。
このVPSはグローバルIPアドレスを持つeth0とループバックしか持っていなかったので、ip rangeとlocal ipは適当なローカルアドレスでOK(のはず)。VPSがLANに参加している場合は考慮しないといけない(はず)。
[global]
listen-addr = xxx.xxx.xxx.xxx
VPS自身に割り当てられたIPアドレスを上記のように設定する必要がありそうだが、アダプタが一つしかないせいか、特に設定しなくても動いた。
##PPPの設定
ipcp-accept-local
ipcp-accept-remote
ms-dns xxx.xxx.xxx.xxx
ms-dns xxx.xxx.xxx.yyy
# ms-dns 192.168.1.1
# ms-dns 192.168.1.3
# ms-wins 192.168.1.2
# ms-wins 192.168.1.4
#noccp
auth
crtscts
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
lock
proxyarp
connect-delay 5000
# To allow authentication against a Windows domain EXAMPLE, and require the
# user to be in a group "VPN Users". Requires the samba-winbind package
# require-mschap-v2
# plugin winbind.so
# ntlm_auth-helper '/usr/bin/ntlm_auth --helper-protocol=ntlm-server-1 --require-membership-of="EXAMPLE\\VPN Users"'
# You need to join the domain on the server, for example using samba:
# http://rootmanager.com/ubuntu-ipsec-l2tp-windows-domain-auth/setting-up-openswan-xl2tpd-with-native-windows-clients-lucid.html
netmask 255.255.255.0
persist
require-mschap-v2
logfile /var/log/xl2tpd.log
まるまるコピペ。DNSを設定。Googleさんに頼ることにして8.8.8.8
とかでもOKらしいけど、VPS用に提供されている2つのDNSサーバのアドレスを指定。
参考サイトによると#noccp
しないとiOSからの接続に難があるとのこと。
mtu/mruはお好みで。netmaskは先ほどのxl2tpd.confでのip range設定に合わせる。ログファイルの場所もお好み。touch /var/log/xl2tpd.log
して作っておく。
##openswanの設定
:(略)
include /etc/ipsec.d/*.conf
conn L2TP-PSK-NAT
rightsubnet=0.0.0.0/0
forceencaps=yes
also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
#iOS用の設定
dpddelay=10
dpdtimeout=20
dpdaction=clear
#iOS用の設定 ここまで
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
ike=3des-sha1,aes-sha1,aes256-sha2_256,aes256-sha2_512
phase2alg=3des-sha1,aes-sha1,aes256-sha2_256,aes256-sha2_512
sha2-truncbug=yes
このへんは参考サイトからのコピペなので今一つ理解していない。VPN接続してきた端末からのパケットをルーティングする設定なのだと思う。
##PPP接続用のパスワードを設定
# Secrets for authentication using CHAP
# client server secret IP addresses
"hogehoge" * "passwd" *
:(略)
アカウントhogehoge
をパスワードpasswd
で認証する。平文でアカウント名とパスワードを列挙するだけみたい。なんだかちょっと不安。特にここでのアカウント名とLinuxユーザーは関係ないみたい。
##IPsec用の事前共有鍵を設定
: PSK "presharedkey"
この1行だけのファイルを作ると、presharedkey
という事前共有鍵(シークレット)が設定される。ここも思い切り平文なのね。
##ファイアウォール(iptables)に穴を開ける
以下のような設定スクリプトにしてある。
#!/bin/bash
/etc/rc.d/init.d/iptables stop
# 設定初期化
iptables -F
iptables -X
# ポリシー設定(デフォルト全拒否)
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# ループパック通信許可
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 外への接続を許可
iptables -P OUTPUT ACCEPT
:(略)
# L2TP/IPsec
iptables -A FORWARD -i ppp+ -j ACCEPT
iptables -A FORWARD -o ppp+ -j ACCEPT
iptables -A INPUT -p esp -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 1701 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 500 -j ACCEPT
iptables -A INPUT -p udp -m udp --dport 4500 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE
# FWルールセット保存
/etc/rc.d/init.d/iptables save
# FW開始
/etc/rc.d/init.d/iptables start
iptablesの設定をカスタマイズしている人はこの手のスクリプトでまとめて設定してると思うけど、# L2TP/IPSec
のところにまとめた部分が重要。これやらないとVPN接続しても外に出られなかったり外から見えなかったり。
##カーネルパラメータの変更
以下を追記。
:(略)
net.core.xfrm_larval_drop = 1
net.ipv4.ip_forward = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.lo.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
eth0とlo以外にもアダプタがあったら、それらについてもsend_redirects
とaccept_redirects
とrp_filter
を0
にする。
##起動
/sbin/service xl2tpd start
/sbin/service ipsec start
/sbin/chkconfig xl2tpd on
/sbin/chkconfig ipsec on
/sbin/sysctl -p
##IPsecの確認
ipsec verify
これで何か怒られたら設定が間違ってる。
#接続
今時のOSは大体「L2TP/IPsec PSK」でVPN接続できるようだ。RSA SecurIDとかL2TPセキュリティ保護とかIPSec IDなどといったオプションは設定不要だが、Androidで接続するときにDNSサーバーを設定しないと上手くいかないことがあった。
#参考サイト
- [L2TP/IPsec(AndroidやiPhoneからのVPN接続)を経路を用意すべくVPSにL2TP/IPsecサーバを設置するとき、ネットにある情報だとなかなかつながらないから、標準環境としてAWSのCentOS 6.3 x86_64 Release Media(ami-3fe8603e)の起動直後から最短距離で設定する方法をまとめた。 · GitHub] (https://gist.github.com/CLCL/5742738)
- [EZ-NET: CentOS 6.0 で L2TP-VPN サーバを構築する]
(http://network.station.ez-net.jp/server/remote/Linux/l2tp.asp) - [linuxでVPNサーバ - Qiita]
(http://qiita.com/mell3210/items/2fa2c9b616e4a2c685af)