Set up a NAT Gateway with Load Balancing
Introduction
In order for NNM to monitor virtual machine instances in a Microsoft Azure Virtual Network, NNM must run on a virtual machine instance that functions as a network address translation (NAT) gateway. A NAT gateway instance routes traffic from internal-only virtual machine instances to the Internet. A NNM installed on a NAT gateway has visibility into the hostnames and private IP addresses of the internal virtual machine instances before the NAT gateway masquerades the source IP address of incoming packets to forward them to the Internet. Microsoft Azure provides a load balancing service that distributes traffic between multiple servers.
This guide shows setting up a NAT gateway in a Microsoft Azure Virtual Network using load balancing.
Before You Begin
Follow the Azure CLI Installation Instructions. Then connect to your subscription from the CLI.
Tip: If you encounter an error in the Azure CLI about the your subscription not being registered to use a namespace, see this section on the common deployment errors page.
Steps
-
Enable Azure CLI Resource Manager commands.
azure config mode arm
-
Create a resource group.
In this example, the resource group pvsLbRg is created.
azure group create pvsLbRg eastus
info: Executing command group create
+ Getting resource group pvsLbRg
+ Creating resource group pvsLbRg
info: Created resource group pvsLbRg
data: Name: pvsLbRg
data: Location: eastus
data: Provisioning State: Succeeded
data: Tags: null
data:
info: group create command OK
-
Create a storage account in the resource group pvsLbRg .
In this example, the storage group pvslbstore is created.
azure storage account create --location eastus --resource-group pvsLbRg --kind Storage --sku-name GRS pvslbstore
info: Executing command storage account create
+ Checking availability of the storage account name
+ Creating storage account
info: storage account create command OK
-
Create a Virtual Network in the resource group pvsLbRg .
In this example, the Virtual Network is pvsVNet and has the network range 10.240.0.0/16.
azure network vnet create -g pvsLbRg -n pvsVNet -a 10.240.0.0/16 -l eastus
info: Executing command network vnet create
+ Looking up the virtual network "pvsVNet"
+ Creating virtual network "pvsVNet"
data: Name : pvsVNet
data: Type : Microsoft.Network/virtualNetworks
data: Location : eastus
data: Provisioning state : Succeeded
data: Address prefixes:
data: 10.240.0.0/16
info: network vnet create command OK
-
Create a Load Balancer.
In this example, the Load Balancer is pvsLb.
azure network lb create pvsLbRg pvsLb eastus
info: Executing command network lb create
+ Looking up the load balancer "pvsLb"
+ Creating load balancer "pvsLb"
data: Name : pvsLb
data: Type : Microsoft.Network/loadBalancers
data: Location : eastus
data: Provisioning state : Succeeded
info: network lb create command OK
-
Create a public IP and sub domain name for the Load Balancer front end pool.
In this example, the sub domain name is examplelbsubdomain and the public IP is pvsPIP.
azure network public-ip create -d examplelbsubdomain pvsLbRg pvsLbPIP eastus
info: Executing command network public-ip create
warn: Using default --idle-timeout 4
warn: Using default --allocation-method Dynamic
warn: Using default --ip-version IPv4
+ Looking up the public ip "pvsLbPIP "
+ Creating public ip address "pvsLbPIP "
data: Name : pvsLbPIP
data: Type : Microsoft.Network/publicIPAddresses
data: Location : eastus
data: Provisioning state : Succeeded
data: Allocation method : Dynamic
data: IP version : IPv4
data: Idle timeout in minutes : 4
data: Domain name label : examplelbsubdomain
data: FQDN : examplelbsubdomain.eastus.cloudapp.azure.com
info: network public-ip create command OK
-
Create a front end IP pool and associate it with the public IP pvsLbPIP.
In this example, the frontend pool is named pvsFrontEndPool.
azure network lb frontend-ip create pvsLbRg pvsLb pvsFrontendPool -i pvsLbPIP
info: Executing command network lb frontend-ip create
+ Looking up the load balancer "pvsLb"
+ Looking up the public ip "pvsLbPIP"
+ Updating load balancer "pvsLb"
data: Name : pvsFrontendPool
data: Provisioning state : Succeeded
data: Private IP allocation method : Dynamic
info: network lb frontend-ip create command OK
-
Create a back end IP pool.
In this example, the back end pool is pvsLbBackendPool.
azure network lb address-pool create pvsLbRg pvsLb pvsLbBackendPool
info: Executing command network lb address-pool create
+ Looking up the load balancer "pvsLb"
+ Updating load balancer "pvsLb"
data: Name : pvsLbBackendPool
data: Provisioning state : Succeeded
info: network lb address-pool create command OK
-
Create a load balancer rule to balance all incoming traffic on port 80 to port 80 on the addresses in the back end pool.
azure network lb rule create pvsLbRg pvsLb webLbRule -p tcp -f 80 -b 80 -t pvsFrontendPool -o pvsLbBackendPool
info: Executing command network lb rule create
+ Looking up the load balancer "pvsLb"
warn: Using default --idle-timeout 4
warn: Using default --enable-floating-ip false
warn: Using default --load-distribution Default
+ Updating load balancer "pvsLb"
data: Name : webLbRule
data: Provisioning state : Succeeded
data: Protocol : Tcp
data: Frontend port : 80
data: Backend port : 80
data: Enable floating IP : false
data: Load distribution : Default
data: Idle timeout in minutes : 4
info: network lb rule create command OK
-
Create a public subnet for the first NAT gateway so that it is accessible over SSH and the NNM web server port.
In this example, the public subnet is pvsPublic and has the network range 10.240.0.0/24.
azure network vnet subnet create -g pvsLbRg -e pvsVNet -n pvsPublic -a 10.240.0.0/24
info: Executing command network vnet subnet create
+ Looking up the virtual network "pvsVNet"
+ Looking up the subnet "pvsPublic"
+ Creating subnet "pvsPublic"
data: Name : pvsPublic
data: Provisioning state : Succeeded
data: Address prefix : 10.240.0.0/24
info: network vnet subnet create command OK
-
Create a public IP and sub domain name for the NAT gateway.
In this example, the sub domain name is exampleNatsubdomain and the public IP is pvsNatPIP.
azure network public-ip create -d exampleNatsubdomain pvsLbRg pvsNatPIP eastus
info: Executing command network public-ip create
warn: Using default --idle-timeout 4
warn: Using default --allocation-method Dynamic
warn: Using default --ip-version IPv4
+ Looking up the public ip "pvsNatPIP"
+ Creating public ip address "pvsNatPIP"
data: Name : pvsNatPIP
data: Type : Microsoft.Network/publicIPAddresses
data: Location : eastus
data: Provisioning state : Succeeded
data: Allocation method : Dynamic
data: IP version : IPv4
data: Idle timeout in minutes : 4
data: Domain name label : exampleNatsubdomain
data: FQDN : exampleNatsubdomain.eastus.cloudapp.azure.com
info: network public-ip create command OK
-
Create a NIC for the NAT gateway and associate it with the public IP pvsNatPIP, public subnet pvsPublic, and back end pool pvsLbBackendPool.
In this example, the new NIC is pvsNatNic.
azure network nic create --public-ip-name pvsNatPIP--subnet-name pvsPublic --subnet-vnet-name pvsVNet pvsLbRg pvsNatNic -d /subscriptions/x-x-x-x-x/resourceGroups/pvsLbRg/providers/Microsoft.Network/loadBalancers/pvsLb/backendAddressPools/pvsLbBackendPool eastus
info: Executing command network nic create
+ Looking up the network interface "pvsNatNic"
+ Looking up the subnet "pvsPublic"
+ Looking up the public ip "pvsPIP"
+ Creating network interface "pvsNatNic"
data: Name : pvsNatNic
data: Type : Microsoft.Network/networkInterfaces
data: Location : eastus
data: Provisioning state : Succeeded
data: Internal domain name suffix : gqhqyfrlprbu3jyndjoq4ap5se.bx.internal.cloudapp.net
data: Enable IP forwarding : false
data: IP configurations:
data: Name : default-ip-config
data: Provisioning state : Succeeded
data: Private IP address : 10.240.0.4
data: Private IP version : IPv4
data: Private IP allocation method : Dynamic
data:
info: network nic create command OK
-
Enable IP forwarding on the new interface pvsNatNic.
azure network nic set -g pvsLbRg -n pvsNatNic-f true
info: Executing command network nic set
+ Looking up the network interface "pvsNatNic"
+ Updating network interface "pvsNatNic"
data: Name : pvsNatNic
data: Type : Microsoft.Network/networkInterfaces
data: Location : eastus
data: Provisioning state : Succeeded
data: MAC address : 00-0D-3A-13-27-48
data: Internal domain name suffix : gqhqyfrlprbu3jyndjoq4ap5se.bx.internal.cloudapp.net
data: Enable IP forwarding : true
data: IP configurations:
data: Name : default-ip-config
data: Provisioning state : Succeeded
data: Private IP address : 10.240.0.4
data: Private IP version : IPv4
data: Private IP allocation method : Dynamic
data:
info: network nic set command OK
-
Repeat the previous steps to create a public subnet (pvsPublic2) with network range 10.240.1.0/24, create a public IP, create a NIC (pvsNatNic2) and add it to the back end pool, and enable IP forwarding on the new NIC.
Repeat this step for other NAT gateway instances that you want to use.
azure network vnet subnet create -g pvsLbRg -e pvsVNet -n pvsPublic2 -a 10.240.1.0/24
azure network public-ip create -d examplenat2subdomain pvsLbRg pvsNatPIP2 eastus
azure network nic create --public-ip-name pvsNatPIP2 --subnet-name pvsPublic2 --subnet-vnet-name pvsVNet pvsLbRg pvsNatNic2 -d subscriptions/x-x-x-x/resourceGroups/pvsLbRg/providers/Microsoft.Network/loadBalancers/pvsLb/backendAddressPools/pvsLbBackendPool eastus
azure network nic set -g pvsLbRg -n pvsNatNic2 -f true
-
Create a security group for the NAT gateways.
In this example, the security group is pvsPublicNSG.
azure network nsg create pvsLbRg pvsPublicNSG eastus
info: Executing command network nsg create
+ Looking up the network security group "pvsPublicNSG"
+ Creating a network security group "pvsPublicNSG"
data: Name : pvsPublicNSG
data: Type : Microsoft.Network/networkSecurityGroups
data: Location : eastus
data: Provisioning state : Succeeded
data: Security rules:
data: Name Source IP Source Port Destination IP Destination Port Protocol Direction Access Priority
data: ----------------------------- ----------------- ----------- -------------- ---------------- -------- --------- ------ --------
data: AllowVnetInBound VirtualNetwork * VirtualNetwork * * Inbound Allow 65000
data: AllowAzureLoadBalancerInBound AzureLoadBalancer * * * * Inbound Allow 65001
data: DenyAllInBound * * * * * Inbound Deny 65500
data: AllowVnetOutBound VirtualNetwork * VirtualNetwork * * Outbound Allow 65000
data: AllowInternetOutBound * * Internet * * Outbound Allow 65001
data: DenyAllOutBound * * * * * Outbound Deny 65500
info: network nsg create command OK
-
Create a rule in the pvsPublicNSG to allow SSH to the NAT gateway.
In this example, the new rule is called SSHRule and the rule has a priority of 1000. This gives it precedence over the existing rules seen in the previous step.
azure network nsg rule create --protocol tcp --direction inbound --priority 1000 --destination-port-range 22 --access allow pvsLbRg pvsPublicNSG SSHRule
info: Executing command network nsg rule create
warn: Using default --source-port-range *
warn: Using default --source-address-prefix *
warn: Using default --destination-address-prefix *
+ Looking up the network security group "pvsPublicNSG"
+ Looking up the network security rule "SSHRule"
+ Creating a network security rule "SSHRule"
data: Name : SSHRule
data: Type : Microsoft.Network/networkSecurityGroups/securityRules
data: Provisioning state : Succeeded
data: Source IP : *
data: Source Port : *
data: Destination IP : *
data: Destination Port : 22
data: Protocol : Tcp
data: Direction : Inbound
data: Access : Allow
data: Priority : 1000
info: network nsg rule create command OK
-
Create a rule in the pvsPublicNSG to allow all traffic to the NAT gateway from within the virtual network.
In this example, the new rule is called PrivateToPublicRule and the rule has a priority of 1001. This gives it precedence over the existing rules that disallow traffic.
azure network nsg rule create --direction inbound --priority 1001 --source-address-prefix VirtualNetwork --destination-port-range 0-65535 --access allow pvsLbRg pvsPublicNSG PrivateToPublicRule
info: Executing command network nsg rule create
warn: Using default --protocol *
warn: Using default --source-port-range *
warn: Using default --destination-address-prefix *
+ Looking up the network security group "pvsPublicNSG"
+ Looking up the network security rule "PrivateToPublicRule"
+ Creating a network security rule "PrivateToPublicRule"
data: Name : PrivateToPublicRule
data: Type : Microsoft.Network/networkSecurityGroups/securityRules
data: Provisioning state : Succeeded
data: Source IP : VirtualNetwork
data: Source Port : *
data: Destination IP : *
data: Destination Port : 0-65535
data: Protocol : *
data: Direction : Inbound
data: Access : Allow
data: Priority : 1001
info: network nsg rule create command OK
-
Create a rule in the pvsPublicNSG to allow traffic to the NNM webserver from the Internet. The default port is 8835.
In this example, the new rule is called PVSWebRule and the rule has a priority of 1002. This gives it precedence over the existing rules that disallow traffic.
azure network nsg rule create --direction inbound --priority 1002 --protocol tcp --source-address-prefix Internet --destination-port-range 8835 --access allow pvsLbRg pvsPublicNSG PvsWebRule
info: Executing command network nsg rule create
warn: Using default --source-port-range *
warn: Using default --destination-address-prefix *
+ Looking up the network security group "pvsPublicNSG"
+ Looking up the network security rule "PvsWebRule"
+ Creating a network security rule "PvsWebRule"
data: Name : PvsWebRule
data: Type : Microsoft.Network/networkSecurityGroups/securityRules
data: Provisioning state : Succeeded
data: Source IP : Internet
data: Source Port : *
data: Destination IP : *
data: Destination Port : 8835
data: Protocol : Tcp
data: Direction : Inbound
data: Access : Allow
data: Priority : 1002
info: network nsg rule create command OK
-
Create a rule in the pvsPublicNSG to allow HTTP traffic to the NAT gateway so it can be forwarded to the web servers being load balanced.
In this example, the new rule is called AllWebRule and the rule has a priority of 1003. This gives it precedence over the existing rules that disallow traffic.
azure network nsg rule create --direction inbound --priority 1003 --protocol tcp --source-address-prefix Internet --destination-port-range 80 --access allow pvsLbRg pvsPublicNSG AllWebRule
-
Assign the security group pvsPublicNSG to the pvsNatNic, which will be used as the interface of the NAT gateway when it is launched.
azure network nic set -g pvsLbRg -n pvsNatNic -o pvsPublicNSG
info: Executing command network nic set
+ Looking up the network interface "pvsNatNic"
+ Looking up the network security group "pvsPublicNSG"
+ Updating network interface "pvsNatNic"
data: Name : pvsNatNic
data: Type : Microsoft.Network/networkInterfaces
data: Location : eastus
data: Provisioning state : Succeeded
data: Internal domain name suffix : gqhqyfrlprbu3jyndjoq4ap5se.bx.internal.cloudapp.net
data: Enable IP forwarding : false
data: IP configurations:
data: Name : default-ip-config
data: Provisioning state : Succeeded
data: Private IP address : 10.240.0.4
data: Private IP version : IPv4
data: Private IP allocation method : Dynamic
data:
info: network nic set command OK
-
Repeat the previous step for any other NAT gateway NICs you have created.
azure network nic set -g pvsLbRg -n pvsNatNic2 -o pvsPublicNSG
-
Create an availability set for all the VM instances that will be created. This is required for having more than one VM attached to the load balancer.
azure availset create pvsLbRg pvsLbAs eastus
info: Executing command availset create
+ Looking up the availability set "pvsLbAs"
+ Creating availability set "pvsLbAs"
info: availset create command OK
-
Launch the NAT gateway instance. In this example CentOS 7 is used.
In this example, the SSH key azurePVS_id_rsa.pub is used. If you do not have an SSH key, refer to the Azure documentation for instructions on how to generate a key.
Note: If you select a different image to install on your NAT gateway virtual machine, ensure that it is a platform that NNM supports.
azure vm create --resource-group pvsLbRg --name pvsNatGateway --location eastus --os-type linux --nic-name pvsNatNic --vnet-name pvsVNet --vnet-subnet-name pvsPublic --storage-account-name pvslbstore --image-urn CentOS -r pvsLbAs --ssh-publickey-file ~/.ssh/azurePVS_id_rsa.pub --admin-username centos
info: Executing command vm create
+ Looking up the VM "pvsNatGateway"
info: Verifying the public key SSH file: ~/.ssh/azurePVS_id_rsa.pub
info: Using the VM Size "Standard_DS1"
info: The [OS, Data] Disk or image configuration requires storage account
+ Looking up the storage account pvsstore
+ Looking up the NIC "pvsNatNic"
info: Found an existing NIC "pvsNatNic"
info: The storage URI 'https://pvslbstore.blob.core.windows.net/' will be used for boot diagnostics settings, and it can be overwritten by the parameter input of '--boot-diagnostics-storage-uri'.
+ Creating VM "pvsNatGateway"
info: vm create command OK
-
Launch any other NAT gateway instances.
azure vm create --resource-group pvsLbRg --name pvsNatGateway2 --location eastus --os-type linux --nic-name pvsNatNic2 --vnet-name pvsVNet --vnet-subnet-name pvsPublic2 --storage-account-name pvslbstore --image-urn CentOS -r pvsLbAs --ssh-publickey-file ~/.ssh/azurePVS_id_rsa.pub --admin-username centos
-
Create a private subnet for the instances that won't have a public IP address.
In this example, the private subnet is pvsPrivate.
azure network vnet subnet create -g pvsLbRg -e pvsVNet -n pvsPrivate -a 10.240.2.0/24
info: Executing command network vnet subnet create
+ Looking up the virtual network "pvsVNet"
+ Looking up the subnet "pvsPrivate"
+ Creating subnet "pvsPrivate"
data: Name : pvsPrivate
data: Provisioning state : Succeeded
data: Address prefix : 10.240.2.0/24
info: network vnet subnet create command OK
-
Create a route table for the private subnet.
In this example, the route table is pvsPrivateUDR.
azure network route-table create -g pvsLbRg -n pvsPrivateUDR -l eastus
info: Executing command network route-table create
+ Looking up Route Table "pvsPrivateUDR"
+ Creating Route Table "pvsPrivateUDR"
data: Name : pvsPrivateUDR
data: Type : Microsoft.Network/routeTables
data: Location : eastus
data: Provisioning state : Succeeded
info: network route-table create command OK
-
Create a route to the internet using the NAT gateway as the next hop for instances in the private subnet.
In this example, the private IP address of the NAT gateway is 10.240.0.4.
azure network route-table route create -g pvsLbRg -r pvsPrivateUDR -n RouteToInternet -a 0.0.0.0/0 -y VirtualAppliance -p 10.240.0.4
info: Executing command network route-table route create
+ Looking up Route Table "pvsPrivateUDR"
+ Looking up route "RouteToInternet" in route table "pvsPrivateUDR"
+ Creating route "RouteToInternet" in a route table "pvsPrivateUDR"
data: Name : RouteToInternet
data: Provisioning state : Succeeded
data: Next hop type : VirtualAppliance
data: Next hop IP address : 10.240.0.4
data: Address prefix : 0.0.0.0/0
info: network route-table route create command OK
-
Associate the route table pvsPrivateUDR with the private subnet pvsPrivate.
azure network vnet subnet set -g pvsLbRg -e pvsVNet -n pvsPrivate -r pvsPrivateUDR
info: Executing command network vnet subnet set
+ Looking up the virtual network "pvsVNet"
+ Looking up the subnet "pvsPrivate"
+ Looking up Route Table "pvsPrivateUDR"
+ Updating subnet "pvsPrivate"
data: Name : pvsPrivate
data: Provisioning state : Succeeded
data: Address prefix : 10.240.2.0/24
info: network vnet subnet set command OK
-
Create a NIC for an example instance in the private subnet. You will need to create a new NIC for every additional instance you create.
In this example, the new NIC is named pvsPrivateNic.
azure network nic create --subnet-name pvsPrivate --subnet-vnet-name pvsVNet pvsLbRg pvsPrivateNic eastus
info: Executing command network nic create
+ Looking up the network interface "pvsPrivateNic"
+ Looking up the subnet "pvsPrivate"
+ Creating network interface "pvsPrivateNic"
data: Name : pvsPrivateNic
data: Type : Microsoft.Network/networkInterfaces
data: Location : eastus
data: Provisioning state : Succeeded
data: Internal domain name suffix : gqhqyfrlprbu3jyndjoq4ap5se.bx.internal.cloudapp.net
data: Enable IP forwarding : false
data: IP configurations:
data: Name : default-ip-config
data: Provisioning state : Succeeded
data: Private IP address : 10.240.2.4
data: Private IP version : IPv4
data: Private IP allocation method : Dynamic
data:
info: network nic create command OK
-
Launch an example instance into the private subnet pvsPrivate using the pvsPrivateNic as the NIC.
azure vm create --resource-group pvsLbRg --name exampleInstance --location eastus --os-type linux --nic-name pvsPrivateNic --vnet-name pvsVNet --vnet-subnet-name pvsPrivate --storage-account-name pvslbstore --image-urn CentOS --ssh-publickey-file ~/.ssh/azurePVS_id_rsa.pub --admin-username centos
info: Executing command vm create
+ Looking up the VM "exampleInstance"
info: Verifying the public key SSH file: ~/.ssh/azurePVS_id_rsa.pub
info: Using the VM Size "Standard_DS1"
info: The [OS, Data] Disk or image configuration requires storage account
+ Looking up the storage account pvsstore
+ Looking up the NIC "pvsPrivateNic"
info: Found an existing NIC "pvsPrivateNic"
info: This is an NIC without publicIP configured
info: The storage URI 'https://pvsstore.blob.core.windows.net/' will be used for boot diagnostics settings, and it can be overwritten by the parameter input of '--boot-diagnostics-storage-uri'.
+ Creating VM "exampleInstance"
info: vm create command OK
-
Repeat the previous steps to create any additional private instances if they are going into a new subnet. To create a new instance in an existing subnet, simply repeat the launch into the subnet step.
azure network vnet subnet create -g pvsLbRg -e pvsVNet -n pvsPrivate2 -a 10.240.3.0/24
azure network route-table create -g pvsLbRg -n pvsPrivateUDR2 -l eastus
azure network route-table route create -g pvsLbRg -r pvsPrivateUDR2 -n RouteToInternet -a 0.0.0.0/0 -y VirtualAppliance -p 10.240.1.4
azure network vnet subnet set -g pvsLbRg -e pvsVNet -n pvsPrivate2 -r pvsPrivateUDR2
azure network nic create --subnet-name pvsPrivate2 --subnet-vnet-name pvsVNet pvsLbRg pvsPrivateNic2 eastus
azure vm create --resource-group pvsLbRg --name exampleInstance2 --location eastus --os-type linux --nic-name pvsPrivateNic2 --vnet-name pvsVNet --vnet-subnet-name pvsPrivate2 --storage-account-name pvslbstore --image-urn CentOS --ssh-publickey-file ~/.ssh/azurePVS_id_rsa.pub --admin-username centos
-
Connect to the new NAT gateway instances using the public DNS name that was created when your public IP was created.
ssh -i ~/.ssh/azurePVS_id_rsa.pub [email protected]
-
Once logged in, configure iptables and IP forwarding.
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -t nat -A PREROUTING -i eth0 ! -s 10.240.0.0/16 -p tcp --dport 80 -j DNAT --to-destination 10.240.2.4:80
The first sudo command tells the kernel to allow IP forwarding. The second sudo command masquerades packets received from internal instances as if they originated from the NAT gateway instance. The last command enables port forwarding so traffic to the NAT gateway on port 80 gets forwarded to port 80 on 10.240.2.4. In this example 10.240.2.4 is one the web servers being load balanced.
Tip: Consider saving these commands in a startup script, because these settings will not persist if the instance is rebooted.