In the realm of Azure cloud computing, a solid grasp of Linux Bash and networking fundamentals is essential for several reasons.
Firstly, Linux Bash commands are pivotal in managing and configuring virtual machines (VMs) within Azure, as many VMs in Azure are based on Linux distributions.
Secondly, networking forms the backbone of any cloud infrastructure, and understanding networking fundamentals is crucial for setting up secure and efficient communication between various Azure resources.
Let’s dive into some of the key networking components within Azure.
The Difference Between VNets, Subnets and NSGs
Virtual Networks (VNets) serve as the foundational building blocks that isolate and segregate Azure resources into distinct network segments.
Subnets, on the other hand, exist within VNets and allow for further segmentation, enabling the efficient organization of resources based on their specific requirements.
Network Security Groups (NSGs) are pivotal for enforcing network-level security rules, such as allowing or denying traffic to and from specific resources.
Understanding the distinctions among these components is paramount in designing a robust and secure Azure infrastructure.
To create our test infrastructure in Azure, we’ll leverage the power of Linux Bash and Azure CLI (Command-Line Interface).
Linux Bash commands will assist us in configuring and managing Linux-based VMs, which are widely used in Azure environments.
Additionally, Azure CLI provides a powerful toolset to interact with Azure services, enabling us to deploy, configure, and manage resources seamlessly through command-line instructions.
By combining our knowledge of Linux Bash and Azure CLI, we’ll efficiently craft and maintain a resilient and flexible test infrastructure tailored to our specific needs within the Azure cloud ecosystem.
Scenario Overview
As the Solutions Architect for our manufacturing company, we are embarking on a pivotal journey to enhance our network security strategy while migrating our enterprise resource planning (ERP) app to Azure.
Across our various sites, we recognize the need to ensure stringent security measures that align with our company’s standards.
To achieve this, we are opting to leverage our own Azure subscription for a more comprehensive and tailored learning experience.
Note, if you would like to follow along using the official Microsoft document you can do so here.
If you prefer a more hands on approach i.e. using your own Azure subscription instead of the sandbox, I will detail all the steps below as using your own subscription will require additional commands to setup the region.
Our foremost objective is to establish robust security protocols, addressing not only the virtual machine (VM) networking but also Azure services networking.
By doing so, we aim to exercise precise control over which computers are granted access to the servers hosting our critical ERP application.
Through the implementation of network security groups (NSGs), we will safeguard our network traffic within Azure, ensuring that only authorized communication flows through.
Furthermore, our journey involves harnessing the capabilities of virtual network service endpoints.
These endpoints will serve as a pivotal tool in managing and controlling network traffic to and from Azure services, including crucial components such as storage and databases.
Our efforts in securing both VM networking and Azure services networking will culminate in resilient network infrastructure that aligns seamlessly with our stringent security requirements, thereby allowing us to confidently migrate key systems onto the Azure platform.
Exercise – Create and Manage Network Security Groups
As the solutions architect we…
Create a Virtual Network and Network Security Group
Let’s get learning and using the CLI (BASH) Linux commands to create our virtual network and security group.
Login to your own Azure subscription and launch the CLI.
First, we’re going to use the “rg” command to reference our resource group so we don’t have to keep re-typing it. Like this:
rg=rrtest1
O.K. great. Now let’s create our resource group “rrtest” referencing the “rg” command and setting our location as “ukwest” or whatever location suits you best.
az group create --name $rg --location ukwest
Now let’s create the ERP-servers virtual network and the Applications subnet:
az network vnet create \
--resource-group $rg \
--name ERP-servers \
--address-prefixes 10.0.0.0/16 \
--subnet-name Applications \
--subnet-prefixes 10.0.0.0/24
Now let’s create the Databases subnet, run the following:
az network vnet subnet create \
--resource-group $rg \
--vnet-name ERP-servers \
--address-prefixes 10.0.1.0/24 \
--name Databases
Now we will create the ERP-SERVERS-NSG network security group, run the following:
az network nsg create \
--resource-group $rg \
--name ERP-SERVERS-NSG
Create VMs running Ubuntu
Let’s dive into the exciting world of virtual machines, shall we?
Imagine you’re the master of your own digital universe, and you’ve got two trusty companions: AppServer and DataServer.
Now, to give them some structure, you’re going to assign roles.
AppServer, the go-getter, is heading to the Applications subnet.
Meanwhile, DataServer, the data wizard, is making a home in the Databases subnet.
But we can’t forget about security! That’s where our guardian angel, the ERP-SERVERS-NSG (Network Security Group), comes into play.
It’s like the superhero of your virtual world, keeping the baddies out and the goodies safe.
Now, the real fun begins – testing!
With AppServer and DataServer in their designated spots, shielded by the mighty ERP-SERVERS-NSG, it’s time to see if our security measures hold up.
Let’s give those virtual machines a spin and make sure everything’s running like a well-oiled machine in your digital playground.
First, lets build the AppServer VM, in Cloud Shell.
For the admin account, replace <password> with a complex password.
Run the following:
Note: Take out the <> from the command and passwords must be 12 to 72 characters with one uppercase letter, number and a special character.
wget -N https://raw.githubusercontent.com/MicrosoftDocs/mslearn-secure-and-isolate-with-nsg-and-service-endpoints/master/cloud-init.yml && \
az vm create \
--resource-group $rg \
--name AppServer \
--vnet-name ERP-servers \
--subnet Applications \
--nsg ERP-SERVERS-NSG \
--image UbuntuLTS \
--size Standard_DS1_v2 \
--generate-ssh-keys \
--admin-username azureuser \
--custom-data cloud-init.yml \
--no-wait \
--admin-password <password>
Now lets build the the DataServer VM, in Cloud Shell. For the admin account, replace <password> with a complex password.
Run the following:
az vm create \
--resource-group $rg \
--name DataServer \
--vnet-name ERP-servers \
--subnet Databases \
--nsg ERP-SERVERS-NSG \
--size Standard_DS1_v2 \
--image UbuntuLTS \
--generate-ssh-keys \
--admin-username azureuser \
--custom-data cloud-init.yml \
--no-wait \
--admin-password <password>
It can take several minutes for the VMs to be in a running state. To confirm that the VMs are running, run the following:
az vm list \
--resource-group $rg \
--show-details \
--query "[*].{Name:name, Provisioned:provisioningState, Power:powerState}" \
--output table
Once your VM creation is complete, you should see the following output:
Name Provisioned Power
---------- ------------- ----------
AppServer Succeeded VM running
DataServer Succeeded VM running
Check Default Connectivity
Alright, it’s time to hop into your Virtual Machines (VMs) using Secure Shell (SSH)!
Just a quick reminder, you’ve set up a network security group with some default rules.
To get connected to your VMs, we’ll use SSH right from Cloud Shell.
To do this, you’ll need the public IP addresses that were given to your VMs.
To see the list of these IP addresses that you’ll use for connecting to the VMs, simply run this command in Cloud Shell:
az vm list \
--resource-group $rg \
--show-details \
--query "[*].{Name:name, PrivateIP:privateIps, PublicIP:publicIps}" \
--output table
To make your life easier for the rest of this exercise, let’s assign those public IP addresses to some handy variables.
To save the public IP address of AppServer and DataServer to these variables, go ahead and run this command in your trusty Cloud Shell:
APPSERVERIP="$(az vm list-ip-addresses \
--resource-group $rg \
--name AppServer \
--query "[].virtualMachine.network.publicIpAddresses[*].ipAddress" \
--output tsv)"
DATASERVERIP="$(az vm list-ip-addresses \
--resource-group $rg \
--name DataServer \
--query "[].virtualMachine.network.publicIpAddresses[*].ipAddress" \
--output tsv)"
Now let’s check whether you can connect to your AppServer VM, run the following command in Cloud Shell:
ssh azureuser@$APPSERVERIP -o ConnectTimeout=5
You should get a connection timed out message.
To check whether you can connect to your DataServer VM, run the following command:
ssh azureuser@$DATASERVERIP -o ConnectTimeout=5
You should get the same connection failure message.
Just a quick reminder – those default rules are pretty cautious.
They basically say “Nope” to any incoming traffic unless it’s from the same virtual network.
So, that “Deny All Inbound” rule? Yeah, it’s the reason your SSH connection attempts got the cold shoulder.
Name | Priority | Source IP | Destination IP | Access |
Allow VNET Inbound | 6500 | VIRTUAL_NETWORK | VIRTUAL_NETWORK | Allow |
Deny All Inbound | 6500 | * | * | Deny |
Create a Security Rule for SSH
Now that you’ve had a taste of it, you probably noticed that your ERP-SERVERS-NSG network security group comes with some pretty strict default rules, including one that says, “Nope, no incoming traffic allowed!”
But don’t worry, we’re going to add a new rule so you can SSH your way into AppServer and DataServer without any hassle.
Lets create a new inbound security rule to enable SSH access, run the following command:
az network nsg rule create \
--resource-group $rg \
--nsg-name ERP-SERVERS-NSG \
--name AllowSSHRule \
--direction Inbound \
--priority 100 \
--source-address-prefixes '*' \
--source-port-ranges '*' \
--destination-address-prefixes '*' \
--destination-port-ranges 22 \
--access Allow \
--protocol Tcp \
--description "Allow inbound SSH"
To check whether you can now connect to your AppServer VM, run the following command:
ssh azureuser@$APPSERVERIP -o ConnectTimeout=5
Sometimes, the network security group rule can be a bit slow to kick in, so if you see a connection failure message, just give it another go.
You should be all set to connect now.
When that “Are you sure you want to continue connecting (yes/no)?” message pops up, go ahead and type in “yes.”
Next up, enter the password you set when you created the VM. Pretty straight forward.
When you’re ready to wrap things up with the AppServer session, just type “exit.”
To double-check if you can connect to your DataServer VM, simply run this command in your trusty Cloud Shell:
ssh azureuser@$DATASERVERIP -o ConnectTimeout=5
Now, you should be good to go! When you see the “Are you sure you want to continue connecting (yes/no)?” message, simply type in “yes.”
Next, go ahead and enter that password you set when you first created the VM.
And when you’re ready to call it a day with the DataServer session, just type “exit.”
Create a Security Rule to Prevent Web Access
Let’s spice things up a bit! We’re going to add a rule that allows AppServer to chat with DataServer using HTTP, but we’re also going to make sure DataServer keeps its lips sealed when it comes to talking to AppServer over HTTP.
Here are the internal IP addresses for these servers:
Server Name | IP Address |
AppServer | 10.0.0.4 |
DataServer | 10.0.1.4 |
Lets create a new inbound security rule to deny HTTP access over port 80, run the following command:
az network nsg rule create \
--resource-group $rg \
--nsg-name ERP-SERVERS-NSG \
--name httpRule \
--direction Inbound \
--priority 150 \
--source-address-prefixes 10.0.1.4 \
--source-port-ranges '*' \
--destination-address-prefixes 10.0.0.4 \
--destination-port-ranges 80 \
--access Deny \
--protocol Tcp \
--description "Deny from DataServer to AppServer on port 80"
Test HTTP Connectivity Between Virtual Machines
Here, you will verify the functionality of your newly implemented rule.
The objective is to ensure that the AppServer can establish HTTP communication with the DataServer while preventing the DataServer from initiating HTTP communication with the AppServer.
To access your AppServer VM, execute the provided command in Cloud Shell. Afterward, confirm whether the AppServer can successfully communicate with the DataServer over HTTP.
ssh -t azureuser@$APPSERVERIP 'wget http://10.0.1.4; exit; bash'
You will need to enter the password that you established when you created the VM.
A successful connection should result in a response containing a “200 OK” message.
For accessing your DataServer VM, follow a similar procedure in Cloud Shell.
Run the specified command and then verify whether the DataServer can communicate with the AppServer over HTTP.
ssh -t azureuser@$DATASERVERIP 'wget http://10.0.0.4; exit; bash'
Please input the password you set during the VM creation process.
Please note that this action is not expected to be successful, as access over port 80 has been blocked intentionally.
After a few minutes, you should encounter a “Connection timed out” message.
To terminate the command prematurely, press Ctrl+C.
Deploy an App Security Group
Subsequently, establish an application security group tailored for database servers to streamline the configuration process for all servers within this group.
Your objective is to prepare for the deployment of additional database servers while ensuring they are unable to access app servers via HTTP.
By associating sources with the application security group, you can circumvent the need for manual IP address maintenance within the network security group.
Instead, you will assign the network interfaces of the VMs you intend to oversee to the application security group.
To generate a fresh application security group named ERP-DB-SERVERS-ASG, execute the subsequent command within Cloud Shell:
az network asg create \
--resource-group $rg \
--name ERP-DB-SERVERS-ASG
To link DataServer with the application security group, perform the following command within Cloud Shell:
az network nic ip-config update \
--resource-group $rg \
--application-security-groups ERP-DB-SERVERS-ASG \
--name ipconfigDataServer \
--nic-name DataServerVMNic \
--vnet-name ERP-servers \
--subnet Databases
To modify the HTTP rule within the ERP-SERVERS-NSG network security group, utilize the subsequent command in Cloud Shell.
This command should specifically mention the ERP-DB-Servers application security group.
az network nsg rule update \
--resource-group $rg \
--nsg-name ERP-SERVERS-NSG \
--name httpRule \
--direction Inbound \
--priority 150 \
--source-address-prefixes "" \
--source-port-ranges '*' \
--source-asgs ERP-DB-SERVERS-ASG \
--destination-address-prefixes 10.0.0.4 \
--destination-port-ranges 80 \
--access Deny \
--protocol Tcp \
--description "Deny from DataServer to AppServer on port 80 using application security group"
Test the Updated HTTP Security Rule
To establish a connection to your AppServer VM, execute the following command within Cloud Shell.
Verify whether AppServer can communicate with DataServer via HTTP.
ssh -t azureuser@$APPSERVERIP 'wget http://10.0.1.4; exit; bash'
You will be prompted to enter the password you specified during VM creation.
Similar to previous steps, a successful connection should yield a “200 OK” message.
Please allow a minute or two for the app security group settings to take effect.
If the “200 OK” message is not received initially, kindly wait for a minute and attempt the connection again.
For connecting to your DataServer, initiate the following command within Cloud Shell.
Assess whether DataServer can establish communication with AppServer over HTTP.
ssh -t azureuser@$DATASERVERIP 'wget http://10.0.0.4; exit; bash'
Once again, you’ll need to enter the password you designated when creating the VM.
As mentioned previously, this connection is not expected to succeed, as access over port 80 has been deliberately blocked.
After a few minutes, you should encounter a “Connection timed out” message.
To halt the command before the timeout, press Ctrl+C.
This sequence of steps confirms the functionality of your network security group rule by employing an app security group, mirroring the behaviour observed when using a source IP address.
Should you decide to incorporate additional data servers in the future, you can effortlessly ensure they adhere to the requisite network security standards by adding them to the ERP-DB-SERVERS-ASG.