> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nebius.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Setting up a custom NAT gateway for subnets

By default, traffic from your Nebius AI Cloud resources to public IP addresses is routed to the internet through the [default egress gateway](/vpc/routing/overview#default-egress-gateway). You can set up a Compute virtual machine (VM) as a custom gateway for traffic from specific subnets to the internet. The gateway is called a NAT gateway because it uses [network address translation](https://en.wikipedia.org/wiki/Network_address_translation) (NAT) to change the egress traffic's source IP address. This change causes the traffic to appear as if it were sent from the public IP address of the gateway VM rather than the private IP address of the originating resource.

## Costs

Nebius AI Cloud charges you for running Compute virtual machines. For more details, see [Compute pricing](/compute/resources/pricing).

## Prerequisites

1. [Install and configure the Nebius AI Cloud CLI](/cli/quickstart).
2. Make sure you are in a [group](/iam/authorization/groups/index) that has at least the `editor` role within your tenant or project; for example, the default `editors` group. You can check this in the [Administration → IAM](https://console.nebius.com/iam) section of the web console.

## Steps

### Create a gateway virtual machine

1. Get the ID of the network that contains the subnets for which you want to set up routing:

   ```bash theme={null}
   nebius vpc network list
   ```

   Save the network's ID from the `.metadata.id` parameter.

2. Create a subnet for the gateway virtual machine (VM):

   ```bash theme={null}
   nebius vpc subnet create --name gateway-subnet --network-id <network_ID>
   ```

   Save the subnet's ID from the `.metadata.id` parameter.

   <Warning>
     The subnet for the gateway VM must be a separate subnet. In later steps, you create a routing table (route table) and assign it to subnets to which the new routing should apply; assigning this routing table to the gateway VM's subnet leads to routing loops.
   </Warning>

3. Create a private allocation for the gateway VM:

   ```bash theme={null}
   nebius vpc allocation create \
      --name gateway-allocation \
      --ipv4-private-subnet-id <gateway_subnet_ID>
   ```

   Save the allocation's ID from the `.metadata.id` parameter.

4. Create the gateway VM. It must have a network interface that is located in the created subnet, has the allocated private IP address and a public IP address:

   ```bash theme={null}
   nebius compute instance create \
      --name gateway-vm \
      --network-interfaces "[{
        \"name\": \"eth0\",
        \"ip_address\": {
          \"allocation_id\": \"<gateway_allocation_ID>\"
        },
        \"subnet_id\": \"<gateway_subnet_ID>\",
        \"public_ip_address\": {}
      }]" \
      <other_parameters>
   ```

   <Accordion title="Full example">
     ```bash theme={null}
     VM_BOOT_DISK_ID=$(nebius compute disk create \
        --name gateway-boot-disk \
        --size-gibibytes 50 \
        --type network_ssd \
        --source-image-family-image-family ubuntu24.04-cuda13.0 \
        --block-size-bytes 4096 \
        --format json | jq -r ".metadata.id")

     nebius compute instance create \
        --name gateway-vm-example \
        --resources-platform cpu-d3 \
        --resources-preset 4vcpu-16gb \
        --boot-disk-existing-disk-id $VM_BOOT_DISK_ID \
        --boot-disk-attach-mode read_write \
        --boot-disk-device-id boot-disk \
        --network-interfaces "[{
          \"name\": \"eth0\",
          \"ip_address\": {
            \"allocation_id\": \"<gateway_allocation_ID>\"
          },
          \"subnet_id\": \"<gateway_subnet_ID>\",
          \"public_ip_address\": {}
        }]" \
        --cloud-init-user-data "users:
          - name: $USER
            sudo: ALL=(ALL) NOPASSWD:ALL
            shell: /bin/bash
            ssh_authorized_keys:
             - $(cat ~/.ssh/id_ed25519.pub)"
     ```
   </Accordion>

   For more details about VM parameters, see [How to create a virtual machine in Nebius AI Cloud](/compute/virtual-machines/manage).

### Set up the gateway VM

1. Connect to the gateway VM by using SSH:

   ```bash theme={null}
   ssh <username>@<public_IP_address>
   ```

   For more details, see [How to connect to virtual machines in Nebius AI Cloud](/compute/virtual-machines/connect).

2. Enable IPv4 routing and make this change persistent:

   ```bash theme={null}
   sudo sysctl -w net.ipv4.ip_forward=1
   sudo sed -i -E 's/^(#\s?)?net.ipv4.ip_forward.*/net.ipv4.ip_forward=1/' /etc/sysctl.conf
   ```

3. Enable egress NAT and make this change persistent:

   ```bash theme={null}
   sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
   sudo apt-get install iptables-persistent
   ```

   The latter command asks you whether to save your current `iptables` IPv4 and IPv6 rules to files. Answer "yes" to both.

4. Disconnect from the gateway VM:

   ```bash theme={null}
   exit
   ```

### Set up routing

1. Create a routing table in the network:

   ```bash theme={null}
   nebius vpc route-table create \
      --name gateway-table \
      --network-id <network_ID>
   ```

   Save the routing table's ID from the `.metadata.id` parameter.

2. Create a route in the routing table to send egress traffic to the gateway private allocation:

   ```bash theme={null}
   nebius vpc route create \
      --name route-to-allocation \
      --parent-id <routing_table_ID> \
      --destination-cidr 0.0.0.0/0 \
      --next-hop-allocation-id <gateway_allocation_ID>
   ```

3. Assign the routing table to the subnets that should use the NAT gateway:

   ```bash theme={null}
   nebius vpc subnet update <subnet_ID> \
      --route-table-id <routing_table_ID>
   ```

   Repeat for each subnet as needed. Do not assign the routing table to the subnet of the gateway VM (`gateway-subnet`).

### Test routing

To test that the routing table works, send traffic from a VM in a subnet to which you assigned the routing table (a test VM) and check its source IP address:

1. Connect to the test VM by using the gateway VM as the jump host:

   ```bash theme={null}
   ssh -J <username>@<gateway_public_IP_address> <username>@<VM_private_IP_address>
   ```

2. Verify that egress traffic from the test VM to the internet is routed through the gateway VM, by using a public service that looks up the traffic's source IP address:

   ```bash theme={null}
   curl ifconfig.me
   ```

   The command should return the public IP address of the gateway VM. If it returns the private address of the test VM instead:

   * Check that you assigned the routing table to the subnet: run `nebius vpc route-table get <routing_table_ID>` and then find the subnet in the `.status.assignment.subnets` parameter.
   * Check that the test VM belongs to this subnet: run `nebius compute instance get <VM_ID>` and then find the subnet in the `.spec.network_interfaces[0].subnet_id` parameter.
   * Check that you specified the gateway VM's private allocation as the next hop in the route: run `nebius vpc route list --parent-id <routing_table_ID>` and then find the allocation in the `.spec.next_hop.allocation.id` parameter.

## How to delete the created resources

The created Compute virtual machines are chargeable. If you don't need them, [delete these VMs](/compute/virtual-machines/manage#how-to-delete-vms), so Nebius AI Cloud doesn't charge for them.

You can also delete the [routing tables](/vpc/routing/manage#deleting-routing-tables) and [allocations](/cli/reference/vpc/allocation/delete) if you no longer need them.
