Using Cloudflare Tunnel's private networks, users can connect to arbitrary non-browser based TCP/UDP applications, like databases. You can set up network policies that implement zero trust controls to define who and what can access those applications using the WARP client.

By the end of this tutorial, users that pass network policies will be able to access a remote MySQL database available through a Cloudflare Tunnel on TCP port 3306.

## Before you begin

Make sure you have:

* A MySQL database listening for remote connections and configured with users that can connect remotely
* (Optional)[Resolver policies](https://developers.cloudflare.com/cloudflare-one/policies/gateway/resolver-policies/) enabled on your account

## Create a Cloudflare Tunnel

Install `cloudflared` on a server in your private network. This server should have connectivity to the MySQL database.

1. Log in to [Zero Trust](https://one.dash.cloudflare.com) and go to **Networks** > **Tunnels**.

2. Select **Create a tunnel**.

3. Choose **Cloudflared** for the connector type and select **Next**.

4. Enter a name for your tunnel. We suggest choosing a name that reflects the type of resources you want to connect through this tunnel (for example, `enterprise-VPC-01`).

5. Select **Save tunnel**.

6. Next, you will need to install `cloudflared` and run it. To do so, check that the environment under **Choose an environment** reflects the operating system on your machine, then copy the command in the box below and paste it into a terminal window. Run the command.

7. Once the command has finished running, your connector will appear in Zero Trust.

   ![Connector appearing in the UI after cloudflared has run](https://developers.cloudflare.com/_astro/connector.DgDJjokf_1bYl1O.webp)

8. Select **Next**.

## Add private network routes

1. In the **Private Networks** tab, add the following IP addresses:

* Private IP/CIDR of your MySQL server (for example, `10.128.0.175/32`)
* (Optional) Private IP/CIDR of your internal DNS server

1. Select **Save tunnel**.

The application and (optional) DNS server are now connected to Cloudflare.

## Create a Gateway network policy

1. Go to **Gateway** > **Firewall policies** > **Network**.
2. Add a [network policy](https://developers.cloudflare.com/cloudflare-one/policies/gateway/network-policies/) that targets the private IP address and the port of the MySQL database (port 3306 by default). The following example allows access to the database to the users that enrolled into WARP using an `@example.com` email address. The network policies can also take into consideration [device posture checks](https://developers.cloudflare.com/cloudflare-one/identity/devices/).

| Selector         | Operator      | Value           | Logic | Action |
| ---------------- | ------------- | --------------- | ----- | ------ |
| Destination IP   | in            | `10.128.0.175`  | And   | Allow  |
| Destination Port | in            | `3306`          | And   |        |
| User Email       | matches regex | `.*example.com` |       |        |

In addition to the Allow rule above, Cloudflare recommends adding a [catch-all block policy](https://developers.cloudflare.com/learning-paths/replace-vpn/build-policies/) to the bottom of your network policy list to enforce a default-deny model.

Allowed WARP users can now connect to the MySQL server at `10.128.0.175` using the MySQL client of their choice.

## (Optional) Create a Gateway resolver policy

To allow users to access the MySQL database using an internal hostname instead of the private IP address, configure a Gateway resolver policy.

1. Go to **Gateway** > **Resolver policies**.

2. Select **Add a policy**.

3. Create an expression to match against the private [domain](https://developers.cloudflare.com/cloudflare-one/policies/gateway/resolver-policies/#domain) or [hostname](https://developers.cloudflare.com/cloudflare-one/policies/gateway/resolver-policies/#host) of the application, like in the following example:

   | Selector | Operator | Value                |
   | -------- | -------- | -------------------- |
   | Domain   | in       | `internalrecord.com` |

4. In **Select DNS resolver**, select *Configure custom DNS resolvers*.

5. Enter the private IP address of your DNS server.

6. In the dropdown menu, select *`<IP-address> - Private`*.

7. (Optional) Enter a custom port.

8. Select **Create policy**.

If your internal DNS server has an `A` record for the MySQL database, users can connect to the server using this record. For example, assuming a BIND server that includes the entry:

`mysql IN A 10.128.0.175`

Allowed WARP users can connect to the MySQL database at `mysql.internalrecord.com` using the MySQL client of their choice.
