# VNet

VNet automatically proxies connections made to TCP applications available under the public address of a Proxy Service. This guide explains how to configure VNet to support apps with [custom public addresses](https://goteleport.com/docs/enroll-resources/application-access/protect-apps/connecting-apps.md#customize-public-address).

## How it works

Let's assume that a user has logged in to a cluster through a Proxy Service available at `teleport.example.com`. There's a leaf cluster associated with that cluster. It has its own Proxy Service available at `leaf.example.com`. Once started, VNet captures DNS queries for both of those domains and their subdomains.

Type A and AAAA queries are matched against `public_addr` of applications registered in both clusters. If there's a match and the application is registered as a TCP application, VNet responds with a virtual IP address over which the connection will be proxied to the app. In any other case, the query is forwarded to the default DNS name server used by the OS.

If you want VNet to forward connections to an app that has a custom `public_addr` set, you need to first update the VNet config in the Auth Service to include a matching DNS zone.

## Prerequisites

- A running Teleport (v16.0.0 or higher) cluster. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

- The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

* To check that you can connect to your Teleport cluster, sign in with `tsh login`, then verify that you can run `tctl` commands using your current credentials. For example, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ tctl status
  Cluster  teleport.example.com
  Version  18.7.3
  CA pin   sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
  ```
  If you can connect to the cluster and run the `tctl status` command, you can use your current credentials to run subsequent `tctl` commands from your workstation. If you host your own Teleport cluster, you can also run `tctl` commands on the computer that hosts the Teleport Auth Service for full permissions.
* A TCP application connected to the cluster.
* A domain name under your control.

In this guide, we'll use the example app from [TCP Application Access guide](https://goteleport.com/docs/enroll-resources/application-access/protect-apps/tcp.md) and make it available through VNet at public\_addr with suffix as the custom DNS zone.

## Step 1/3. Configure custom DNS zone

Edit the VNet config:

```
$ tctl edit vnet_config
```

Add a custom DNS zone. In our case the `public_addr` of the app is going to be `tcp-app.company.test`, so we're going to set `company.test` as `suffix`. The `spec` section of the config should include the `custom_dns_zones` field:

```
kind: vnet_config
metadata:
  name: vnet-config
  # …
spec:
+ custom_dns_zones:
+ - suffix: suffix
  # …
version: v1

```

---

RELATIONSHIP BETWEEN SUFFIX AND PUBLIC\_ADDR

`suffix` doesn't have to point to a domain that's exactly one level above the `public_addr` of an app. Any level of nesting works. For example, you can have an app under `tcp-app.foo.bar.qux.test` and the suffix can be set to `bar.qux.test`.

---

## Step 2/3. Set `public_addr` of the app

Set `public_addr` field of the application in the Application Service configuration file `/etc/teleport.yaml` and restart the `teleport` daemon.

```
version: v3
# …
app_service:
  # …
  apps:
  - name: "tcp-app"
    uri: tcp://localhost:5432
+   public_addr: "public_addr"

```

## Step 3/3. Connect

Once you [start VNet](https://goteleport.com/docs/connect-your-client/teleport-clients/vnet.md), you should be able to connect to the application over the custom `public_addr` using the application client you would normally use to connect to it. You might need to restart VNet if it was already running while you were making changes to the cluster.

```
$ psql postgres://postgres@tcp-app.company.test/postgres
```

## Next steps

### Configuring IPv4 CIDR range

Each cluster has a configurable IPv4 CIDR range which VNet uses when assigning IP addresses to applications from that cluster. Root and leaf clusters can use different ranges. The default is `100.64.0.0/10` and it can be changed by setting the `ipv4_cidr_range` field of the VNet config.

Edit the VNet config:

```
$ tctl edit vnet_config
```

Edit the `ipv4_cidr_range` field in the `spec` section of the config:

```
kind: vnet_config
metadata:
  name: vnet-config
  # …
spec:
+ ipv4_cidr_range: "100.64.0.0/10"
  # …
version: v1

```

---

IPV4 ADDRESS OF THE TUN DEVICE

When starting, VNet needs to assign an IPv4 address for its virtual network device. To pick an address, [VNet arbitrarily chooses a root cluster](https://github.com/gravitational/teleport/issues/43343) that the user is logged in to and picks an address from the range used by that cluster. If your cluster uses a custom range, but your users are logged in to other clusters that are not under your control, this might cause VNet to pick an address for the TUN device from a range offered by one of those clusters.

---

### Configuring leaf cluster apps

To make a [leaf cluster](https://goteleport.com/docs/zero-trust-access/deploy-a-cluster/trustedclusters.md) app accessible over a custom `public_addr`, you need to follow the same steps while being logged in directly to the leaf cluster.

```
$ tsh login --proxy=leaf.example.com --user=email@example.com
```

### Accessing web apps through VNet

VNet does not officially support [web apps](https://goteleport.com/docs/enroll-resources/application-access/protect-apps/connecting-apps.md) yet. However, since all web apps are served over TCP, it's possible to convert a web app to [a TCP app](https://goteleport.com/docs/enroll-resources/application-access/protect-apps/tcp.md) to make it available via VNet. You'll need to change the `uri` of the application to use `tcp://` instead of `https://`.

Exposing plain HTTP web apps or APIs via VNet is not recommended. Untrusted websites can potentially use DNS rebinding attacks to bypass the browser’s Same-Origin Policy and issue plain HTTP requests to VNet IP addresses. It is strongly recommended to either avoid VNet for plain HTTP access or implement one or more of the following mitigations for DNS rebinding attacks:

- upgrade these APIs to HTTPS or another protocol
- enforce a Host header allowlist at the HTTP server
- block browser access to HTTP websites

There are a few more caveats when converting a Teleport web app to a TCP app:

- The Teleport Web UI uses [HSTS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security). If the application is going to be served from a subdomain of a Proxy Service it must use HTTPS, it will not be accessible in browsers over plain HTTP. It's possible to work around this by setting a custom `public_addr` as explained above in this guide to an address that is not a subdomain of the proxy address.
- HTTPS Applications must handle their own TLS connections and have a valid certificate for the app `public_addr`.
- [JWT Tokens](https://goteleport.com/docs/enroll-resources/application-access/jwt/introduction.md), [redirects](https://goteleport.com/docs/enroll-resources/application-access/protect-apps/connecting-apps.md#rewrite-redirect) and [header rewrites](https://goteleport.com/docs/enroll-resources/application-access/protect-apps/connecting-apps.md#headers-passthrough) are not available for TCP apps.
- Teleport records the start and the end of a session for TCP apps in the audit log, but [session chunks](https://goteleport.com/docs/reference/architecture/session-recording.md) are not captured.

The important thing to understand is that VNet doesn't do anything extra with a TCP connection, it tunnels it directly to the target application's `uri`. The application layer protocol is determined solely by the app itself and its clients.

### Further reading

- Read our VNet usage [guide](https://goteleport.com/docs/connect-your-client/teleport-clients/vnet.md) for end-users accessing your applications with VNet.
- Read [RFD 163](https://github.com/gravitational/teleport/blob/master/rfd/0163-vnet.md) to learn how VNet works on a technical level.
