Azure VPN – StrongsSwan でBGP接続

シェアする

構成

azure vpngatewayへ、Linux VMにstrongswanを導入してIPsec接続し、quaggaを利用し、BGPピアを構成する。
Azure VPN Gatewayを、Active/Active構成にして、耐障害性を向上させる。

前提条件

Azure VPNgateway
  • SKU VpnGw1
  • 手動デプロイ済みで、オンプレIPSecルータと接続あり
  • ルートベース S2S IPSec接続 (IKE v2)
Linux VM
  • ディストリビューション Fedora core 30
  • strongswan 5.7.2-2.fc30
  • quagga 1.2.4-8.fc30

OS設定、必要なパッケージの導入

既存パッケージの最新化
yum -y update
タイムゾーン設定
timedatectl set-timezone Asia/Tokyo
SELinux無効化

/etc/sysconfig/selinux

SELINUX=disabled
SELINUXTYPE=targeted
ロケール、キーマップの設定

参考資料

必要なパッケージの導入
yum -y install strongswan quagga telnet

Linux VM側設定

strongswan設定

/etc/strongswan/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file
config setup
    charondebug="cfg 2, dmn 2, ike 2, net 2"

conn azure-1
    closeaction=restart

    # Dead Peer Discovery
    dpdaction=restart
    dpddelay=10s

    # cipher suites
    ike=aes256-sha256-modp2048s256
    esp=aes256-sha256-modp2048s256

    reauth=no
    keyexchange=ikev2 # Route-based gateway
    mobike=no
    ikelifetime=28800s
    keylife=3600s
    keyingtries=%forever
    authby=secret

    installpolicy=yes
    compress=no

    type=tunnel
    auto=start
    mark=100

    # Self site
    left=10.aa.aa.aa
    leftsubnet=0.0.0.0/0 # because of VTI routing
    leftid=10.aa.aa.aa
    leftupdown=/etc/strongswan/ipsec-vti.sh

    # Remote site
    right=xxx.xxx.xxx.xxx #Azure VPN Gateway's Primary IP address
    rightsubnet=0.0.0.0/0 # because of VTI routing
    rightid=xxx.xxx.xxx.xxx

conn azure-2
    closeaction=restart

    # Dead Peer Discovery
    dpdaction=restart
    dpddelay=10s

    # cipher suites
    ike=aes256-sha256-modp2048s256
    esp=aes256-sha256-modp2048s256

    reauth=no
    keyexchange=ikev2 # Route-based gateway
    mobike=no
    ikelifetime=28800s
    keylife=3600s
    keyingtries=%forever
    authby=secret

    installpolicy=yes
    compress=no

    type=tunnel
    auto=start
    mark=200

    # Self site
    left=10.aa.aa.aa # vpn source interface, like eth0
    leftsubnet=0.0.0.0/0 # because of VTI routing
    leftid=10.xx.xx.xx
    leftupdown=/etc/strongswan/ipsec-vti.sh

    # Remote site
    right=yyy.yyy.yyy.yyy #Azure VPN Gateway's Secondary IP address
    rightsubnet=0.0.0.0/0 # because of VTI routing
    rightid=yyy.yyy.yyy.yyy
/etc/strongswan/secrets
# ipsec.secrets - strongSwan IPsec secrets file
xxx.xxx.xxx.xxx : PSK "secret1"
yyy.yyy.yyy.yyy : PSK "secret2"
/etc/strongswan/ipsec-vti.sh

ファイルを作成します。

#!/bin/bash

IP=$(which ip)
IPTABLES=$(which iptables)
 
PLUTO_MARK_OUT_ARR=(${PLUTO_MARK_OUT//// })
PLUTO_MARK_IN_ARR=(${PLUTO_MARK_IN//// })

case "${PLUTO_CONNECTION}" in
  azure-1)
    VTI_INTERFACE=vti${PLUTO_MARK_IN_ARR[0]}
    BGP_PEER_ADDR=10.pp.pp.4/32
    ;;
  azure-2)
    VTI_INTERFACE=vti${PLUTO_MARK_IN_ARR[0]}
    BGP_PEER_ADDR=10.pp.pp.5/32
    ;;
esac

# output parameters to /var/log/messages for debug
    logger "ipsec-vti.sh: ================================================="
    logger "ipsec-vti.sh: PLUTO_CONNECTION = ${PLUTO_CONNECTION}"
    logger "ipsec-vti.sh: PLUTO_VERB = ${PLUTO_VERB}"
    logger "ipsec-vti.sh: VTI_INTERFACE = ${VTI_INTERFACE}"
    logger "ipsec-vti.sh: BGP_PEER_ADDR = ${BGP_PEER_ADDR}"
    logger "ipsec-vti.sh: PLUTO_ME = ${PLUTO_ME}"
    logger "ipsec-vti.sh: PLUTO_PEER = ${PLUTO_PEER}"
    logger "ipsec-vti.sh: PLUTO_MARK_IN_ARR[0] = ${PLUTO_MARK_IN_ARR[0]}"
    logger "ipsec-vti.sh: PLUTO_MARK_OUT_ARR[0] = ${PLUTO_MARK_OUT_ARR[0]}"
    logger "ipsec-vti.sh: PLUTO_MARK_IN = ${PLUTO_MARK_IN}"
    logger "ipsec-vti.sh: ================================================="
 
case "${PLUTO_VERB}" in
    up-client)
        $IP link add ${VTI_INTERFACE} type vti local ${PLUTO_ME} remote ${PLUTO_PEER} okey ${PLUTO_MARK_OUT_ARR[0]} ikey ${PLUTO_MARK_IN_ARR[0]}
        sysctl -w net.ipv4.conf.${VTI_INTERFACE}.disable_policy=1
        sysctl -w net.ipv4.conf.${VTI_INTERFACE}.rp_filter=2 || sysctl -w net.ipv4.conf.${VTI_INTERFACE}.rp_filter=0
        $IP link set ${VTI_INTERFACE} up mtu 1200
        $IPTABLES -t mangle -I FORWARD -o ${VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
        $IPTABLES -t mangle -I INPUT -p esp -s ${PLUTO_PEER} -d ${PLUTO_ME} -j MARK --set-xmark ${PLUTO_MARK_IN}
        $IP route add ${BGP_PEER_ADDR} dev ${VTI_INTERFACE}
        ;;
    down-client)
        $IP link del ${VTI_INTERFACE}
        $IPTABLES -t mangle -D FORWARD -o ${VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
        $IPTABLES -t mangle -D INPUT -p esp -s ${PLUTO_PEER} -d ${PLUTO_ME} -j MARK --set-xmark ${PLUTO_MARK_IN}
        ;;
esac

実行権限を付与します

chmod o+x /etc/strongswan/ipsec-vti.sh
/etc/strongswan/strongswan.d/charon.conf

以下のように修正します。

[...]
    # Install routes into a separate routing table for established IPsec
    # tunnels.
    install_routes = no
 
    # Install virtual IP addresses.
    install_virtual_ip = no
[...]
自動起動設定
systemctl enable strongswan
systemctl start strongswan

quagga設定

/etc/quagga/bgpd.conf
hostname bgpd
password xxxxxxxx
log file /var/log/quagga/bgpd.log
!
debug bgp updates
!
router bgp 65521
 bgp router-id 10.aa.aa.aa.aa
!
! listing advertize routes
!
! under this line is examples
 network 10.1.0.0/16
!
 neighbor 10.pp.pp.4 remote-as 65515
 neighbor 10.pp.pp.4 ebgp-multihop 255
 neighbor 10.pp.pp.5 remote-as 65515
 neighbor 10.pp.pp.5 ebgp-multihop 255
 neighbor 10.pp.pp.5 route-map RM_LOWER_PRIORITY out
!
 address-family ipv6
 exit-address-family
 exit
!
! setlower priority 10.pp.pp.5 peer route
!
route-map RM_LOWER_PRIORITY permit 10
 set as-path prepend 65521 65521 65521
!
line vty
!
/etc/quagga/zebra.conf
hostname zebra
password xxxxxxxx
!
interface eth0
!
interface ip_vti0
!
interface lo
!
interface vti100
!
interface vti200
!
route-map RM_SET_SRC permit 10
 set src 10.aa.aa.aa
!
ip forwarding
ipv6 forwarding
!
ip protocol bgp route-map RM_SET_SRC
!
line vty
!
自動起動設定
systemctl enable zebra
systemctl start zebra
systemctl enable bgpd
systemctl start bgpd

bgpd側の確認

telnet localhost 2605
! 特権モードに移行
> enable
!
! Hello message 送受信状況の確認
!
# show ip bgp summary
!
! ピアリング状態、受信したルートの確認
!
# show ip bgp

Azure VPN Gateway設定

Azure Powershellが利用できる環境構築

Az Module v2.5 導入手順
参考 焦げログ

Azure Powershellでサインインして、サブスクリプションを選択

公式(サインイン)
公式(サブスクリプション選択)

// Powershell
Connect-AzAccount
Get-AzSubscription
Set-AzContext -Subscription

VPN Gatewayに、2つ目のIPを付与し、Active/Active構成に変更

すでに、オンプレIPsecルータとVPN接続している状況へ、今回は追加接続する
公式(Azure VPN ゲートウェイで、アクティブ/アクティブ S2S VPN 接続を構成する)

$GWName = "prod-vpn-gateway"
$VNetName = "prod-vnet"
$RG = "res-prod"
$GWIPName2 = "prod-vpn-ip2"
$GWIPconf2 = "prod-vpn-ipconfig2"

$vnet = Get-AzVirtualNetwork -Name $VNetName -ResourceGroupName $RG
$subnet = Get-AzVirtualNetworkSubnetConfig -Name 'GatewaySubnet' -VirtualNetwork $vnet
$gw = Get-AzVirtualNetworkGateway -Name $GWName -ResourceGroupName $RG
$location = $gw.Location

$gwpip2 = New-AzPublicIpAddress -Name $GWIPName2 -ResourceGroupName $RG -Location $location -AllocationMethod Dynamic
Add-AzVirtualNetworkGatewayIpConfig -VirtualNetworkGateway $gw -Name $GWIPconf2 -Subnet $subnet -PublicIpAddress $gwpip2

Active / Activeに構成変更する。(30~40分かかる)

// powershell
Set-AzVirtualNetworkGateway -VirtualNetworkGateway $gw -EnableActiveActiveFeature

ローカルネットワークゲートウェイ、コネクションを作成

参考 公式(カスタムIPポリシー追加)

// powershell
$PSK = 'secret1'
Set-AzDefault -ResourceGroupName "res-prod"

// bbb.bbb.bbb.bbb is Linux VM Grobal Address
New-AzLocalNetworkGateway -Name "prod-strongswan01" -Location "japaneast" -GatewayIpAddress "bbb.bbb.bbb.bbb" -AddressPrefix "10.aa.aa.aa.aa/32" -Asn 65521 -BgpPeeringAddress "10.aa.aa.aa.aa"


$ipsecpolicy = New-AzIpsecPolicy -IkeEncryption AES256 -IkeIntegrity SHA256 -DhGroup DHGroup24 -IpsecEncryption AES256 -IpsecIntegrity SHA256 -PfsGroup PFS24 -SALifeTimeSeconds 3600 -SADataSizeKilobytes 102400000

$vnetgw = Get-AzVirtualNetworkGateway -Name "zs3-vpn-gateway"

$lng1 = Get-AzLocalNetworkGateway -Name "zs3-orcaseilvpn01"
New-AzVirtualNetworkGatewayConnection -Name "zs3-orcaseilvpn01_to_zs3-vpn-gateway" -VirtualNetworkGateway1 $vnetgw -LocalNetworkGateway2 $lng1 -Location "japaneast" -ConnectionType IPsec -IpsecPolicies $ipsecpolicy -SharedKey $PSK -EnableBGP $True

Azure側の確認

Set-AzDefault -ResourceGroupName "res-prod"

Get-AzVirtualNetworkGatewayAdvertisedRoute -VirtualNetworkGatewayName "prod-vpn-gateway" -Peer "10.aa.aa.aa" | FT -AutoSize

Get-AzVirtualNetworkGatewayBgpPeerStatus -VirtualNetworkGatewayName "prod-vpn-gateway" -Peer "10.aa.aa.aa"

LocalAddress      : 10.pp.pp.5
Neighbor          : 10.aa.aa.aa
Asn               : 65521
State             : Connected
ConnectedDuration : 00:05:19.8264000
RoutesReceived    : 2
MessagesSent      : 9
MessagesReceived  : 10

LocalAddress      : 10.pp.pp.4
Neighbor          : 10.aa.aa.aa
Asn               : 65521
State             : Connected
ConnectedDuration : 00:05:19.8369274
RoutesReceived    : 2
MessagesSent      : 10
MessagesReceived  : 11

Get-AzVirtualNetworkGatewayLearnedRoute -VirtualNetworkGatewayName "prod-vpn-gateway" | FT -AutoSize

LocalAddress Network         NextHop      SourcePeer   Origin  AsPath                  Weight
------------ -------         -------      ----------   ------  ------                  ------
10.pp.pp.5  10.10.0.0/16    10.pp.pp.4    10.pp.pp.4   IBgp                             32768
10.pp.pp.5  10.aa.aa.aa/32                10.pp.pp.5   Network                          32768
10.pp.pp.5  10.10.0.0/16    10.aa.aa.aa   10.72.254.21 EBgp    65521-65521-65521-65521  32768