それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

インターリンクのVPNサービスにLinux(ubuntu)のstrongswanから接続する。

strongswan でIKEv2を接続する

UbuntuでStrongswanをインストールして、固定IPサービスを利用する。

MyIP 契約 を用意する

インターリンクMyIPの契約をすると、グローバル・アドレスが直接割り当てられる。

ちなみに、グループ専用VPN では、1つのグローバルIP(私の契約の場合はさくらVPSだった)を複数人で共有する仕様なので、IKEv2でVPNを貼ると、GWとローカルアドレス10.0.0.0が与えられる。

仕様が異なるので注意する。

今回試すのは、個人がつかうMyIPの方である。

インストール

今回はraspi ubuntuを用いた

sudo apt update 
sudo apt install strongswan libstrongswan-extra-plugins

証明書のコピー

sudo cp /etc/ssl/certs/Security_Communication_RootCA2.pem  /etc/ipsec.d/cacerts/

証明書のコピーはクライアント側から、vpn サーバーがなりすましでないこと(本物)であることを確認し、IKEv2のフェーズ1を完了するため。pubkey(RSA公開鍵とCA署名)を使って検証するために必要になる。これは rightauth=pubkeyrightid=interlink.or.jpの設定で使っている。

ipsec を設定する

/etc/ipsec.conf

# ipsec.conf - strongSwan IPsec configuration file
# basic configuration
config setup

# 接続設定
conn interlink
 # 
 keyexchange=ikev2
 right=myip12345.interlink.or.jp
 rightid=%interlink.or.jp # ここは必ず。
 rightsubnet=0.0.0.0/0
 rightauth=pubkey
 type=tunnel

 leftauth=eap
 #leftauth=eap-mschapv2 # ←動かない
 #leftauth=eap-md5 # ← eap-md5なら動く
 leftsourceip=%config4
 eap_identity=mi123456
 auto=add
 mark=219
 leftupdown=/etc/ipsec.d/updown/interlink-vpn.sh

/etc/ipsec.secrets

# for ikev2 of eap
mi123456 %interlink.or.jp : EAP "MyPassword"

VTI を用意する

strongswanのdocを参考にvti のスクリプトを用意する。

このファイルは、ipsec.confleftupdownの値で指定したPATHのもの。

#!/usr/bin/env bash

set -o nounset
#set -o errexit

VTI_IF="vti${PLUTO_UNIQUEID}"

case "${PLUTO_VERB}" in
  up-client)
    ip tunnel add "${VTI_IF}" mode vti \
      local "${PLUTO_ME}" remote "${PLUTO_PEER}" \
      okey "${PLUTO_MARK_OUT%%/*}" ikey "${PLUTO_MARK_IN%%/*}"
    ip link set "${VTI_IF}" up
    ip addr add ${PLUTO_MY_SOURCEIP} dev "${VTI_IF}"
    ip route add 1.1.1.1 dev "${VTI_IF}" # 確認用サンプル
    #iptables -I FORWARD -o "${VTI_IF}" -s 172.16.9.0/24 -j ACCEPT
    sysctl -w "net.ipv4.conf.${VTI_IF}.disable_policy=1"
    ;;
  down-client)
    # iptables -D FORWARD -o "${VTI_IF}" -s 172.16.9.0/24 -j ACCEPT
    ip tunnel del "${VTI_IF}"
    ;;
esac

/etc/strongswan.conf

# strongswan.conf - strongSwan configuration file
# (略)
charon {
    load_modular = yes
    plugins {
        include strongswan.d/charon/*.conf
    }
}

include strongswan.d/*.conf

## 2023-08-30
##   include の結果を上書き
charon {
  install_routes = no
  install_virtual_ip = no
}

設定を反映

sudo ipsec restart

接続と切断

sudo ipsec up interlink
sudo ipsec down interlink

経路の確認

ルートがVTI経由になってることを確認

ip route get 1.1.1.1

vti 経由になっている、

1.1.1.1 dev vti1 src xxx.xxx.xxx.xxx uid 1000
    cache

通信の確認

ping送信して、vtiでは生パケットが見えて、eth0ではESP(暗号化)パケットになることを確認

ping -t 2 1.1.1.1

vtiX では「普通」のパケットが見えることを確認

sudo tcpdump -n -i vti1  host 1.1.1.1
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on vti1, link-type RAW (Raw IP), snapshot length 262144 bytes
04:20:00.968755 IP xxx.xxx.xxx.xxx > 1.1.1.1: ICMP echo request, id 20, seq 13, length 64
04:20:00.982322 IP 1.1.1.1 > xxx.xxx.xxx.xxx: ICMP echo reply, id 20, seq 13, length 64

xxx.xxx.xxx.xxxVPNで割当られた固定IPアドレスvti1 は作成された VTIデバイス。ただし、vti1,vti2,vti3 のように接続切断で数字が変化する。ipsec restart で1 に戻る。

eth0 上ではパケットが「カプセル化(暗号化)」されてトンネルに入ってることを確認。

sudo tcpdump -n -i eth0 host yyy.yyy.yyy.yyy
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on macvlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
04:22:13.107454 IP 192.168.0.222.4500 > yyy.yyy.yyy.yyy.4500: UDP-encap: ESP(spi=0xc2bd1f42,seq=0x29), length 136
04:22:13.121220 IP yyy.yyy.yyy.yyy.4500 > 192.168.0.222.4500: UDP-encap: ESP(spi=0xc8a1a75f,seq=0x38), length 136
04:22:17.109161 IP 192.168.0.222.4500 > yyy.yyy.yyy.yyy.4500: UDP-encap: ESP(spi=0xc2bd1f42,seq=0x2a), length 136
04:22:17.122883 IP yyy.yyy.yyy.yyy.4500 > 192.168.0.222.4500: UDP-encap: ESP(spi=0xc8a1a75f,seq=0x39), length 136

yyy.yyy.yyy.yyy は myXXX.interlink.or.jp のAレコード(IKEv2 の接続先)

192.168.0.222ipsec クライアントの eth0 アドレス。

暗号化対象(xfrm)の確認

linuxipsecではXFRMで暗号化されるので、xfrm サブコマンドで暗号化される経路と、本当に通信でつかう(暗号化パケットが通る)経路を確認する。

sudo ip xfrm policy

コマンド実行例

src xxx.xxx.xxx.xxx/32 dst 0.0.0.0/0
        dir out priority 383615
        mark 0xdb/0xffffffff
        tmpl src 192.168.0.222 dst yyy.yyy.yyy.yyy
                proto esp spi 0xc2bd1f42 reqid 1 mode tunnel
src 0.0.0.0/0 dst xxx.xxx.xxx.xxx/32
        dir fwd priority 383615
        mark 0xdb/0xffffffff
        tmpl src yyy.yyy.yyy.yyy dst 192.168.0.222
                proto esp reqid 1 mode tunnel
src 0.0.0.0/0 dst xxx.xxx.xxx.xxx/32
        dir in priority 383615
        mark 0xdb/0xffffffff
        tmpl src yyy.yyy.yyy.yyy dst 192.168.0.222
                proto esp reqid 1 mode tunnel
                

このコマンドの結果では、クライアントからの送信(src=x.x.x.x)と、相手側からの応答(src=0.0.0.0/0)がにマッチしたパケットが実際に通る暗号化経路(y.y.y.y ⇔ 192.168.0.222) が示されている。

ただし、今回は、updown スクリプトsysctl -w "net.ipv4.conf.${VTI_IF}.disable_policy=1"をしているので、vtiを通るパケットは上記から除外される。vtiを出たときに暗号化経路に置き換えられる。

vtiで使いやすい。

ipsec はESPとxfrm があって、経路が暗黙的(透過的)に暗号化されるのであるが、vtiをつかうことでppptpやpppoeデバイスと同じ使い方になるので、扱いやすい。ファイアウォールなども書きやすい。

明示的に接続してつかう場合や、特定IPアドレス宛だけを暗号化トンネルを通したいときに便利だと思う。ipsecを使っていると、暗黙的な暗号化なので、どの経路を通ったら暗号化されるのかが分かりづらく、実際につかうときはクライアント全部をトンネルを通る使い方(スマホやPCが全部トンネルを通る)になりがちである。

それと比べるとvtiを使えば、指定IPアドレス(IPネットワークアドレス)をvti経由にすることで、暗号化と非暗号化を共存できるし、サイト間の通信を確実に暗号化出来て便利だと思った。

今回の設定により、MyIPサービスとipsec,vtiを組み合わせて、自分のVPSサーバーに接続する際にだけ、VPNを通るように設定することが出来て、VPSサーバは固定アドレスを対象にポート開放が可能になった。

インターリンクのサービスでの違い

インターリンクのMyIPサービスグループ専用VPNではサービス提供の形式が違うのと、認証が異なるので注意する。

leftauth=eapで認証され利用可能になる。ただ、MyIPサービスは eap-md5 で認証接続する。一方でが グループ専用VPNサービスは eap-mschapv2 で認証していた。

また、MyIPサービスはPPP的にグローバルIPが割り当てられるのにたいし、グループ専用VPNサービスはローカルアドレス(10.x.x.x)が割り当てられGW(10.x.x.1)が存在しグローバルIPはGW経由で外部に接続したときに使われる。

また、MyIPサービスはPPP的だがDNS割当がない。グループ専用VPNサービスはDNS割当がある。

また、どちらもOP25Bについては対象外になっているようです。

上記のような違いがあった。

VPNサービスと価格で考えた場合。

さくらVPSに、自分でWireguardやOpenVPNを構成できるなら、月額課金より自分で構成しちゃったほうが楽ちんだと思ったり。課金するだけでVPNと固定IPが誰でも使えるのが魅力的ですけどね。

メール関連の運用には

固定IPでメール関連を運用しようと思うと大変ですよね。

参考資料