Janne Mattila

From programmer to programmer -- Programming just for the fun of it

Network security groups and existing connections

Posted on: March 18, 2024

Network security groups (NSG) allows you to filter network traffic in your Azure virtual networks. You can define inbound and outbound security rules based on source and destination, ports, and protocols.

From the above documentation, you can find the following snippets:

A flow record is created for existing connections. Communication is allowed or denied based on the connection state of the flow record. The flow record allows a network security group to be stateful.

and

If inbound traffic is allowed over a port, it’s not necessary to specify an outbound security rule to respond to traffic over the port.

Let me try to show these in practice in this post.

Let’s start by deploying a virtual network and single virtual machine with public IP assigned to it:

Since there is public IP address attached to the virtual machine, we can use it to connect to the virtual machine.

We have network security group associated with the subnet that virtual machine resides:

Currently, the deployed network security group is empty:

Now, obviously, I can’t connect to the machine since RDP/SSH traffic is not allowed.

If I now try to connect to the machine:

It recommends me to add a just-in-time policy to enable that connection but limit the exposure of the machine to the internet:

I’ll enable it and then request just-in-time access from my IP address:

It enables just-in-time access:

And in the background, it will create a new rule in the network security group. You can see this change in the Activity Log:

And this new rule is automatically added to the network security group:

Rule is simple: Allow RDP (port 3389) from my IP address.

Now, I can connect to the machine as expected:

Here’s a diagram of the process:

sequenceDiagram actor User User->>NSG: SSH/RDP NSG->>VM: Allow rule Note right of NSG: Flow record
created VM-->>NSG: NSG-->>User: Allowed
automatically
(since flow record exists) Note right of User: SSH/RDP
Connection
established

I can now work normally using my established RDP/SSH connection.

Let’s study a bit more about our just-in-time settings:

As you can see, the time range was configured to be 3 hours. I expect the system to automatically remove this rule after it has been expired.


After 4 hours, I can see the following entries in the Activity Log:

The latest entry indicates that my just-in-time access has been removed.

However, my RDP/SSH connection is not disconnected, and I can still continue to work normally:

At first glance this might seem counter-intuitive, so let’s check again the network security groups documentation to understand this better:

Existing connections may not be interrupted when you remove a security rule that allowed the connection. Modifying network security group rules will only affect new connections. When a new rule is created or an existing rule is updated in a network security group, it will only apply to new connections. Existing connections are not reevaluated with the new rules.

Above explains the behavior we are seeing in the above demo.

Even if I don’t have a rule to allow RDP/SSH connection anymore in the network security group, I can continue to use that existing RDP/SSH connection that I’ve established earlier.

At high level, the behavior can be explained with the following diagram:

sequenceDiagram actor User User->>NSG: SSH/RDP NSG->>VM: Allow rule Note right of NSG: Flow record
created VM-->>NSG: NSG-->>User: Allowed
automatically
(since flow record exists) Note right of User: SSH/RDP
Connection
established Note left of NSG: Update NSG Note right of NSG: Flow record
exist User->>VM: SSH/RDP continues to work

Above just demonstrated the stateful behavior of the network security groups. I used RDP/SSH connection as an example, but the same behavior applies to other established connections as well.


Bonus: Let’s deny the internet access completely from our virtual machine with this rule:

Now our virtual machine is unable to connect to internet but RDP/SSH connection still continues to work:

And if I remove the above rule, internet connectivity is restored:

This just confirms this statement from the above:

If inbound traffic is allowed over a port, it’s not necessary to specify an outbound security rule to respond to traffic over the port.


I hope you find this useful!