Skip to content

How to Extend the Private Endpoints beyond Azure

When we talk about Virtual Network integration for Azure services, we are referring to the capability of connecting and integrating those Azure services with an Azure Virtual Network (VNet). This integration allows the service to operate within the secure and isolated network boundaries of the VNet.

Azure provides the following methods for VNet integration with Azure services:

  • Deploying dedicated instances of the service into a virtual network. The services can then be privately accessed within the virtual network and from on-premises networks.
  • Using Private Endpoint that connects you privately and securely to a service powered by Azure Private Link. Private Endpoint uses a private IP address from your virtual network, effectively bringing the service into your virtual network.
  • Accessing the service using public endpoints by extending a virtual network to the service, through service endpoints. Service endpoints allow service resources to be secured to the virtual network.
  • Use service tags to allow or deny traffic to your Azure resources to and from public IP endpoints.

Note

For a deeper dive into Azure Virtual Network integration methods, we recommend reading the article Unveiling the Potential of Azure Virtual Network Integration.

In this tutorial, we'll focus on using a Private Endpoint to create a private connection from endpoint subnet to Azure Blob Storage. Then, we'll extend access to the Storage Private Endpoint to server-01 located in Private Data Center using n2x.io. We will deploy n2x-node-01 VM in the edge subnet, to create a virtual private network connection, allowing us to mount the Azure Blob Storage container on server-01.

Here is the high-level overview of tutorial setup architecture:

Architecture

In our setup, we will be using the following components:

  • A Private Endpoint is a network interface that uses a private IP address from your virtual network. For more info please visit the Azure Documentation

  • n2x-node is an open-source agent that runs on the machines you want to connect to your n2x.io network topology. For more info please visit n2x.io Documentation.

Before you begin

In order to complete this tutorial, you must meet the following requirements:

Note

Please note that this tutorial uses a Linux OS with an Ubuntu 22.04 (Jammy Jellyfish) with amd64 architecture.

Step-by-step Guide

Step 1 - Create an Azure Blob Storage container

  1. Before creating an Azure Blob Storage container we need create a new Storage Account. In the Azure portal, use the search bar to find Storage Accounts.

  2. Click the + Create button to start the creation process.

    New Storage Account

  3. Next, fill in the fields with the information from the table below and click Review + Create.

    Storage Account Settings

    Resource group Storage account name Region Performance Redundancy
    edge-rg n2xstorage East US Standard LSR

    Note

    Azure Storage Account provides four types of Redundancy Storage, we will go with Locally-redundant Storage (LRS) for the demo purpose. You can choose the one that best suits your requirements.

    Setting Storage Account

  4. After deployment is completed, click on Go to resource:

    Go-to Resource

  5. The following screen will show an Overview of the created Storage Account. The next step we go to the left menu and click on Containers. Then we have to click on + Container, fill the Name and Anonymous access level with information on the following picture and click on Create button:

    Create Container

  6. Hence we have successfully created the blob Storage. You can see the n2x-demo container under the storage account:

    Container List

  7. Before you create the private endpoint, it's recommended to disable public access to the storage account. In the search box at the top of the portal, enter Storage account. Select n2xstorage. In the Security + networking section on left pane, select Networking and click on Disable Public network access. Finally, select Save:

    Disable Public Access Storage Account

  8. We can get the Connection string and key to access the blob Storage form Access Keys option in same Security + networking section of Storage Account:

    Access Keys

Step 2 - Deploying a n2x-node in Azure

This step-by-step guide, will help you set up an n2x-node in Azure. It covers the creation of all the necessary infrastructure within Azure, including a resource group (RG), virtual network (VNet), subnet, network security group (NSG), and a virtual machine (VM).

Step 3 - Configuring n2x-node to export VNet CIDR

Before configuring n2x-node-01 to export VNet CIDR, we must enable IP forwarding on both the Linux OS within the Azure VM and its associated Network Interface Card (NIC). This will allow the VM to forward incoming IPv4 packets. Here's how to do it:

  1. Enable IPv4 forwarding at the Linux OS.

  2. Enable IPv4 forwarding in NIC associated with the VM.

Now, to make the VNet CIDR available on your n2x.io subnet we need to configure the n2x-node-01 to export this CIDR. For this, we need to edit /etc/n2x/n2x-node.yml and add the following configuration:

# network routes behind this node (optional)
routes:
  export:
    - <VNet CIDR>
  import:  

Info

Replace <VNet CIDR> with the VNet CIDR value, in this case is 10.0.1.0/24.

Restart the n2x-node service for this change to take effect:

sudo systemctl restart n2x-node

Step 4 - Deploying Storage Private Endpoint

Before creating the Storage Private Endpoint we need to create an endpoint subnet and some additional resources:

  1. Add the endpoint-subnet in the edge-vnet Vnet as described in the following table. For more information, see Add a Subnet:

    Subnet Settings

    Subnet Name IPv4 address range Starting address Size NAT gateway NSG Route table
    endpoint-subnet 10.0.1.0/24 10.0.1.128 /28 none none none

    Endpoint Subnet

  2. Create a routing table for the endpoint-subnet and add a new route in the route table with the destination 10.254.1.0/24 (n2x.io subnet CIDR) vía IP address of n2x-node-01. For more information, see Manage Route Table.

    Routing Table Settings

    Resource Group Region Name Propagate gateway routes
    edge-rg East US endpoint-subnet-rt Yes

    Endpoint Subnet RT

    Route Settings

    Route name Destination Type Destination IP addresses / CIDR Range Next hop type Next hop address
    n2x-net-route IP Addresses 10.254.1.0/24 Virtual appliance 10.0.1.4

    Add Route

  3. Create a network security group storage-private-endpoint that enables ports 80 and 443 from Any. For more information, see Manage network security groups.

    Network Security Group Settings

    Resource Group Region Name
    edge-rg East US storage-private-endpoint

    NSG

    Network Security Group Rules

    Rule Source Source Port Range Destination Service Action
    Inbound Any * Any HTTP Allow
    Inbound Any * Any HTTPS Allow

    NSG Rules

  4. Now, we need to associate the route table and security group previously created with the endpoint-subnet. From the Virtual Network section, select and edit the endpoint-subnet:

    Add RT NSG to Subnet

Now we can create the Private Endpoint, in the search box at the top of the portal, enter Private endpoints. In the left pane select Private endpoints and click on + Create:

Create Endpoint

Configure the Private Endpoint using the values as shown in the following image and click Create:

Review Endpoint

After deployment is completed, click on Go to resource:

Go-to Private EP

Finally, in the DNS configuration section you can see the FQDN and IP address assigned to the endpoint:

DNS Config EP

Info

Remember the FQDN and IP address assigned to this endpoint, we must be used it to connect with Azure Blob Storage.

Step 5 - Connecting the server-01 to our n2x.io network topology

Now we need to connect the server-01 must be able to access the Azure Blob Storage container using the Private Endpoint.

Adding a new node in a subnet with n2x.io is very easy. Here's how:

New Node

  1. Head over to the n2x WebUI and navigate to the Network Topology section in the left panel.
  2. Click the Add Node button and ensure the new node is placed in the same subnet as the n2x-node-01.
  3. Assign a name and description for the new node.
  4. Click Add New Connected Node to Subnet.

Here, we can select the environment where we are going to install the n2x-node agent. In this case, we are going to use Linux:

Node Setup

Run the script on server-01 terminal and check if the service is running with the command:

systemctl status n2x-node

You can use ip addr show dev n2x0 command on server-01 to check the IP assigned to this node:

Node IP

At this point, we need to make the VNet CIDR available in our server-01 importing this CIDR. For this, we need to edit /etc/n2x/n2x-node.yml in server-01 and add the following configuration:

# network routes behind this node (optional)
routes:
  export:
    - 
  import:
    - <VNet CIDR>  

Info

Replace <VNet CIDR> with the VNet CIDR value, in this case is 10.0.1.0/24.

Restart the n2x-node service for this change to take effect:

systemctl restart n2x-node

We can check the local routing table in server-01 with the following command:

ip route

Server-01 RT

Step 6 - Mount the Azure Blob Storage container as a filesystem on server-01

Finally, we will show you how to mount an Azure Blob Storage container using BlobFuse2 in server-01 (Ubuntu 22.04):

  1. We need to configure the Linux Package Repository for Microsoft Products:

    sudo wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
    sudo dpkg -i packages-microsoft-prod.deb
    sudo apt-get update && apt-get install -y libfuse3-dev fuse3
    
  2. Now we can install the package blobfuse2 with the following command:

    sudo apt-get install -y blobfuse2
    
  3. You can configure the BlobFuse2 settings using a YAML configuration file, using environment variables, or as parameters passed to the BlobFuse2 commands. In this tutorial, we are going to create a fuse-config.yaml file with the following configuration:

    logging:
      type: syslog
      level: log_debug
    
    components:
      - libfuse
      - stream
      - attr_cache
      - azstorage
    
    libfuse:
      attribute-expiration-sec: 120
      entry-expiration-sec: 120
      negative-entry-expiration-sec: 240
    
    stream:
      block-size-mb: 8
      max-buffers: 64
      buffer-size-mb: 16
    
    attr_cache:
      timeout-sec: 7200
    
    azstorage:
      type: block
      account-name: n2xstorage
      account-key: <ACCOUNT_KEY>
      endpoint: https://n2xstorage.blob.core.windows.net
      mode: key
      container: n2x-demo
    

    Info

    Replace <ACCOUNT_KEY> with the key value of Storage Account created in the step 1.

  4. You can configure Azure DNS Private Resolver to resolve on-premises DNS queries for Azure DNS private zones. But for this tutorial, we are going to include the following entry in the /etc/hosts:

    #<private-endpoint-ip>   <private-endpoint-fqdn>
    
    10.0.1.132   n2xstorage.blob.core.windows.net
    
  5. We need to create an empty directory to mount the blob container on your local machine, in this case, we will use /mnt/n2x-container:

    sudo mkdir -p /mnt/n2x-container
    
  6. Now we’re ready to mount the Azure Blob Storage container:

    sudo blobfuse2 mount /mnt/n2x-container --config-file=./fuse-config.yaml --allow-other
    

    Note

    For a full list of mount options, see BlobFuse2 mount commands.

    You might notice a little delay when firing the above command: that’s because blobfuse2 tries to reach Azure Blob Storage internally for authentication purposes. If you don’t see any errors, your Blob container should be mounted on the /mnt/n2x-container folder.

  7. To verify if the Blob container was mounted correctly, you can type mount | grep blobfuse2 in the terminal and you should see something like the screenshot below:

    Mount Filesystem

  8. Once mounted, you can interact with the Azure Blob Storage container the same way as you would use any local folder. You can create a testing file in /mnt/n2x-container folder:

    cd /mnt/n2x-container
    echo "Testing Container" > file.txt
    

    Blob Container Local Content

    We can access the Azure Dashboard to verify that the information is the same as the local directory mounted through blobfuse2.

    Blob Container Dashboard Content

Success

That's it! The Azure Blob Storage container is now mounted as a filesystem using Storage Private Endpoint.

Conclusion

In this article, we demonstrated how to create a Private Endpoint for Azure Blob Storage, enabling on-premises applications or servers to securely access the storage container over the private network established by n2x.io. While this example focused on Blob Storage, the concepts can be applied to any Azure service supported by Private Link, such as Azure Cosmos DB, Azure Key Vault, Azure Databricks, and many others (https://learn.microsoft.com/en-us/training/modules/introduction-azure-private-link/).

By using Azure Private Endpoints, you can eliminate the exposure of Azure services to the public internet, enhancing overall network security. Additionally, Private Endpoints can improve network performance and reliability by keeping traffic within the Microsoft Azure backbone network.