はじめに
自宅内で遊びに使っているサーバ(と言う名のノートPC)がそろそろ限界に近づいているので、NTTPCコミュニケーションズのVPS「Indigo」に移行してみようと思います。自宅と同じような感覚で使うためも、VPN張りたいよね!ということで、自宅とVPS上のインスタンスをSite to Site IPSec-VPNで接続することにしました。
#前提条件
##自宅側
- FortiGate 60C(v5.2.13,build762)
- 古っ。。
- 普通のプロバイダ契約で、DDNS使用
##VPS側
- NTT PC コミュニケーションズ「Indigo」上の、KVM Instance 1 CPU 1 GB - Ubuntu 18.04
- strongSwan U5.6.2/K4.15.0-106-generic
##ネットワーク環境
ネットワーク | 自宅側 | VPS側 |
---|---|---|
グローバルIPアドレス | x.x.x.x(可変)/xxxx.fortiddns.com | y.y.y.y(固定) |
IPSec接続用IPアドレス | 172.16.1.1 | 172.16.1.2 |
ローカルアドレス | 192.168.100.0/24 | - |
自宅側FortiGateの設定
IPSecウィザード
FortiGateのIPSecウィザード「Site to Site - Cisco」をベースに作成します。
カスタムで作ってもよいのですが、一旦ウィザードで作ると、インタフェイスの設定とか、ルーティングの設定とか必要なものを自動的に作ってくれるので楽ちんです。
##トンネルの設定
ウィザードで作成したトンネルを以下のように設定します。ポイントになる設定だけ表に抜き出しているので参考にしてください。
###ネットワーク
項目 | 設定 |
---|---|
リモートゲートウェイ | 固定IPアドレス |
IPアドレス | VPSのインスタンスのグローバルIPアドレス |
インターフェイス | 自宅のインターネットの出口 |
NATトラバーサル | 有効(Indigoのファイアウォールを抜けるため) |
項目 | 設定 |
---|---|
方式 | 事前共有鍵 |
事前共有鍵 | 適当なパスワード |
IKEバージョン | 2 |
項目 | 設定 |
---|---|
暗号化 | AES256 |
認証 | SHA256 |
Diffie-Hellman Group | 21 |
ローカルID | 自宅側DDNSのFQDN(例:xxxx.fortiddns.com) |
項目 | 設定 |
---|---|
暗号化 | AES256 |
認証 | SHA256 |
Diffie-Hellman Group | 21 |
##インタフェイス
ウィザードで作成したインタフェイスを以下のように設定をします。
項目 | 設定 |
---|---|
IP | IPSecで使用する自宅側のIP、ここでは172.16.1.1 にしています。 |
リモートIP | 同じくVPS側のIP、ここでは172.16.1.2 にしています。 |
管理者アクセス | 疎通確認のため、PINGだけ許可しています。 |
##ルーティング
ウィザードで作成したスタティックルートを以下のように設定をします。
項目 | 設定 |
---|---|
宛先IP/マスク | インタフェイスで指定したリモートIPに設定します。 |
VPS側の設定
##必要なコンポーネントのインストール
IPSec-VPNの接続には、strongSwanを使用します。
# apt install strongswan
##strongSwanの設定
ipsec.conf
strongSwanの設定ファイルです。
right
とleft
というのがVPNのどっちがどっちかよくわからなくなりますが、先に書いた絵と同じように、left
がVPS側、right
が自宅側ということにしています。
# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup
charondebug="ike 1, knl 1, cfg 0"
# strictcrlpolicy=yes
# uniqueids = no
# Add connections here.
conn home
left=y.y.y.y
leftsubnet=0.0.0.0/0
right=xxxx.fortiddns.com
rightid=%any
rightsubnet=0.0.0.0/0
leftfirewall=no
leftupdown=/etc/strongswan.d/updown.sh
keyexchange=ikev2
ike=aes256-sha256-ecp521
esp=aes256-sha256-ecp521
type=tunnel
authby=secret
auto=route
compress=no
mark=42
forceencaps=yes
###ipsec.secrets
FortiGateに仕込んだ事前共有鍵を指定します。
# This file holds shared secrets or RSA private keys for authentication.
# RSA private key for this host, authenticating it to any other host
# which knows the public part.
#
y.y.y.y xxxx.fortiddns.com : PSK "asdfasdfasdfasdfadsf"
###updown.sh
IPSecで無事に接続された際に実行されるスクリプトを作成します。
ここで、自宅側のネットワークをVTI経由で通信するようにルーティングの設定等を行っています。
#!/bin/bash
PLUTO_MARK_OUT_ARR=(${PLUTO_MARK_OUT//// })
PLUTO_MARK_IN_ARR=(${PLUTO_MARK_IN//// })
echo ${PLUTO_VERB}
echo ${PLUTO_CONNECTION}
VTI_INTERFACE="vti"${PLUTO_MARK_IN_ARR}
case "${PLUTO_VERB}" in
up-client)
ip tunnel add ${VTI_INTERFACE} mode vti local ${PLUTO_ME} remote ${PLUTO_PEER} key 42
ip link set ${VTI_INTERFACE} up
ip link set ${VTI_INTERFACE} up mtu 1350
ip addr add 172.16.1.2/32 dev ${VTI_INTERFACE}
ip route add 172.16.1.1/32 dev ${VTI_INTERFACE}
ip route add 192.168.100.0/24 dev ${VTI_INTERFACE}
;;
down-client)
$IP link del ${VTI_INTERFACE}
;;
esac
ファイアウォールの設定
VPS側のファイアウォールに穴あけが必要です。Indigoのコントロールパネルから、ファイアウォールで以下の設定を入れます。
方向 | プロトコル | ポート | IPアドレス |
---|---|---|---|
IN | UDP | 500(IKE) | x.x.x.x |
IN | UDP | 4500(NAT-T) | x.x.x.x |
IPSec VPNの接続
準備ができたので早速接続してみましょう。
# ipsec start
Starting strongSwan 5.6.2 IPsec [starter]...
# ipsec statusall
Status of IKE charon daemon (strongSwan 5.6.2, Linux 4.15.0-106-generic, x86_64):
uptime: 19 seconds, since Jun 21 07:41:20 2020
malloc: sbrk 1617920, mmap 0, used 568000, free 1049920
worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 3
loaded plugins: charon aesni aes rc2 sha2 sha1 md4 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm attr kernel-netlink resolve socket-default connmark stroke updown eap-mschapv2 xauth-generic counters
Listening IP addresses:
y.y.y.y
172.16.1.2
Connections:
home: y.y.y.y...xxxx.fortiddns.com IKEv2
home: local: [y.y.y.y] uses pre-shared key authentication
home: remote: uses pre-shared key authentication
home: child: 0.0.0.0/0 === 0.0.0.0/0 TUNNEL
(以下省略)
このように表示されてたらおそらく大丈夫かと。。
VTIと、ルーティングが設定されているかも確認しておきます。
# ifconfig
ens10: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet y.y.y.y netmask 255.255.255.0 broadcast y.y.y.255
ether XX:XX:XX:XX:XX:XX txqueuelen 1000 (Ethernet)
RX packets 549464753 bytes 108213055144 (108.2 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1350377 bytes 262993102 (262.9 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vti42: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1350
inet 172.16.1.2 netmask 255.255.255.255 destination 172.16.1.2
tunnel txqueuelen 1000 (IPIP Tunnel)
RX packets 1292489 bytes 185606148 (185.6 MB)
RX errors 93 dropped 93 overruns 0 frame 0
TX packets 1229046 bytes 148444508 (148.4 MB)
TX errors 424 dropped 0 overruns 0 carrier 424 collisions 0
# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 0 0 0 ens10
y.y.y.y 0.0.0.0 255.255.255.0 U 0 0 0 ens10
172.16.1.1 0.0.0.0 255.255.255.255 UH 0 0 0 vti42
192.168.100.0 0.0.0.0 255.255.255.0 U 0 0 0 vti42
大丈夫そうなので、試しに、VPS側から自宅側にping
で疎通確認してみます。
# ping 172.16.1.1 -c 5
PING 172.16.1.1 (172.16.1.1) 56(84) bytes of data.
64 bytes from 172.16.1.1: icmp_seq=1 ttl=255 time=10.7 ms
64 bytes from 172.16.1.1: icmp_seq=2 ttl=255 time=11.3 ms
64 bytes from 172.16.1.1: icmp_seq=3 ttl=255 time=10.6 ms
64 bytes from 172.16.1.1: icmp_seq=4 ttl=255 time=11.1 ms
64 bytes from 172.16.1.1: icmp_seq=5 ttl=255 time=11.0 ms
# ping 192.168.100.1 -c 5
PING 192.168.100.1 (192.168.100.1) 56(84) bytes of data.
64 bytes from 192.168.100.1: icmp_seq=1 ttl=255 time=11.7 ms
64 bytes from 192.168.100.1: icmp_seq=2 ttl=255 time=10.3 ms
64 bytes from 192.168.100.1: icmp_seq=3 ttl=255 time=11.2 ms
64 bytes from 192.168.100.1: icmp_seq=4 ttl=255 time=13.8 ms
64 bytes from 192.168.100.1: icmp_seq=5 ttl=255 time=10.5 ms
大丈夫ですね。
自動起動の設定
OS起動時に自動的に接続されるように設定しておきます。
# systemctl enable strongswan
#うまくいかなかった場合の確認ポイント
ログを確認する。
strongSwanとかがエラーを吐いていないか、/var/log/syslog
を確認しましょう。
ファイアウォールを疑う
設定に間違いがないのに、うまく行かない場合はファイアウォールを疑うべきですね。
- VPS側のファイアウォール(
ufw
とかiptables
とか)の設定を確認する。 - 自宅側のファイアウォールのポリシーを確認する。特にIPSec用に作成したインタフェイスからinternalへの通信はポリシーの設定が必要です。
それでもだめな場合は
tcpdumpとかでパケットキャプチャをとってみましょう。
# tcpdump -i ens10 -f "host x.x.x.x" -w /tmp/vpn.pcap
私の場合は、/etc/ipsec.conf
のforceencaps=yes
が抜けていたせいで、NAT-Traversalが効いてなくて、ESPのパケットがVPSから自宅には飛ぶのに、自宅からVPSに飛んでこないという状況が見えていました。。
おわりに
ちゃんとしたVPNをサービスがついているVPSであれば、こんなことしなくてもよいのかもしれませんが、strongSwanを使うことで安価なVPSと自宅をIPSec VPNで接続することができました。これでVPSの用途が広がります。
あと、VPS側のファイアウォールの設定で、自宅のグローバルIPアドレスを指定したのですが、自宅のグローバルIPアドレスは可変でDDNS運用ですので、プロバイダの都合で変わってしまいます。そうなったときでも大丈夫なように別記事でDDNS運用でも大丈夫な仕組みを作っていますので、興味があればそちらも参照してください。
#参考資料
-
FortiGateとStrongSwanでSite-Site IPsec VPNを張る
- こちら、大いに参考にさせてもらいました。感謝です。