m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

プローブURLでどんなヘッダー投げているか確認

プローブURLって

どんなことするのかわからないので・・・

ドキュメントの情報としては

https://developer.apple.com/documentation/devicemanagement/vpn/vpn/ondemandruleselement/actionparameters?changes=latest_minor

An HTTP or HTTPS (preferred) URL to probe, using a GET request. If the URL's hostname cannot be resolved, if the server is unreachable, or if the server does not respond with a 200 HTTP status code, a VPN connection is established in response. Note: This key is valid only if the value of DomainAction is ConnectIfNeeded.

200OK返せとか、200OK以外返して判断するみたいなのであまり 仕組みについては細かく言及していない感じ

ググってみたところ 以下より抜粋
無線LAN - ネットワークエンジニアを目指して 無線LAN - ネットワークエンジニアを目指して

とのこと

うーーーーーーーーーーーーーん VPN通信可能チェック用の簡易APIと考えれば良いのか・・・

今回、実際のプローブレスポンスはできなくとも似た感じの挙動で対応できれば問題ないからよいかな

iphone側でGETリクエストで送信するのでURLを工夫してVPNからの接続検査を制御する感じになるのか・・・ 実際にどんなヘッダーが来るのかも気になったので簡単なコードで確認してみた

これ(Node.js の mocky を使用し スタブREST API を作成してみる

var mocky = require('mocky');
var fs = require('fs');
var url = require('url');
var querystring = require('querystring');

mocky.createServer([{
  // Users
  url: "/test1",
  method: 'get',
  res: function(req, res, callback) {
    //iconsole.log(req.socket);
    console.log(req.rawHeaders);
    callback(null, {
      status: 500,
      body: "error"
    });
  }
}
]).listen(4321);

出たログ

[mocksrv] [req 10] [Thu, 04 May 2023 08:54:11 GMT] method: GET url: /test1 req.body:
[
  'Host',
  '192.168.123.51:4321',
  'Accept',
  '*/*',
  'Accept-Language',
  'en-US,en;q=0.9',
  'Connection',
  'keep-alive',
  'Accept-Encoding',
  'gzip, deflate',
  'User-Agent',
  'nesessionmanager (unknown version) CFNetwork/1399 Darwin/22.1.0'
]

CFNetwork | Apple Developer Documentation

なるほど、、、ネットワークの構成変更時の処理だからこの機能で処理されるのか 内部的な意味は分かってないけど ひとまずはここまでとする

プローブリクエストは別途あらためて勉強しておこう

iOSのVPNの構成プロファイルを検証(オンデマンド接続)

いつごろ追加されているかは知らないが

https://developer.apple.com/documentation/devicemanagement/vpn/ikev2?changes=latest_minor

まあ、オンデマンド接続自体はあっても困らないのでよい それぞれがどのような動きをするか確認

VPN.IKEv2配下

IKEv2配下のキー内で設定可能なもの

項番 キー名 説明 備考
1 OnDemandEnabled 1またはtrueの場合にオンデマンド接続を有効にする OnDemandRulesが設定されていること
2 OnDemandRules 配列形式にオンデマンドルールを設定して、オンデマンド接続を有効にする 複数の一致条件がある場合は先勝ち

※接続と切断の両方が混在する場合は正しい挙動ができないため、非推奨
3 OnDemandUserOverrideDisabled 1またはtrueの場合にオンデマンド接続時の切り替えスイッチを変更不可にする DEP化対象端末による配信処理でのみ有効

VPN.VPN.OnDemandRulesElement

オンデマンドルール条件 Actionだけでも動作はするため、一切、VPNに繋げさせない設定として指定することも可能

項番 キー名 必須 説明 備考
1 Action 必須 ルール一致時の動作
・Connect
 VPNオンデマンド接続を行う
※別のネットワークへ切り替えてもVPN接続は解除されない

・Disconnect
 VPN接続不可とする

・EvaluateConnection
 通信時に判定してオンデマンド接続の制御を行う

・Ignore
 ネットワーク切り替え時のみオンデマンド接続時、接続解除後はオンデマンド接続を無効にする
Connect中はVPN設定のオンデマンド接続トグルをOFFにしない限り、通信が始まるとVPN接続を試行する
2 ActionParameters - ActionEvaluateConnection時の判定条件を指定 ActionEvaluateConnection時は必須
3 DNSDomainMatch - DNS検索ドメインが含まれる場合は一致扱いとなる 基本、InterfaceTypeMatchCellular以外

また、*を含めることもサポートされている模様
4 DNSServerAddressMatch - DNSサーバが含まれる場合は一致扱いとなる 基本、InterfaceTypeMatchCellular以外

また、CIDR指定もサポートされている模様
5 InterfaceTypeMatch - インターフェース
Ethernet
WiFi
・Cellular
iOSで有線できないので基本、WiFiCellular
6 SSIDMatch - SSIDが含まれている場合は一致扱い 基本、InterfaceTypeMatchWiFiのみ
7 URLStringProbe - プローブURL
リクエストを送信して200OKの場合は一致扱い

DNSDomainMatchDNSServerAddressMatchは接続する端末のネットワーク情報を参照して判定するため

VPN.VPN.OnDemandRulesElement.ActionParameters

アクションパラメータ条件 特定のドメインへのアクセス時に特定のDNSサーバやプローブURLと通信できない場合にVPN接続するように制御するため、
VPN接続している場合のみ200OKが返る設定を行う

項番 キー名 必須 説明 備考
1 DomainAction 必須 ドメイン一致時の挙動を指定
・ConnectIfNeeded
・NeverConnect
2 Domains 必須 ドメイン
3 RequiredDNSServers - VPN接続時のみ通信可能なDNSサーバアドレス
到達できない場合はVPN接続を行う
DomainActionConnectIfNeeded
4 RequiredURLStringProbe - VPN接続時のみ通信可能なプローブURL DomainActionConnectIfNeeded

設定例

項番 パターン 備考
1 WiFiの場合はVPN接続する
2 Cellularの場合はVPN接続しない
3 SSIDhogehogeの場合は接続する
4 SSIDhogehogeの場合は接続、Cellularの場合はVPN接続しない
5 通信チェックしてドメインへの名前解決ができない場合に VPN接続を行う

共通設定

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>DNS</key>
            <dict>
                <key>ServerAddresses</key>
                <array>
                    <string>8.8.8.8</string>
                    <string>8.8.4.4</string>
                </array>
                <key>SupplementalMatchDomainsNoSearch</key>
                <integer>0</integer>
            </dict>
            <key>IKEv2</key>
            <dict>
                <key>AuthName</key>
                <string>任意のアカウント</string>
                <key>AuthPassword</key>
                <string>任意のパスワード</string>
                <key>AuthenticationMethod</key>
                <string>None</string>
                <key>ChildSecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>DeadPeerDetectionRate</key>
                <string>Medium</string>
                <key>DisableMOBIKE</key>
                <integer>0</integer>
                <key>DisableRedirect</key>
                <integer>0</integer>
                <key>EnableCertificateRevocationCheck</key>
                <integer>0</integer>
                <key>EnableFallback</key>
                <integer>0</integer>
                <key>EnablePFS</key>
                <integer>0</integer>
                <key>ExtendedAuthEnabled</key>
                <true/>
                <key>IKESecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>LocalIdentifier</key>
                <string>多分、VPNサーバドメイン</string>
                <key>RemoteAddress</key>
                <string>多分、VPNサーバドメイン</string>
                <key>RemoteIdentifier</key>
                <string>多分、VPNサーバドメイン</string>
                <key>UseConfigurationAttributeInternalIPSubnet</key>
                <integer>0</integer>
            </dict>
            <key>PayloadDescription</key>
            <string>VPN設定を構成します</string>
            <key>PayloadDisplayName</key>
            <string>VPN</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.vpn.managed.ここはなんかシステムで動的に変わる</string>
            <key>PayloadType</key>
            <string>com.apple.vpn.managed</string>
            <key>PayloadUUID</key>
            <string>ここはなんかシステムで動的に変わる</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>Proxies</key>
            <dict>
                <key>HTTPEnable</key>
                <integer>0</integer>
                <key>HTTPSEnable</key>
                <integer>0</integer>
            </dict>
            <key>UserDefinedName</key>
            <string>vpn.test-ryuouen.link</string>
            <key>VPNType</key>
            <string>IKEv2</string>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>vpnオンデマンドテスト</string>
    <key>PayloadIdentifier</key>
    <string>ここはなんかシステムで動的に変わる</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>ここはなんかシステムで動的に変わる</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

以下、差分を記載

WiFiの場合はVPN接続する

         <key>IKEv2</key>
            <dict>
                <key>OnDemandEnabled</key>
                <integer>1</integer>
                <key>OnDemandUserOverrideDisabled</key>
                <integer>1</integer>
                <key>OnDemandRules</key>
                <array>
                    <dict>
                        <key>Action</key>
                        <string>Connect</string>
                        <key>InterfaceTypeMatch</key>
                        <string>WiFi</string>
                    </dict>
                </array>

Cellularの場合はVPN接続しない

         <key>IKEv2</key>
            <dict>
                <key>OnDemandEnabled</key>
                <integer>1</integer>
                <key>OnDemandUserOverrideDisabled</key>
                <integer>1</integer>
                <key>OnDemandRules</key>
                <array>
                    <dict>
                        <key>Action</key>
                        <string>Disconnect</string>
                        <key>InterfaceTypeMatch</key>
                        <string>Cellular</string>
                    </dict>
                </array>

SSIDhogehogeの場合は接続する

         <key>IKEv2</key>
            <dict>
                <key>OnDemandEnabled</key>
                <integer>1</integer>
                <key>OnDemandUserOverrideDisabled</key>
                <integer>1</integer>
                <key>OnDemandRules</key>
                <array>
                    <dict>
                        <key>Action</key>
                        <string>Connect</string>
                        <key>InterfaceTypeMatch</key>
                        <string>WiFi</string>
                        <key>SSIDMatch</key>
                        <array>
                            <string>hogehoge</string>
                        </array>
                    </dict>
                </array>

SSIDhogehogeの場合は接続、Cellularの場合はVPN接続しない

         <key>IKEv2</key>
            <dict>
                <key>OnDemandEnabled</key>
                <integer>1</integer>
                <key>OnDemandUserOverrideDisabled</key>
                <integer>1</integer>
                <key>OnDemandRules</key>
                <array>
                    <dict>
                        <key>Action</key>
                        <string>Connect</string>
                        <key>InterfaceTypeMatch</key>
                        <string>WiFi</string>
                        <key>SSIDMatch</key>
                        <array>
                            <string>ryuouennet_mk2_A</string>
                        </array>
                    </dict>
                    <dict>
                        <key>Action</key>
                        <string>Disconnect</string>
                        <key>InterfaceTypeMatch</key>
                        <string>Cellular</string>
                    </dict>
                </array>

通信チェックしてドメインへの名前解決ができない場合に VPN接続を行う

         <key>IKEv2</key>
            <dict>
                <key>OnDemandEnabled</key>
                <integer>1</integer>
                <key>OnDemandUserOverrideDisabled</key>
                <integer>1</integer>
                <key>OnDemandRules</key>
                <array>
                    <dict>
                        <key>Action</key>
                        <string>EvaluateConnection</string>
                        <key>ActionParameters</key>
                        <array>
                            <dict>
                                <key>DomainAction</key>
                                <string>ConnectIfNeeded</string>
                                <key>Domains</key>
                                <array>
                                    <string>.hogehoge.com</string>
                                    <string>.hoeghoge.co.jp</string>
                                </array>
                                <key>RequiredDNSServers</key>
                                <array>
                                    <string>10.1.1.2</string>
                                    <string>10.1.1.3</string>
                                </array>
                            </dict>    
                        </array>
                        <key>InterfaceTypeMatch</key>
                        <string>WiFi</string>
                    </dict>
                </array>

所感

基本、Wi-FiSSIDで絞るのが楽な感じ EvaluateConnectionとか使用すると設定考えるのめんどーになるし、DNSサーバの準備とか必要

参考

VPN.IKEv2 | Apple Developer Documentation

IKEv2 VPNサーバーにiPhone (iOS)でオンデマンド接続させる方法 - Qiita

StrongswanでIKEv2のVPNサーバを構築する3

ひとまず、、、

ユーザー・パスワードと証明書の認証ができたので他のやつもやってみる

過去記事

m-shige1979.hatenablog.com

残件

  • 共有シークレット
  • EAP証明書

接続別

共有シークレット

/etc/strongswan/ipsec.conf

conn ikev2-vpn-secret
    authby=secret
    auto=add
    compress=no
    type=tunnel
    fragmentation=yes
    forceencaps=yes
    left=%any
    leftid=@vpn.test-ryuouen.link
    leftcert=cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightsourceip=192.168.100.0/24
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never
    eap_identity=%identity

/etc/strongswan/ipsec.secrets

# 共有シークレット
: PSK "mUERghoqa3WNauK310hH4gR2NbPw8TyN" # 任意の文字列

構成プロファイル

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>DNS</key>
            <dict>
                <key>ServerAddresses</key>
                <array>
                    <string>8.8.8.8</string>
                    <string>8.8.4.4</string>
                </array>
                <key>SupplementalMatchDomainsNoSearch</key>
                <integer>0</integer>
            </dict>
            <key>IKEv2</key>
            <dict>
                <key>AuthenticationMethod</key>
                <string>SharedSecret</string>
                <key>ChildSecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>DeadPeerDetectionRate</key>
                <string>Medium</string>
                <key>DisableMOBIKE</key>
                <integer>0</integer>
                <key>DisableRedirect</key>
                <integer>0</integer>
                <key>EnableCertificateRevocationCheck</key>
                <integer>0</integer>
                <key>EnableFallback</key>
                <integer>0</integer>
                <key>EnablePFS</key>
                <integer>0</integer>
                <key>ExtendedAuthEnabled</key>
                <false/>
                <key>IKESecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>LocalIdentifier</key>
                <string>vpn.test-ryuouen.link</string>
                <key>RemoteAddress</key>
                <string>vpn.test-ryuouen.link</string>
                <key>RemoteIdentifier</key>
                <string>vpn.test-ryuouen.link</string>
                <key>SharedSecret</key>
                <string>共有シークレットの値</string>
                <key>UseConfigurationAttributeInternalIPSubnet</key>
                <integer>0</integer>
            </dict>
            <key>PayloadDescription</key>
            <string>VPN設定を構成します</string>
            <key>PayloadDisplayName</key>
            <string>VPN</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.vpn.managed.任意のUUID</string>
            <key>PayloadType</key>
            <string>com.apple.vpn.managed</string>
            <key>PayloadUUID</key>
            <string>任意のUUID</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>Proxies</key>
            <dict>
                <key>HTTPEnable</key>
                <integer>0</integer>
                <key>HTTPSEnable</key>
                <integer>0</integer>
            </dict>
            <key>UserDefinedName</key>
            <string>IKEv2共有シークレット</string>
            <key>VPNType</key>
            <string>IKEv2</string>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>vpnテスト4</string>
    <key>PayloadIdentifier</key>
    <string>ryuouenMacMini.任意のUUID</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>任意のUUID</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

EAP証明書

/etc/strongswan/ipsec.conf

conn ikev2-vpn-tls
    auto=add
    compress=no
    type=tunnel
    fragmentation=yes
    forceencaps=yes
    left=%any
    leftid=@vpn.test-ryuouen.link
    leftcert=cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightauth=eap-tls
    rightid=vpnuser
    rightcert=vpnuser.cert.pem
    rightca="C=JP, ST=Fukuoka, O=自分のorganization, CN=自分のRoot CA"
    rightsourceip=192.168.100.0/24
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never
    eap_identity=%identity

構成プロファイル

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>Password</key>
            <string>証明書のパスワード</string>
            <key>PayloadCertificateFileName</key>
            <string>vpnuser.p12</string>
            <key>PayloadContent</key>
            <data>
            MII...
            証明書のデータ
            </data>
            <key>PayloadDescription</key>
            <string>PKCS#12フォーマットの証明書を追加します</string>
            <key>PayloadDisplayName</key>
            <string>vpnuser.p12</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.security.pkcs12.一意のUUID</string>
            <key>PayloadType</key>
            <string>com.apple.security.pkcs12</string>
            <key>PayloadUUID</key>
            <string>一意のUUID</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
        </dict>
        <dict>
            <key>DNS</key>
            <dict>
                <key>ServerAddresses</key>
                <array>
                    <string>8.8.8.8</string>
                    <string>8.8.4.4</string>
                </array>
                <key>SupplementalMatchDomainsNoSearch</key>
                <integer>0</integer>
            </dict>
            <key>IKEv2</key>
            <dict>
                <key>AuthenticationMethod</key>
                <string>None</string>
                <key>ChildSecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>DeadPeerDetectionRate</key>
                <string>Medium</string>
                <key>DisableMOBIKE</key>
                <false/>
                <key>DisableRedirect</key>
                <false/>
                <key>EnableCertificateRevocationCheck</key>
                <false/>
                <key>EnableFallback</key>
                <false/>
                <key>EnablePFS</key>
                <integer>0</integer>
                <key>ExtendedAuthEnabled</key>
                <true/>
                <key>IKESecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>LocalIdentifier</key>
                <string>vpnuser</string>
                <key>PayloadCertificateUUID</key>
                <string>証明書のUUID</string>
                <key>RemoteAddress</key>
                <string>vpn.test-ryuouen.link</string>
                <key>RemoteIdentifier</key>
                <string>vpn.test-ryuouen.link</string>
                <key>UseConfigurationAttributeInternalIPSubnet</key>
                <false/>
            </dict>
            <key>PayloadDescription</key>
            <string>VPN設定を構成します</string>
            <key>PayloadDisplayName</key>
            <string>VPN</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.vpn.managed.一意のUUID</string>
            <key>PayloadType</key>
            <string>com.apple.vpn.managed</string>
            <key>PayloadUUID</key>
            <string>一意のUUID</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>Proxies</key>
            <dict>
                <key>HTTPEnable</key>
                <integer>0</integer>
                <key>HTTPSEnable</key>
                <integer>0</integer>
            </dict>
            <key>UserDefinedName</key>
            <string>IKEv2証明書(eap)</string>
            <key>VPNType</key>
            <string>IKEv2</string>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>vpnテスト3</string>
    <key>PayloadIdentifier</key>
    <string>一意の文字列</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>一意のUUID</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

今回はここでおしまい

StrongswanでIKEv2のVPNサーバを構築する2

経緯

VPNサーバは構築した、、、
でもユーザーとパスワードですぐに突破されるからだめっぽいかもしれん

証明書がないとログインできないようにしよう

過去記事

m-shige1979.hatenablog.com

どのようにやるのか?

なんか以下のサイトをみたところstrongswan認証局を作成してクライアント証明書を発行できるとのこと 証明書のくだりはいまだによくわかってないのでひとまず記事の通りにやってみる

seinolab.jp

CA(認証局)の作成

※ sudoコマンドでroot権限に移動して作業する

CA用ディレクトリを作成

mkdir -p /etc/pki/myCA/cacerts

CA用のプライベート鍵を生成し、権限を変更

strongswan pki \
  --gen \
  --type rsa \
  --size 4096 \
  --outform pem > /etc/pki/myCA/cacerts/root.key.pem
chmod 600 /etc/pki/myCA/cacerts/root.key.pem

CA用のルート証明書を作成

strongswan pki --self --ca \
    --lifetime 3660 \
    --in /etc/pki/myCA/cacerts/root.key.pem \
    --type rsa \
    --dn "C=JP, ST=自分の地域, O=自分のorganization, CN=自分のRoot CA" \
    --outform pem > /etc/pki/myCA/cacerts/root.cert.pem

※DN値は各自の値に合わせる

x509形式に変換

openssl x509 \
    -in /etc/pki/myCA/cacerts/root.cert.pem \
    -outform DER \
    -out /etc/pki/myCA/cacerts/root.cert.der

CRL(証明書の失効リスト)を作成

mkdir -p /etc/pki/myCA/crls
strongswan pki \
    --signcrl \
    --cacert /etc/pki/myCA/cacerts/root.cert.pem \
    --cakey /etc/pki/myCA/cacerts/root.key.pem \
    --lifetime=150 \
    --outform pem > /etc/pki/myCA/crls/crl.pem

CAをStrongswanへ配備する

# tree /etc/pki/myCA/cacerts/
/etc/pki/myCA/cacerts/
├── root.cert.der
├── root.cert.pem
└── root.key.pem

0 directories, 3 files
#
# sudo ln -s /etc/pki/myCA/cacerts/root.cert.pem /etc/strongswan/ipsec.d/cacerts/
#

クライアント証明書の発行

※クライアントの識別名はvpnuserとして進める

ディレクトリを作成

mkdir -p /etc/pki/myCA/clients

鍵ファイルを作成し、権限を設定

strongswan pki \
    --gen \
    --type rsa \
    --size 2048 \
    --outform pem > /etc/pki/myCA/clients/vpnuser.key.pem
chmod 600 /etc/pki/myCA/clients/vpnuser.key.pem

公開鍵の形式へ変換

strongswan pki \
    --pub \
    --in /etc/pki/myCA/clients/vpnuser.key.pem \
    --type rsa > /etc/pki/myCA/clients/vpnuser.key.pem.pub

クライアント証明書作成

strongswan pki \
    --issue \
    --lifetime 3660 \
    --in /etc/pki/myCA/clients/vpnuser.key.pem.pub \
    --cacert /etc/pki/myCA/cacerts/root.cert.pem \
    --cakey /etc/pki/myCA/cacerts/root.key.pem \
    --dn "C=JP, O=自分のorganization, CN=vpnuser" \
    --san vpnuser \
    --outform pem > /etc/pki/myCA/clients/vpnuser.cert.pem

p12ファイルで出力

openssl pkcs12 -export \
    -inkey /etc/pki/myCA/clients/vpnuser.key.pem \
    -in /etc/pki/myCA/clients/vpnuser.cert.pem \
    -certfile /etc/pki/myCA/cacerts/root.cert.pem \
    -caname "自分のRoot CA" \
    -name "自分のorganization client certificate" \
    -out /etc/pki/myCA/clients/vpnuser.p12

クライアント証明書をStrongswanへ配備

sudo ln -s /etc/pki/myCA/clients/vpnuser.cert.pem /etc/strongswan/ipsec.d/certs/

Strongswan設定

/etc/strongswan/ipsec.conf

末尾に追加

conn ikev2-vpn-rsa
    auto=add
    compress=no
    type=tunnel
    fragmentation=yes
    forceencaps=yes
    left=%any
    leftid=@vpn.test-ryuouen.link
    leftcert=cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=vpnuser
    rightcert=vpnuser.cert.pem
    rightca="C=JP, ST=Fukuoka, O=mshige1979 organization, CN=mshige1979 Root CA"
    rightsourceip=192.168.100.0/24
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never
    eap_identity=%identity

自分の端末へp12ファイルをコピー

これは各自の方法で行う
以下は例

scp ec2-user@サーバアドレス:/etc/pki/myCA/clients/vpnuser.p12 ~/Downloads

証明書を信頼するように変更

できた

一旦、ユーザーパスワードのやつを消す

/etc/strongswan/ipsec.secret

~
~
"/etc/strongswan/ipsec.secrets" 6L, 135B                                                                              5,1          全て
# ipsec.secrets - strongSwan IPsec secrets file
: RSA "privkey.pem"

# ユーザーパスワード
#vpn_username : EAP "vpn_password"

おまけ

構成プロファイル

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>DNS</key>
            <dict>
                <key>ServerAddresses</key>
                <array>
                    <string>8.8.8.8</string>
                    <string>8.8.4.4</string>
                </array>
                <key>SupplementalMatchDomainsNoSearch</key>
                <integer>0</integer>
            </dict>
            <key>IKEv2</key>
            <dict>
                <key>AuthenticationMethod</key>
                <string>Certificate</string>
                <key>ChildSecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>DeadPeerDetectionRate</key>
                <string>Medium</string>
                <key>DisableMOBIKE</key>
                <integer>0</integer>
                <key>DisableRedirect</key>
                <integer>0</integer>
                <key>EnableCertificateRevocationCheck</key>
                <integer>0</integer>
                <key>EnableFallback</key>
                <integer>0</integer>
                <key>EnablePFS</key>
                <integer>0</integer>
                <key>IKESecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>LocalIdentifier</key>
                <string>vpnuser</string>
                <key>PayloadCertificateUUID</key>
                <string>システムが発行する可変値</string>
                <key>RemoteAddress</key>
                <string>vpn.test-ryuouen.link</string>
                <key>RemoteIdentifier</key>
                <string>vpn.test-ryuouen.link</string>
                <key>UseConfigurationAttributeInternalIPSubnet</key>
                <integer>0</integer>
            </dict>
            <key>PayloadDescription</key>
            <string>VPN設定を構成します</string>
            <key>PayloadDisplayName</key>
            <string>VPN</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.vpn.managed.システムが発行する可変値</string>
            <key>PayloadType</key>
            <string>com.apple.vpn.managed</string>
            <key>PayloadUUID</key>
            <string>システムが発行する可変値</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>Proxies</key>
            <dict>
                <key>HTTPEnable</key>
                <integer>0</integer>
                <key>HTTPSEnable</key>
                <integer>0</integer>
            </dict>
            <key>UserDefinedName</key>
            <string>IKEv2証明書</string>
            <key>VPNType</key>
            <string>IKEv2</string>
        </dict>
        <dict>
            <key>Password</key>
            <string>証明書のパスワード</string>
            <key>PayloadCertificateFileName</key>
            <string>vpnuser.p12</string>
            <key>PayloadContent</key>
            <data>
            多分、p12が発行する証明書のデータ
            </data>
            <key>PayloadDescription</key>
            <string>PKCS#12フォーマットの証明書を追加します</string>
            <key>PayloadDisplayName</key>
            <string>vpnuser.p12</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.security.pkcs12.システムが発行する可変値</string>
            <key>PayloadType</key>
            <string>com.apple.security.pkcs12</string>
            <key>PayloadUUID</key>
            <string>システムが発行する可変値</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>vpnテスト2</string>
    <key>PayloadIdentifier</key>
    <string>システムが発行する可変値</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>システムが発行する可変値</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

次は他の認証も試してみる

参考

Strongswan で IKEv2 VPN サーバを構築する 後編 | seinolab

StrongswanでIKEv2のVPNサーバを構築する

経緯

仕事でVPNサーバ使ったシステムがあるのだが 環境が碌にない状況でテストとかどうすんの?って感じの状況

とりあえず、VPNサーバないと話にならんので調査がてら構築する

作成するVPNサーバの環境

  • AWSのEC2
  • IKEv2
  • ユーザ・パスワードの簡易的なものを作成(あとで削除)

イメージはこんな感じ

やること

  1. 対象ドメインを準備
  2. セキュリティグループを作成し、EC2に追加
  3. EC2にセキュリティグループを追加し、ソースの宛先チェックを無効にする
  4. EC2にStrongswan、Certbotをインストール
  5. EC2にCertbotで証明書を作成し、証明書をStrongswanの場所へリンクを貼る
  6. Strongswanの設定ファイルを編集
  7. StrongswanのVPNの仮想IPをホストへルーティング
  8. 接続確認

作業

1. 対象ドメインを準備

vpn.test-ryuouen.link

として過程 ※EC2のIPアドレスをAレコードに設定しておくこと

2. セキュリティグループを作成

タイプ プロトコル ポート範囲 ソース
カスタムUDP UDP 500 0.0.0.0/0
カスタムUDP UDP 4500 0.0.0.0/0
カスタムプロトコル ESP(50) すべて 0.0.0.0/0
カスタムプロトコル AH(51) すべて 0.0.0.0/0

3. EC2にセキュリティグループを追加し、ソースの宛先チェックを無効にする

セキュリティグループを付与

ソース/宛先チェックを変更を無効とする

4. EC2にStrongswan、Certbotをインストール

sudo amazon-linux-extras install epel -y
sudo yum install strongswan -y
sudo yum install certbot -y

5. EC2にCertbotで証明書を作成し、証明書をStrongswanの場所へリンクを貼る

セキュリティグループに80番ポートを許可

※あとで外します

証明書発行

sudo certbot certonly \
    --standalone \
    -d vpn.test-ryuouen.link \
    -m mshige1979@ryuouen.net \
    --agree-tos -n

[ec2-user@ip-172-16-10-100 ~]$ sudo tree /etc/letsencrypt/live
/etc/letsencrypt/live
├── README
└── vpn.test-ryuouen.link
    ├── README
    ├── cert.pem -> ../../archive/vpn.test-ryuouen.link/cert1.pem
    ├── chain.pem -> ../../archive/vpn.test-ryuouen.link/chain1.pem
    ├── fullchain.pem -> ../../archive/vpn.test-ryuouen.link/fullchain1.pem
    └── privkey.pem -> ../../archive/vpn.test-ryuouen.link/privkey1.pem

1 directory, 6 files
[ec2-user@ip-172-16-10-100 ~]$

※ここで80番ポートは閉じておくこと

sudo ln -s /etc/letsencrypt/live/vpn.test-ryuouen.link/cert.pem /etc/strongswan/ipsec.d/certs/
sudo ln -s /etc/letsencrypt/live/vpn.test-ryuouen.link/chain.pem /etc/strongswan/ipsec.d/cacerts/
sudo ln -s /etc/letsencrypt/live/vpn.test-ryuouen.link/privkey.pem /etc/strongswan/ipsec.d/private/

6. Strongswanの設定ファイルを編集

設定ファイルバックアップ

sudo cp -p /etc/strongswan/ipsec.conf /etc/strongswan/ipsec.conf.org
sudo cp -p /etc/strongswan/ipsec.secrets /etc/strongswan/ipsec.secrets.org

/etc/strongswan/ipsec.conf

# basic configuration

config setup
        # strictcrlpolicy=yes
        # uniqueids = no

# これは共通の設定っぽい
conn %default
    keyexchange=ikev2
    ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024!
    esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1!
    dpdaction=clear
    dpddelay=300s
    rekey=no

# ユーザーとパスワードによる認証
conn ikev2-vpn-user
    auto=add
    compress=no
    type=tunnel
    fragmentation=yes
    forceencaps=yes
    left=%any
    leftid=@vpn.test-ryuouen.link       # VPNのドメイン
    leftcert=cert.pem                  # letsencryptの証明書
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightauth=eap-mschapv2              # EAPのユーザー認証らしい
    rightsourceip=192.168.100.0/24   # VPNクライアントのIP範囲らしい
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never
    eap_identity=%identity

/etc/strongswan/ipsec.secrets

# ipsec.secrets - strongSwan IPsec secrets file
: RSA "privkey.pem"

# ユーザーパスワード
vpn_username : EAP "vpn_password"

※今回はユーザー・パスワードによる認証のみ

起動

sudo systemctl enable strongswan
sudo systemctl start strongswan

7. StrongswanのVPNの仮想IPをホストへルーティング

sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE

なんか他のサイトに繋がらなくなったけどまあひとまずはここまで(多分、DNSサーバがらみ) 次は証明書とかの接続できるか試す予定

おまけ

Apple configurator2で作成した構成プロファイル

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>DNS</key>
            <dict>
                <key>ServerAddresses</key>
                <array>
                    <string>8.8.8.8</string>
                    <string>8.8.4.4</string>
                </array>
                <key>SupplementalMatchDomainsNoSearch</key>
                <integer>0</integer>
            </dict>
            <key>IKEv2</key>
            <dict>
                <key>AuthName</key>
                <string>サーバに設定したユーザー</string>
                <key>AuthPassword</key>
                <string>サーバに設定したパスワード</string>
                <key>AuthenticationMethod</key>
                <string>None</string>
                <key>ChildSecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>DeadPeerDetectionRate</key>
                <string>Medium</string>
                <key>DisableMOBIKE</key>
                <integer>0</integer>
                <key>DisableRedirect</key>
                <integer>0</integer>
                <key>EnableCertificateRevocationCheck</key>
                <integer>0</integer>
                <key>EnableFallback</key>
                <integer>0</integer>
                <key>EnablePFS</key>
                <integer>0</integer>
                <key>ExtendedAuthEnabled</key>
                <true/>
                <key>IKESecurityAssociationParameters</key>
                <dict>
                    <key>DiffieHellmanGroup</key>
                    <integer>14</integer>
                    <key>EncryptionAlgorithm</key>
                    <string>AES-256</string>
                    <key>IntegrityAlgorithm</key>
                    <string>SHA2-256</string>
                    <key>LifeTimeInMinutes</key>
                    <integer>1440</integer>
                </dict>
                <key>LocalIdentifier</key>
                <string>vpn.test-ryuouen.link</string>
                <key>RemoteAddress</key>
                <string>vpn.test-ryuouen.link</string>
                <key>RemoteIdentifier</key>
                <string>vpn.test-ryuouen.link</string>
                <key>UseConfigurationAttributeInternalIPSubnet</key>
                <integer>0</integer>
            </dict>
            <key>PayloadDescription</key>
            <string>VPN設定を構成します</string>
            <key>PayloadDisplayName</key>
            <string>VPN</string>
            <key>PayloadIdentifier</key>
            <string>com.apple.vpn.managed.ここはなんかシステムで動的に変わる</string>
            <key>PayloadType</key>
            <string>com.apple.vpn.managed</string>
            <key>PayloadUUID</key>
            <string>ここはなんかシステムで動的に変わる</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>Proxies</key>
            <dict>
                <key>HTTPEnable</key>
                <integer>0</integer>
                <key>HTTPSEnable</key>
                <integer>0</integer>
            </dict>
            <key>UserDefinedName</key>
            <string>vpn.test-ryuouen.link</string>
            <key>VPNType</key>
            <string>IKEv2</string>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>vpnテスト1</string>
    <key>PayloadIdentifier</key>
    <string>ここはなんかシステムで動的に変わる</string>
    <key>PayloadRemovalDisallowed</key>
    <false/>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadUUID</key>
    <string>ここはなんかシステムで動的に変わる</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

【補足】iptablesの設定が再起動したら消えてしまう・・・

設定を外付け保存

sudo iptables-save > /etc/sysconfig/iptables

起動スクリプトに追加

sudo vi /etc/rc.d/rc.local
----
# 追記
if [ -f /etc/sysconfig/iptables ]; then
      /sbin/iptables-restore < /etc/sysconfig/iptables
fi
----

一応実行権限付与

sudo chmod +x /etc/rc.d/rc.local

参考

strongSwanでLet’s Encrypt証明書を使ったIKEv2 VPNサーバーを作る – World203
特集記事 : 時代は変遷するもの… [Gentoo Linuxな生活/IKEv2 VPNで悩む] - Nest Of Hawk
Strongswan で IKEv2 VPN サーバを構築する 前編 | seinolab
Strongswan で IKEv2 VPN サーバを構築する 後編 | seinolab
strongSwanにiPhoneからオレオレ証明書認証でIPsec IKEv2を繋げる - Qiita

感謝

関連記事

m-shige1979.hatenablog.com m-shige1979.hatenablog.com

Amazon Linux2023を起動してみた

Amazon Linux 2023

aws.amazon.com

ほー

とりあえず起動してみた

設定?、雑でよいかね

めんどうなんでパブリックに配備

動的IPつけ忘れたんで、EIPで付与

はいれた あれ?なんか以前、Windows経由で入ろうとしたら入れなかったんだけどなーまあ、いいか

以下を参考にいろいろみてみた

Amazon Linux 2023とAmazon Linux2のデフォルトで起動しているサービスやインストールされているパッケージを比較してみた | DevelopersIO

  • SELINUX付き
  • crond未インストール
  • /var/log/messageとかない、あるのはjournalctl

まとめ

rsyslogいれておけばよいのかな まあ、そのうちjournalctlとcloudwatch logsをよい感じに連携する方法が見つかると信じておく パッケージはまあ、大丈夫でしょ 今年出たっぽいのでそのうち良い案とか出ることを期待しますm( )m

AWS Chatbotでslackにメッセージを投げたい

AWS Chatbot

aws.amazon.com

とりあえずやってみる

Chatbot設定

slackを選択してクライアントの設定を行う

slackのワークスペースを用意

リクエスト画面で許可する

AWS上で作成されたことを確認

チャネルを設定

SNS

トピックの作成

設定

ChatbotにSNSを連携

SNSトピックを連携

通知されない?

cloudwatch logsで確認

Encountered error while sending message to Slack: Slack Web API returned unsuccessful response 
( ok: false, error code: channel_not_found, full response body: ChatPostMessageResponse
(ok=false, warning=null, error=channel_not_found, needed=null, provided=null, 
deprecatedArgument=null, responseMetadata=null, channel=null, ts=null, message=null)).

slackのプライベートチャネルにawsを招待

今回はここまで

所感

今回はテストメッセージを送るところまで確認できた cloudwatchのアラートやEC2からメッセージを送れるかも試してみたい

参考

【初心者向け】Amazon SNSからSlackに通知をしてみよう | SunnyCloud

AWS Chatbotを使ってみた - サーバーワークスエンジニアブログ

AWS Chatbotを使ってSlackのプライベートチャンネルに連携できないときの対処方法 | DevelopersIO