How to Expose Inbound Services With NAT Gateway on Vultr

Updated on 05 February, 2026
Guide
Learn how to securely expose SSH and HTTP services with Vultr NAT Gateway.
How to Expose Inbound Services With NAT Gateway on Vultr header image

VPC only instances are isolated from the public internet and do not accept inbound connections by default. To expose specific services such as SSH or application endpoints, NAT Gateway port forwarding routes inbound traffic from the internet to selected services running on private instances inside a VPC.

This guide explains how to expose inbound services on VPC only instances with NAT Gateway port forwarding on Vultr.

Prerequisites

Before you begin, ensure you:

Identify Private IP Addresses of VPC Only Instances

Identify the private IP addresses of the VPC only instances running inside the VPC. These addresses are required when creating NAT Gateway port forwarding rules.

  1. Log in to the Vultr Customer Portal.
  2. Navigate to Products and click Network.
  3. Select VPC Networks.
  4. Choose the VPC associated with the NAT Gateway.
  5. Verify that all VPC only instances appear under Attached Nodes.
  6. Note the private IP address of the instance you want to access.

Create a NAT Gateway Port Forwarding Rule

Create a port forwarding rule on the NAT Gateway to expose a specific service running on a VPC only instance. The rule maps a public port on the NAT Gateway to a private IP address and port inside the VPC.

  1. Export your Vultr API key as an environment variable.

    console
    $ export VULTR_API_KEY=YOUR_VULTR_API_KEY
    

    Replace YOUR_VULTR_API_KEY with your Vultr API key.

  2. List the VPC networks available in your account.

    console
    $ curl -sS --location --request GET "https://api.vultr.com/v2/vpcs" \
      --header "Content-Type: application/json" \
      --header "Authorization: Bearer ${VULTR_API_KEY}" \
      | jq .
    

    Identify the ID of the VPC network that has the NAT Gateway provisioned.

  3. Export the VPC ID as an environment variable.

    console
    $ export VPC_ID=YOUR_VPC_ID
    

    Replace YOUR_VPC_ID with the ID of your VPC network.

  4. Retrieve the NAT Gateway ID for the VPC.

    console
    $ curl -sS --location "https://api.vultr.com/v2/vpcs/${VPC_ID}/nat-gateway" \
      --header "Authorization: Bearer ${VULTR_API_KEY}" \
      | jq .
    

    From the output, copy the NAT Gateway ID for use in subsequent steps.

  5. Export the NAT Gateway ID.

    console
    $ export NAT_GATEWAY_ID=YOUR_NAT_GATEWAY_ID
    

    Replace YOUR_NAT_GATEWAY_ID with your NAT Gateway ID.

  6. Create an SSH port forwarding rule to expose inbound access.

    console
    $ curl -sS --location \
      --request POST "https://api.vultr.com/v2/vpcs/${VPC_ID}/nat-gateway/${NAT_GATEWAY_ID}/global/port-forwarding-rules" \
      --header "Content-Type: application/json" \
      --header "Authorization: Bearer ${VULTR_API_KEY}" \
      --data '{
        "name": "ssh-to-private-instance",
        "protocol": "tcp",
        "external_port": 2222,
        "internal_ip": "PRIVATE_IP_OF_INSTANCE",
        "internal_port": 22,
        "enabled": true,
        "description": "SSH access to private instance"
      }' \
      | jq .
    

    Replace the following values as required:

    • name: A descriptive unique name for the port forwarding rule.
    • external_port: The public port exposed on the NAT Gateway.
    • internal_ip: The private IP address of the instance in the VPC.
    • internal_port: The port on which the service is listening on the instance.
    • protocol: The transport protocol (tcp or udp).
    Note
    Only the ports explicitly defined in port forwarding rules are accessible from the internet. All other inbound traffic to the private instance remains blocked. Repeat this step to create additional port forwarding rules for other instances or services by using their respective private IP addresses and ports.
  7. Verify that the SSH port forwarding rule is active.

    console
    $ curl -sS --location \
      --request GET "https://api.vultr.com/v2/vpcs/${VPC_ID}/nat-gateway/${NAT_GATEWAY_ID}/global/port-forwarding-rules" \
      --header "Authorization: Bearer ${VULTR_API_KEY}" \
      | jq .
    

    Verify that the rule appears in the output and that the enabled field is set to true.

Verify Exposed SSH Access Through the NAT Gateway

After creating the port forwarding rule, verify that the NAT Gateway forwards inbound SSH traffic to the VPC only instance.

  1. Identify the public IP address of the NAT Gateway.

    console
    $ curl -sS --location "https://api.vultr.com/v2/vpcs/${VPC_ID}/nat-gateway" \
      --header "Authorization: Bearer ${VULTR_API_KEY}" \
      | jq '.nat_gateways[].public_ips[]'
    

    The command returns the public IPv4 address assigned to the NAT Gateway.

  2. Connect to the private instance over SSH using the NAT Gateway public IP and the forwarded port.

    console
    $ ssh -p 2222 USERNAME@NAT_GATEWAY_PUBLIC_IP
    

    Replace USERNAME with the instance login user and NAT_GATEWAY_PUBLIC_IP with the NAT Gateway public IP address.

    A successful login confirms that the NAT Gateway forwards inbound SSH traffic to the private instance correctly.

Note
You can expose additional services by creating separate port forwarding rules that map public ports on the NAT Gateway to the corresponding service ports on the VPC only instance.

Verify Inter-instance Connectivity

VPC only instances connected to the same VPC network communicate with each other directly over private IP addresses without using the NAT Gateway.

Note
Inter-instance traffic within the same VPC does not traverse the NAT Gateway. The NAT Gateway is used only for outbound internet traffic and inbound traffic explicitly exposed through port forwarding rules.
  1. Connect to one of the VPC only instances using the existing SSH port forwarding rule.

    console
    $ ssh -p 2222 USERNAME@NAT_GATEWAY_PUBLIC_IP
    
  2. From the connected instance, test connectivity to another VPC only instance using its private IP address.

    console
    $ ping PRIVATE_IP_OF_OTHER_INSTANCE
    

    Replace PRIVATE_IP_OF_OTHER_INSTANCE with the private IP address noted earlier.

    Successful responses confirm that the instances communicate internally within the VPC using private networking.

Deploy Demo Services and Expose Inbound Access Through the NAT Gateway

Deploy simple demo services on two VPC only instances and verify that they can access each other over private networking.

Note
This section uses a simple Nginx service with a custom index.html file to demonstrate service communication inside a private VPC. In real-world scenarios, replace these steps with the deployment method required for your service, such as running containers with Docker, deploying a web framework, or starting application-specific services.

Deploy a Demo Service on Instance 1

Deploy a simple web service on Instance 1 to demonstrate an inbound service.

  1. Connect to Instance 1 using the existing SSH port forwarding rule.

  2. Install the Nginx web server.

    console
    $ sudo apt update
    $ sudo apt install -y nginx
    
  3. Create a demo page that identifies Instance 1.

    console
    $ sudo tee /var/www/html/index.html > /dev/null <<EOF
    <h1>Demo Service - Instance 1</h1>
    <p>This service runs on Instance 1 inside the VPC.</p>
    EOF
    
  4. Allow HTTP traffic through the firewall.

    console
    $ sudo ufw allow 80
    
  5. Verify that the service is running locally.

    console
    $ curl http://localhost
    

    A successful response confirms that the service is accessible.

Deploy a Demo Service on Instance 2

Deploy a simple web service on Instance 2 to demonstrate an inbound service.

  1. Connect to Instance 2 using SSH, either through its own port forwarding rule or by initiating an SSH connection from Instance 1 using Instance 2’s private IP address.

  2. Install the Nginx web server.

    console
    $ sudo apt update
    $ sudo apt install -y nginx
    
  3. Create a demo page that identifies Instance 2.

    console
    $ sudo tee /var/www/html/index.html > /dev/null <<EOF
    <h1>Demo Service - Instance 2</h1>
    <p>This service runs on Instance 2 inside the VPC.</p>
    EOF
    
  4. Allow HTTP traffic through the firewall.

    console
    $ sudo ufw allow 80
    
  5. Verify that the service is running locally.

    console
    $ curl http://localhost
    

    A successful response confirms that the service is accessible.

Verify Service Connectivity Between Instances

Verify that services on VPC only instances communicate with each other using private IP addresses.

  1. From Instance 1, access the service running on Instance 2 using its private IP address.

    console
    $ curl http://PRIVATE_IP_OF_INSTANCE_2
    

    Replace PRIVATE_IP_OF_INSTANCE_2 with the private IP of Instance 2.

  2. From Instance 2, access the service running on Instance 1 using its private IP address.

    console
    $ curl http://PRIVATE_IP_OF_INSTANCE_1
    

    Replace PRIVATE_IP_OF_INSTANCE_1 with the private IP of Instance 1.

Note
Successful responses confirm that services running on both instances can access each other over the VPC’s private network. This demonstrates secure inter-instance connectivity required for services such as databases and internal backends that do not require internet access.

Expose the Service Through NAT Gateway

Expose the service running on Instance 1 by creating an HTTP port forwarding rule on the NAT Gateway. This maps a public port on the NAT Gateway to port 80 on the private instance.

  1. Create an HTTP port forwarding rule.

    console
    $ curl -sS --location \
      --request POST "https://api.vultr.com/v2/vpcs/${VPC_ID}/nat-gateway/${NAT_GATEWAY_ID}/global/port-forwarding-rules" \
      --header "Content-Type: application/json" \
      --header "Authorization: Bearer ${VULTR_API_KEY}" \
      --data '{
        "name": "http-to-instance-1",
        "protocol": "tcp",
        "external_port": 8080,
        "internal_ip": "PRIVATE_IP_OF_INSTANCE_1",
        "internal_port": 80,
        "enabled": true,
        "description": "Expose HTTP service on Instance 1"
      }' \
      | jq .
    

    Replace PRIVATE_IP_OF_INSTANCE_1 with the private IP address of Instance 1.

  2. Verify that the HTTP port forwarding rule is active.

    console
    $ curl -sS --location \
      --request GET "https://api.vultr.com/v2/vpcs/${VPC_ID}/nat-gateway/${NAT_GATEWAY_ID}/global/port-forwarding-rules" \
      --header "Authorization: Bearer ${VULTR_API_KEY}" \
      | jq .
    

    Confirm that the rule appears in the output and that the enabled field is set to true.

  3. Access the service using the NAT Gateway public IP and exposed port.

    console
    $ curl http://NAT_GATEWAY_PUBLIC_IP:8080
    

    A successful response confirms that the service is exposed through the NAT Gateway and reachable from the public internet.

Conclusion

You have exposed inbound services on VPC only instances using a NAT Gateway on Vultr. By configuring port forwarding rules, you selectively publish services such as SSH and HTTP while keeping instances isolated from direct public access. Private instances continue to communicate internally over the VPC, and only explicitly defined ports become reachable from the internet.

Comments