> ## 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.

# Getting started with Nebius Tunnels: Connect a VM service to the internet

In this guide, you'll create a tunnel, prepare access for a tunnel agent, connect to a Compute virtual machine (VM) and run the agent on the VM. After the agent connects, your local service on the VM will be available through a public tunnel URL.

## Costs

Nebius Tunnels is provided free of charge during preview. If you create a VM for this guide, Nebius AI Cloud charges you for [Compute resources](/compute/resources/pricing).

## Prerequisites

1. [Install and configure](/cli/install) the Nebius AI Cloud CLI.

2. Check that your project ID is saved in the Nebius AI Cloud CLI profile configuration:
   ```bash theme={null}
   cat ~/.nebius/config.yaml
   ```

3. [Create a Compute VM](/compute/virtual-machines/manage#create-a-vm) or select an existing one.

4. [Set up SSH access to the VM](/compute/virtual-machines/connect) and make sure that a local HTTP service is available on the VM, for example at `localhost:8080`.

5. [Get the project ID](/iam/manage-projects#cli-3) and save it to an environment variable:

   ```bash theme={null}
   export PROJECT_ID=<project_ID>
   ```

6. [Get the tenant ID](/iam/get-tenants#cli) and save it to an environment variable:

   ```bash theme={null}
   export TENANT_ID=<tenant_ID>
   ```

   You'll need the tenant ID when granting the service account access to Nebius Tunnels.

## Steps

### Create a tunnel

Create a tunnel and save its ID:

```bash theme={null}
export TUNNEL_ID=$(nebius tunnel create \
  --title "quickstart-tunnel" \
  --format jsonpath='{.metadata.id}')
```

### Prepare agent access

1. Create a service account for the tunnel agent and save its ID:

   ```bash theme={null}
   export SA_ID=$(nebius iam service-account create \
     --name "tunnel-agent" \
     --parent-id "$PROJECT_ID" \
     --format jsonpath='{.metadata.id}')
   ```

2. Create a group for Nebius Tunnels service accounts and save its ID:

   ```bash theme={null}
   export GROUP_ID=$(nebius iam group create \
     --name "tunnel-agents" \
     --parent-id "$TENANT_ID" \
     --format jsonpath='{.metadata.id}')
   ```

3. Grant the group the `applicationtunnel.agent` role for the tunnel:

   ```bash theme={null}
   nebius iam access-permit create \
     --parent-id "$GROUP_ID" \
     --resource-id "$TUNNEL_ID" \
     --role applicationtunnel.agent
   ```

4. Add the service account to the group:

   ```bash theme={null}
   nebius iam group-membership create \
     --parent-id "$GROUP_ID" \
     --member-id "$SA_ID"
   ```

5. Create an authorized key pair:

   ```bash theme={null}
   openssl genrsa -out ./private_key.pem 4096
   openssl rsa -in ./private_key.pem -pubout -out ./public_key.pem
   ```

6. Upload the public key and save its ID:

   ```bash theme={null}
   export PUBLIC_KEY_ID=$(nebius iam auth-public-key create \
     --account-service-account-id "$SA_ID" \
     --data "$(cat ./public_key.pem)" \
     --format jsonpath='{.metadata.id}')
   ```

### Connect to the VM

Use the SSH access method that you configured for the VM. The VM doesn't need a public IP address for Nebius Tunnels, but your SSH client must be able to reach it, for example, by using a public IP address, a private IP address or an FQDN from another VM in the same network. For more information, see [How to connect to virtual machines in Nebius AI Cloud](/compute/virtual-machines/connect).

1. Copy the service account private key to the VM:

   ```bash theme={null}
   scp ./private_key.pem <username>@<VM_address_or_FQDN>:~/private_key.pem
   ```

2. Connect to the VM:

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

### Run the tunnel agent

Run the following commands on the VM.

1. Download and extract the `nebius-tunnel-agent` binary for your VM's OS and architecture.

   Available archives:

   * [macOS ARM64](https://storage.eu-north1.nebius.cloud/products/releases/nebius-tunnel-agent/latest/nebius-tunnel-agent-darwin-arm64.tar.gz)
   * [macOS x86\_64](https://storage.eu-north1.nebius.cloud/products/releases/nebius-tunnel-agent/latest/nebius-tunnel-agent-darwin-x86_64.tar.gz)
   * [Linux ARM64](https://storage.eu-north1.nebius.cloud/products/releases/nebius-tunnel-agent/latest/nebius-tunnel-agent-linux-aarch64.tar.gz)
   * [Linux x86\_64](https://storage.eu-north1.nebius.cloud/products/releases/nebius-tunnel-agent/latest/nebius-tunnel-agent-linux-x86_64.tar.gz)
   * [Windows ARM64](https://storage.eu-north1.nebius.cloud/products/releases/nebius-tunnel-agent/latest/nebius-tunnel-agent-windows-arm64.tar.gz)
   * [Windows x86\_64](https://storage.eu-north1.nebius.cloud/products/releases/nebius-tunnel-agent/latest/nebius-tunnel-agent-windows-x86_64.tar.gz)

   For example, to download and extract the Linux x86\_64 archive:

   ```bash theme={null}
   curl -LO https://storage.eu-north1.nebius.cloud/products/releases/nebius-tunnel-agent/latest/nebius-tunnel-agent-linux-x86_64.tar.gz
   tar -xzf nebius-tunnel-agent-linux-x86_64.tar.gz
   ```

2. Create `config.yaml` for the agent:

   ```bash theme={null}
   cat > config.yaml <<EOF
   tunnel_id: <tunnel_ID>

   iam:
     service_account:
       service_account_id: <service_account_ID>
       public_key_id: <authorized_key_ID>
       private_key_path: ./private_key.pem

   services:
     - name: web
       target: localhost:8080
       type: http
   EOF
   ```

   In the configuration, specify the following values:

   * `tunnel_ID`: Value of `$TUNNEL_ID`.
   * `service_account_ID`: Value of `$SA_ID`.
   * `authorized_key_ID`: Value of `$PUBLIC_KEY_ID`.

3. Run the agent:

   ```bash theme={null}
   ./nebius-tunnel-agent -config ./config.yaml
   ```

   When the agent connects, it returns the public endpoint in the following format:

   ```text theme={null}
   <service_name>-<tunnel_masked_ID>.tunnel.applications.<region>.nebius.cloud
   ```

   Where:

   * `service_name` is the `services.name` value from the agent configuration.
   * `tunnel_masked_ID` is the mask of the tunnel ID without the `applicationtunnel-` prefix and regional routing code. For example, for `applicationtunnel-<routing_code>abcdef1234`, the tunnel ID mask is `abcdef1234`.
   * `region` is the [region](/overview/regions) of the project where the tunnel was created, for example `eu-north1`.

4. Add the `https` scheme and open the returned endpoint in your browser.

## How to delete the created resources

If you don't need the tunnel, delete it:

```bash theme={null}
nebius tunnel delete --id "$TUNNEL_ID"
```

If you created a VM for this guide and don't need it anymore, [delete the VM](/compute/virtual-machines/delete), so Nebius AI Cloud doesn't charge for it.
