forked from erjosito/azcli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
routeserver-vpngw.azcli
484 lines (452 loc) · 24.9 KB
/
routeserver-vpngw.azcli
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
##############################################################
#
# This script demonstrates how to configure Linux NVAs in
# Azure with BGP (bird) and VPN (StrongSwan) on Ubuntu 18.04.
#
# An NVA in Azure will inject a 0.0.0.0/0 to the RS, a VPN
# to onprem will be simulated with a 2nd Linux NVA.
#
# Exec summary:
# - 0.0.0.0/0 is not re-advertised by the VPNGW towards onprem
# - Splitting 0/0 in two works just fine
# - The GatewaySubnet does not need any RT to prevent it from
# learning the default routes (!!!!)
# - The NVA needs a default RT to prevent it from learning the
# default
#
# Jose Moreno, March 2021
##############################################################
# Variables
rg=nva
location=westeurope
vnet_name=hub
vnet_prefix=10.1.0.0/16
gw_subnet_name=GatewaySubnet
gw_subnet_prefix=10.1.0.0/24
vpngw_asn=65501
rs_subnet_name=RouteServersubnet
rs_subnet_prefix=10.1.1.0/24
nva_subnet_name=nva
nva_subnet_prefix=10.1.2.0/24
vm_subnet_name=vm
vm_subnet_prefix=10.1.10.0/24
vm_size=Standard_B1s
onprem_vnet_name=onprem
onprem_vnet_prefix=10.2.0.0/16
onprem_nva_subnet_name=nva
onprem_nva_subnet_prefix=10.2.2.0/24
publisher=Canonical
offer=UbuntuServer
sku=18.04-LTS
version=$(az vm image list -p $publisher -f $offer -s $sku --all --query '[0].version' -o tsv 2>/dev/null)
psk=Microsoft123!
# Alternatively generate a random string
# psk=$(openssl rand -base64 64)
# psk=${psk//$'\n'/} # Remove line breaks
# Auxiliary function to get the first IP of a subnet (default gateway)
function first_ip(){
subnet=$1
IP=$(echo $subnet | cut -d/ -f 1)
IP_HEX=$(printf '%.2X%.2X%.2X%.2X\n' `echo $IP | sed -e 's/\./ /g'`)
NEXT_IP_HEX=$(printf %.8X `echo $(( 0x$IP_HEX + 1 ))`)
NEXT_IP=$(printf '%d.%d.%d.%d\n' `echo $NEXT_IP_HEX | sed -r 's/(..)/0x\1 /g'`)
echo "$NEXT_IP"
}
# Auxiliary function to wait until a resource has finished creation (either Successful or Failed)
function wait_until_finished {
wait_interval=15
resource_id=$1
resource_name=$(echo $resource_id | cut -d/ -f 9)
echo "Waiting for resource $resource_name to finish provisioning..."
start_time=`date +%s`
state=$(az resource show --id $resource_id --query properties.provisioningState -o tsv)
until [[ "$state" == "Succeeded" ]] || [[ "$state" == "Failed" ]] || [[ -z "$state" ]]
do
sleep $wait_interval
state=$(az resource show --id $resource_id --query properties.provisioningState -o tsv)
done
if [[ -z "$state" ]]
then
echo "Something really bad happened..."
else
run_time=$(expr `date +%s` - $start_time)
((minutes=${run_time}/60))
((seconds=${run_time}%60))
echo "Resource $resource_name provisioning state is $state, wait time $minutes minutes and $seconds seconds"
fi
}
# Create Vnets and subnets
az group create -n $rg -l $location
az network vnet create -g $rg -n $vnet_name --address-prefix $vnet_prefix --subnet-name $vm_subnet_name --subnet-prefix $vm_subnet_prefix
az network vnet subnet create --vnet-name $vnet_name -g $rg -n $gw_subnet_name --address-prefix $gw_subnet_prefix
az network vnet subnet create --vnet-name $vnet_name -g $rg -n $rs_subnet_name --address-prefix $rs_subnet_prefix
az network vnet subnet create --vnet-name $vnet_name -g $rg -n $nva_subnet_name --address-prefix $nva_subnet_prefix
az network vnet create -g $rg -n $onprem_vnet_name --address-prefix $onprem_vnet_prefix --subnet-name $onprem_nva_subnet_name --subnet-prefix $onprem_nva_subnet_prefix
# Start VNG creation
az network public-ip create -g $rg -n vpngw-pipa --sku Basic --allocation-method Dynamic -l $location
az network public-ip create -g $rg -n vpngw-pipb --sku Basic --allocation-method Dynamic -l $location
az network vnet-gateway create -g "$rg" --sku VpnGw1 --gateway-type Vpn --vpn-type RouteBased --vnet $vnet_name -n vpngw --asn $vpngw_asn --public-ip-address vpngw-pipa vpngw-pipb --no-wait
# Create VM for testing purposes
azurevm_name=azurevm
azurevm_pip_name="${azurevm_name}-pip"
az network nsg create -n "${azurevm_name}-nsg" -g $rg
az network nsg rule create -n SSH --nsg-name "${azurevm_name}-nsg" -g $rg --priority 1000 --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -n ICMP --nsg-name "${azurevm_name}-nsg" -g $rg --priority 1030 --destination-port-ranges '*' --access Allow --protocol Icmp
az vm create -n $azurevm_name -g $rg -l $location --image ubuntuLTS --generate-ssh-keys --nsg "${azurevm_name}-nsg" \
--public-ip-address $azurevm_pip_name --vnet-name $vnet_name --size $vm_size --subnet $vm_subnet_name
azurevm_pip_ip=$(az network public-ip show -n $azurevm_pip_name --query ipAddress -o tsv -g $rg) && echo $azurevm_pip_ip
azurevm_nic_id=$(az vm show -n $azurevm_name -g "$rg" --query 'networkProfile.networkInterfaces[0].id' -o tsv)
azurevm_private_ip=$(az network nic show --ids $azurevm_nic_id --query 'ipConfigurations[0].privateIpAddress' -o tsv) && echo $azurevm_private_ip
# Create Azure NVA with Bird and StrongSwan (only Bird is required for this scenario)
nva_asn=65001
nva_name=nva
nva_pip=${nva_name}-pip
nva_cloudinit_file=/tmp/nva_cloudinit.txt
nva_default_gw=$(first_ip "$nva_subnet_prefix") && echo $nva_default_gw
cat <<EOF > $nva_cloudinit_file
#cloud-config
runcmd:
- apt update
- UCF_FORCE_CONFOLD=1 DEBIAN_FRONTEND=noninteractive apt install -y bird strongswan --fix-missing
- sysctl -w net.ipv4.ip_forward=1
- sysctl -w net.ipv4.conf.all.accept_redirects = 0
- sysctl -w net.ipv4.conf.all.send_redirects = 0
EOF
az network nsg create -n "${nva_name}-nsg" -g $rg
az network nsg rule create -n SSH --nsg-name "${nva_name}-nsg" -g $rg --priority 1000 --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -n IKE --nsg-name "${nva_name}-nsg" -g $rg --priority 1010 --destination-port-ranges 4500 --access Allow --protocol Udp
az network nsg rule create -n IPsec --nsg-name "${nva_name}-nsg" -g $rg --priority 1020 --destination-port-ranges 500 --access Allow --protocol Udp
az network nsg rule create -n ICMP --nsg-name "${nva_name}-nsg" -g $rg --priority 1030 --destination-port-ranges '*' --access Allow --protocol Icmp
az network nsg rule create -n Webin --nsg-name "${nva_name}-nsg" -g $rg --priority 1040 --source-address-prefixes 'VirtualNetwork' --destination-port-ranges 80 443 --access Allow --protocol Tcp
az network public-ip create -g $rg -n "$nva_pip" --allocation-method Dynamic --sku Basic
az network nic create -n "${nva_name}-nic0" -g $rg --vnet-name $vnet_name --subnet $nva_subnet_name --network-security-group "${nva_name}-nsg" --public-ip-address "$nva_pip" --ip-forwarding
az vm create -n $nva_name -g $rg -l $location --image "${publisher}:${offer}:${sku}:${version}" --generate-ssh-keys \
--size ${vm_size} --custom-data "$nva_cloudinit_file" --nics "${nva_name}-nic0"
nva_pip_ip=$(az network public-ip show -n $nva_pip -g $rg --query ipAddress -o tsv) && echo $nva_pip_ip
nva_private_ip=$(az network nic show -n "${nva_name}-nic0" -g $rg --query 'ipConfigurations[0].privateIpAddress' -o tsv) && echo $nva_private_ip
# Configure SNAT in the NVA for traffic to Internet (not in the 10.0.0.0/0 range)
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo iptables -t nat -A POSTROUTING ! -d '10.0.0.0/8' -o eth0 -j MASQUERADE"
# Simulation of onprem with a different Azure VNet and NVA
onprem_nva_asn=65002
onprem_nva_name=onpremnva
onprem_nva_pip=${onprem_nva_name}-pip
nva_cloudinit_file=/tmp/nva_cloudinit.txt
cat <<EOF > $nva_cloudinit_file
#cloud-config
runcmd:
- apt update
- UCF_FORCE_CONFOLD=1 DEBIAN_FRONTEND=noninteractive apt install -y bird strongswan --fix-missing
- sysctl -w net.ipv4.ip_forward=1
- sysctl -w net.ipv4.conf.all.accept_redirects = 0
- sysctl -w net.ipv4.conf.all.send_redirects = 0
EOF
az network nsg create -n "${onprem_nva_name}-nsg" -g $rg
az network nsg rule create -n SSH --nsg-name "${onprem_nva_name}-nsg" -g $rg --priority 1000 --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -n IKE --nsg-name "${onprem_nva_name}-nsg" -g $rg --priority 1010 --destination-port-ranges 4500 --access Allow --protocol Udp
az network nsg rule create -n IPsec --nsg-name "${onprem_nva_name}-nsg" -g $rg --priority 1020 --destination-port-ranges 500 --access Allow --protocol Udp
az network nsg rule create -n ICMP --nsg-name "${onprem_nva_name}-nsg" -g $rg --priority 1030 --destination-port-ranges '*' --access Allow --protocol Icmp
az vm create -n $onprem_nva_name -g $rg -l $location --image ubuntuLTS --generate-ssh-keys \
--public-ip-address $onprem_nva_pip --vnet-name $onprem_vnet_name --size $vm_size --subnet $onprem_nva_subnet_name \
--custom-data $nva_cloudinit_file --nsg "${onprem_nva_name}-nsg"
onprem_nva_nic_id=$(az vm show -n $onprem_nva_name -g "$rg" --query 'networkProfile.networkInterfaces[0].id' -o tsv)
az network nic update --ids $onprem_nva_nic_id --ip-forwarding
onprem_nva_pip_ip=$(az network public-ip show -n $onprem_nva_pip -g $rg --query ipAddress -o tsv) && echo $onprem_nva_pip_ip
onprem_nva_private_ip=$(az network nic show --ids $onprem_nva_nic_id --query 'ipConfigurations[0].privateIpAddress' -o tsv) && echo $onprem_nva_private_ip
onprem_nva_default_gw=$(first_ip "$onprem_nva_subnet_prefix") && echo $onprem_nva_default_gw
sleep 30 # It can take some time for the bird/ipsec daemons to start
# Create Local Network Gateway
az network local-gateway create -g "$rg" -n onprem --gateway-ip-address "$onprem_nva_pip_ip" \
--local-address-prefixes "${onprem_nva_private_ip}/32" --asn "$onprem_nva_asn" --bgp-peering-address "$onprem_nva_private_ip" --peer-weight 0
# Wait until VNet GW is successfully provisioned
vpngw_id=$(az network vnet-gateway show -g $rg -n vpngw --query 'id' -o tsv)
wait_until_finished $vpngw_id
# Create VPN connection
az network vpn-connection create -n onprem -g $rg -l $location --vnet-gateway1 vpngw --local-gateway2 onprem --shared-key $psk --enable-bgp
# Deploy RS (no --no-wait option)
rs_subnet_id=$(az network vnet subnet show -n $rs_subnet_name --vnet-name $vnet_name -g $rg --query id -o tsv)
az network routeserver create -n rs -g $rg --hosted-subnet $rs_subnet_id -l $location
az network routeserver update -n rs -g $rg --allow-b2b-traffic
# Configure StrongSwan VPN in onprem NVA
vpngw_asn=$(az network vnet-gateway show -n vpngw -g $rg --query 'bgpSettings.asn' -o tsv)
vpngw_pip_0=$(az network vnet-gateway show -n vpngw -g $rg --query 'bgpSettings.bgpPeeringAddresses[0].tunnelIpAddresses[0]' -o tsv) && echo $vpngw_pip_0
vpngw_private_ip_0=$(az network vnet-gateway show -n vpngw -g $rg --query 'bgpSettings.bgpPeeringAddresses[0].defaultBgpIpAddresses[0]' -o tsv) && echo $vpngw_private_ip_0
vpngw_pip_1=$(az network vnet-gateway show -n vpngw -g $rg --query 'bgpSettings.bgpPeeringAddresses[1].tunnelIpAddresses[0]' -o tsv) && echo $vpngw_pip_1
vpngw_private_ip_1=$(az network vnet-gateway show -n vpngw -g $rg --query 'bgpSettings.bgpPeeringAddresses[1].defaultBgpIpAddresses[0]' -o tsv) && echo $vpngw_private_ip_1
# VTI interfaces and static routes
# Note these changes are not reboot-persistent!!!
echo "Configuring VPN between Azure:${vpngw_pip_0}/${vpngw_private_ip_0} and B:${onprem_nva_pip_ip}/${onprem_nva_private_ip}..."
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip tunnel add vti0 local $onprem_nva_private_ip remote $vpngw_pip_0 mode vti key 12"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo sysctl -w net.ipv4.conf.vti0.disable_policy=1"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip link set up dev vti0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip route add ${vpngw_private_ip_0}/32 dev vti0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip tunnel add vti1 local $onprem_nva_private_ip remote $vpngw_pip_1 mode vti key 11"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo sysctl -w net.ipv4.conf.vti1.disable_policy=1"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip link set up dev vti1"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip route add ${vpngw_private_ip_1}/32 dev vti1"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo sed -i 's/# install_routes = yes/install_routes = no/' /etc/strongswan.d/charon.conf"
myip=$(curl -s4 ifconfig.co) && echo $myip
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip route add ${vpngw_pip_0}/32 via $onprem_nva_default_gw"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip route add ${vpngw_pip_1}/32 via $onprem_nva_default_gw"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ip route add ${myip}/32 via $onprem_nva_default_gw" # To not lose SSH connectivity
# IPsec config files
psk_file=/tmp/ipsec.secrets
cat <<EOF > $psk_file
$onprem_nva_pip_ip $vpngw_pip_0 : PSK "$psk"
$onprem_nva_pip_ip $vpngw_pip_1 : PSK "$psk"
EOF
ipsec_file=/tmp/ipsec.conf
cat <<EOF > $ipsec_file
config setup
charondebug="all"
uniqueids=yes
strictcrlpolicy=no
conn vng0
authby=secret
leftid=$onprem_nva_pip_ip
leftsubnet=0.0.0.0/0
right=$vpngw_pip_0
rightsubnet=0.0.0.0/0
keyexchange=ikev2
ikelifetime=28800s
keylife=3600s
keyingtries=3
compress=yes
auto=start
ike=aes256-sha1-modp1024
esp=aes256-sha1
mark=12
conn vng1
authby=secret
leftid=$onprem_nva_pip_ip
leftsubnet=0.0.0.0/0
right=$vpngw_pip_1
rightsubnet=0.0.0.0/0
keyexchange=ikev2
ikelifetime=28800s
keylife=3600s
keyingtries=3
compress=yes
auto=start
ike=aes256-sha1-modp1024
esp=aes256-sha1
mark=11
EOF
# Copy files to NVA and restart ipsec daemon
username=$(whoami)
scp $psk_file $onprem_nva_pip_ip:/home/$username/ipsec.secrets
scp $ipsec_file $onprem_nva_pip_ip:/home/$username/ipsec.conf
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo mv ./ipsec.* /etc/"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo systemctl restart ipsec"
# Configure BGP with Bird (azure NVA to RS)
rs_asn=$(az network routeserver show -n rs -g $rg --query 'virtualRouterAsn' -o tsv) && echo $rs_asn
rs_ip1=$(az network routeserver show -n rs -g $rg --query 'virtualRouterIps[0]' -o tsv) && echo $rs_ip1
rs_ip2=$(az network routeserver show -n rs -g $rg --query 'virtualRouterIps[1]' -o tsv) && echo $rs_ip2
bird_config_file=/tmp/bird.conf
cat <<EOF > $bird_config_file
log syslog all;
router id $nva_private_ip;
protocol device {
scan time 10;
}
protocol direct {
disabled;
}
protocol kernel {
preference 254;
learn;
merge paths on;
import filter {
reject;
};
export filter {
reject;
};
}
protocol static {
import all;
# Test route
route 1.1.1.1/32 via $nva_default_gw;
# Default
route 0.0.0.0/0 via $nva_default_gw;
route 0.0.0.0/1 via $nva_default_gw;
route 128.0.0.0/1 via $nva_default_gw;
# Vnet prefix
route $vnet_prefix via $nva_default_gw;
# More specific prefixes to send internal traffic through NVA
#route $onprem_nva_subnet_prefix via $nva_default_gw;
#route $vm_subnet_prefix via $nva_default_gw;
}
protocol bgp rs0 {
description "RouteServer instance 0";
multihop;
local $nva_private_ip as $nva_asn;
neighbor $rs_ip1 as $rs_asn;
import filter {accept;};
export filter {accept;};
}
protocol bgp rs1 {
description "Route Server instance 1";
multihop;
local $nva_private_ip as $nva_asn;
neighbor $rs_ip2 as $rs_asn;
import filter {accept;};
export filter {accept;};
}
EOF
username=$(whoami)
scp $bird_config_file "${nva_pip_ip}:/home/${username}/bird.conf"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo mv /home/${username}/bird.conf /etc/bird/bird.conf"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo systemctl restart bird"
# ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "systemctl status bird"
# Protect the Azure NVA from learning the default route
nva_rt_name=nva
az network route-table create -n $nva_rt_name -g $rg -l $location
az network route-table route create --route-table-name $nva_rt_name -g $rg --address-prefix '0.0.0.0/1' --name "Default1" --next-hop-type Internet
az network route-table route create --route-table-name $nva_rt_name -g $rg --address-prefix '128.0.0.0/1' --name "Default2" --next-hop-type Internet
# az network route-table route create --route-table-name $nva_rt_name -g $rg --address-prefix $onprem_nva_subnet_prefix --name "OnpremOverride" --next-hop-type VirtualNetworkGateway # Does not work
az network vnet subnet update -g $rg --vnet-name $vnet_name -n $nva_subnet_name --route-table $nva_rt_name
# Protect the VPNGW from learning default routes: NOT REQUIRED!
vpngw_rt_name=vpngw
az network route-table create -n $vpngw_rt_name -g $rg -l $location
az network vnet subnet update -g $rg --vnet-name $vnet_name -n GatewaySubnet --route-table $vpngw_rt_name
# az network route-table route create --route-table-name $vpngw_rt_name -g $rg --address-prefix '0.0.0.0/1' --name "Default2" --next-hop-type Internet
# az network route-table route create --route-table-name $vpngw_rt_name -g $rg --address-prefix '128.0.0.0/1' --name "Default3" --next-hop-type Internet
# az network route-table update -n $vpngw_rt_name -g $rg --disable-bgp-route-propagation
# Add peering to RS
az network routeserver peering create --routeserver rs -g $rg --peer-ip $nva_private_ip --peer-asn $nva_asn -n $nva_name
# Configure BGP with Bird (onprem NVA to VPNGW)
bird_config_file=/tmp/bird.conf
cat <<EOF > $bird_config_file
log syslog all;
router id $nva_private_ip;
protocol device {
scan time 10;
}
protocol direct {
disabled;
}
protocol kernel {
preference 254;
learn;
merge paths on;
import filter {
if net ~ ${vpngw_private_ip_0}/32 then accept;
if net ~ ${vpngw_private_ip_1}/32 then accept;
else reject;
};
export filter {
if net ~ ${vpngw_private_ip_0}/32 then reject;
else accept;
};
}
protocol static {
import all;
# Test route
route 2.2.2.2/32 via $onprem_nva_default_gw;
route $onprem_vnet_prefix via $onprem_nva_default_gw;
}
protocol bgp vpngw0 {
description "VPN Gateway instance 0";
multihop;
local $onprem_nva_private_ip as $onprem_nva_asn;
neighbor $vpngw_private_ip_0 as $vpngw_asn;
import filter {accept;};
export filter {accept;};
}
protocol bgp vpngw1 {
description "VPN Gateway instance 1";
multihop;
local $onprem_nva_private_ip as $onprem_nva_asn;
neighbor $vpngw_private_ip_1 as $vpngw_asn;
import filter {accept;};
export filter {accept;};
}
EOF
username=$(whoami)
scp $bird_config_file "${onprem_nva_pip_ip}:/home/${username}/bird.conf"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo mv /home/${username}/bird.conf /etc/bird/bird.conf"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo systemctl restart bird"
# Wait 1 minute to make sure the config is applied
sleep 60
# IPsec Diagnostics (onprem NVA to VPNGW)
az network vpn-connection show -g $rg -n onprem --query '[connectionStatus,ingressBytesTransferred,egressBytesTransferred]' -o tsv
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "ip a"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "netstat -rnv"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "systemctl status ipsec"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo ipsec status"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo tail /var/log/syslog"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "ping $vpngw_private_ip_0 -c 15"
# BGP Diagnostics (bird)
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "systemctl status bird"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo birdc show status"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo birdc show protocols"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo birdc show protocols rs0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo birdc show protocol all rs0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo birdc show route"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo birdc show route protocol rs0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo birdc show route export rs0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show route where net ~2.2.2.2/32 all" # 2.2.2.2/32 is advertised by the onprem NVA
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "netstat -rnv"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "systemctl status bird"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show status"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show protocols vpngw0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show protocol all vpngw0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show route"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show route protocol vpngw0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show route export vpngw0"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "sudo birdc show route where net ~1.1.1.1/32 all" # 1.1.1.1/32 is advertised by the Azure NVA
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "netstat -rnv"
# BGP Diagnostics (Azure)
az network routeserver peering list --routeserver rs -g $rg -o table
az network routeserver peering list-learned-routes -n $nva_name --routeserver rs -g $rg --query 'RouteServiceRole_IN_0' -o table
az network routeserver peering list-advertised-routes -n $nva_name --routeserver rs -g $rg --query 'RouteServiceRole_IN_0' -o table
az network vnet-gateway list-bgp-peer-status -n vpngw -g $rg -o table
az network vnet-gateway list-learned-routes -n vpngw -g $rg -o table
az network vnet-gateway list-advertised-routes -n vpngw -g $rg --peer $onprem_nva_private_ip -o table
# Effective routes
nva_nic_id=$(az vm show -n $nva_name -g $rg --query 'networkProfile.networkInterfaces[0].id' -o tsv)
az network nic show-effective-route-table --ids $nva_nic_id -o table
az network nic show-effective-route-table --ids $azurevm_nic_id -o table
# Ping from onprem to Azure VM
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "ping $azurevm_private_ip -c 5"
# Connectivity to Internet
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $nva_pip_ip "sudo iptables -t nat -L"
echo "Connectivity should be sourced from the NVA, $nva_pip_ip:"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $onprem_nva_pip_ip "curl -s4 ifconfig.co"
ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no -J $nva_pip_ip $azurevm_private_ip "curl -s4 ifconfig.co"
#################
# Log Analytics #
#################
# Create Log Analytics workspace
logws_name=$(az monitor log-analytics workspace list -g $rg --query '[0].name' -o tsv)
if [[ -z "$logws_name" ]]
then
logws_name=log$RANDOM
echo "INFO: Creating log analytics workspace ${logws_name}..."
az monitor log-analytics workspace create -n $logws_name -g $rg
else
echo "INFO: Log Analytics workspace $logws_name found in resource group $rg"
fi
logws_id=$(az resource list -g $rg -n $logws_name --query '[].id' -o tsv)
logws_customerid=$(az monitor log-analytics workspace show -n $logws_name -g $rg --query customerId -o tsv)
# Attach VPN GW
vpngw_id=$(az network vnet-gateway show -g $rg -n vpngw --query 'id' -o tsv)
az monitor diagnostic-settings create -n mydiag --resource $vpngw_id --workspace $logws_id \
--metrics '[{"category": "AllMetrics", "enabled": true, "retentionPolicy": {"days": 0, "enabled": false }, "timeGrain": null}]' \
--logs '[{"category": "GatewayDiagnosticLog", "enabled": true, "retentionPolicy": {"days": 0, "enabled": false}},
{"category": "TunnelDiagnosticLog", "enabled": true, "retentionPolicy": {"days": 0, "enabled": false}},
{"category": "RouteDiagnosticLog", "enabled": true, "retentionPolicy": {"days": 0, "enabled": false}},
{"category": "IKEDiagnosticLog", "enabled": true, "retentionPolicy": {"days": 0, "enabled": false}}]' >/dev/null
# IKE logs
query='AzureDiagnostics
| where ResourceType == "VIRTUALNETWORKGATEWAYS"
| where Category == "IKEDiagnosticLog"
| where TimeGenerated >= ago(2m)
| project TimeGenerated, Message
| take 20'
az monitor log-analytics query -w $logws_customerid --analytics-query $query -o tsv
###############
# Danger Zone #
###############
# az network vnet-gateway reset -g $rg -n vpngw --gateway-vip vpngw-pipa
# az group delete -y --no-wait -n $rg