[Yandex Cloud documentation](../../index.md) > [Yandex BareMetal](../index.md) > [Tutorials](index.md) > Configuring DNS connectivity between Yandex BareMetal and Yandex Virtual Private Cloud to access Managed Service for PostgreSQL via FQDN

# Configuring DNS connectivity between Yandex BareMetal and Yandex Virtual Private Cloud to access Managed Service for PostgreSQL via FQDN

Using fully qualified domain names (FQDNs) to connect to cloud services such as Yandex Managed Service for PostgreSQL is a best practice which helps to achive infrastructure abstraction and process automation. FQDNs remain constant, while IP addresses may change when you scale, restore, or migrate services.

However, if a server in the BareMetal segment is connected to the cloud via Yandex Cloud Interconnect, you will have an issue resolving FQDNs of cloud services, since direct DNS queries from an external subnet get blocked.

To resolve this issue, we recommend deploying an intermediate VM in the same subnet as the Managed Service for PostgreSQL cluster to act as a Bind9-based DNS forwarder. This server will accept DNS requests from the BareMetal server, forward them to Yandex Cloud DNS, and return responses to the client, ensuring correct resolution of the cloud service FQDNs.

To configure DNS connectivity:

1. [Set up your infrastructure](#prepare-infra).
1. [Configure a DNS forwarder on a VM](#configure-forwarder).
1. [Configure a DNS client on the BareMetal server](#configure-baremetal).
1. [Test FQDN access to the Managed Service for PostgreSQL cluster](#check-postgresql).
1. [Check the result](#check-result).

If you no longer need the resources you created, [delete them](#clear-out).

## Set up your infrastructure {#prepare-infra}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).

### Required paid resources {#paid-resources}

The solution support costs include:

* Fee for using a VM and disk (see [Yandex Compute Cloud pricing](../../compute/pricing.md)).
* Fee for using a Managed Service for PostgreSQL cluster (see [Yandex Managed Service for PostgreSQL pricing](../../managed-postgresql/pricing.md)).
* Fee for renting the BareMetal servers (see [Yandex BareMetal pricing](../pricing.md)).
* Fee for Yandex Cloud Interconnect resource usage (see [Yandex Cloud Interconnect pricing](../../interconnect/pricing.md)).

### Create a Managed Service for PostgreSQL cluster {#create-postgresql-cluster}

1. In the [management console](https://console.yandex.cloud), select the folder where you want to create a cluster.
1. In the list of services, select **Managed Service for&nbsp;PostgreSQL**.
1. Click **Create cluster**.
1. Configure the cluster:
   * **Cluster name**: Specify the cluster name.
   * **Database**: Specify the database name, username, and password.
   * **Network settings**: Select the availability zones and subnets.
1. Click **Create cluster**.

   {% note info %}

   Creating a Managed Service for PostgreSQL cluster automatically creates a private DNS zone, `mdb.yandexcloud.net`, where DNS records for cluster hosts are generated. Host FQDNs have the `c-<cluster_ID>-<host_number>.mdb.yandexcloud.net` format. Inside the zone, DNS records for the database are automatically created as well, e.g., `10.129.0.29` for the master and `10.130.0.15` for the replica.

   {% endnote %}

For more information on creating a cluster, see [this guide](../../managed-postgresql/operations/cluster-create.md).

### Create a VM for a DNS forwarder {#create-dns-forwarder-vm}

1. In the [management console](https://console.yandex.cloud), select the folder where you want to create a VM.
1. In the list of services, select **Compute Cloud**.
1. In the left-hand panel, select ![image](../../_assets/console-icons/server.svg) **Virtual machines**.
1. Click **Create virtual machine**.
1. Under **General information**, enter the VM name.
1. Under **Boot disk image**, select the **Ubuntu 22.04 LTS** image.
1. Under **Network settings**:
   * In the **Subnet** field, select the subnet where the Managed Service for PostgreSQL cluster hosts are located, e.g., `10.129.0.0/24`.
   * Enter the VM internal IP address, e.g., `10.129.0.10`.
   * Make sure the availability zone matches the zone hosting the Managed Service for PostgreSQL cluster, e.g., `ru-central1-b`.
1. Click **Create VM**.

For more information on creating a VM, see [this guide](../../compute/operations/vm-create/create-linux-vm.md).

### Rent a BareMetal server {#lease-baremetal-server}

1. In the [management console](https://console.yandex.cloud), select the folder for the server you want to rent.
1. In the list of services, select **BareMetal**.
1. Click **Lease server**.
1. Set up the server:
   * Select the appropriate server [configuration](../concepts/server-configurations.md).
   * Assign or get a private IP address over DHCP, e.g., `172.16.2.2`.
1. Click **Lease server**.

For more information on renting a server, see [this guide](../operations/servers/server-lease.md).

### Configure network connectivity {#configure-network-connectivity}

Configure connectivity between the BareMetal and Virtual Private Cloud subnets via Yandex Cloud Interconnect:

1. Create a Virtual Private Cloud network with subnets in the availability zones you need.
1. Create a BareMetal private subnet.
1. Configure a connection via Yandex Cloud Interconnect between the BareMetal subnet and the Virtual Private Cloud subnet hosting the Managed Service for PostgreSQL cluster.

For more information on setting up network connectivity, see [this guide](bm-vrf-and-vpc-interconnect.md).

The examples below use the following parameters:

* BareMetal subnet: `172.16.2.0/24`
* BareMetal server IP address: `172.16.2.2`
* Virtual Private Cloud subnet with Managed Service for PostgreSQL hosts: `10.129.0.0/24`
* Bind9 VM IP address: `10.129.0.10`
* Virtual Private Cloud DNS resolvers: `10.129.0.2` and `10.130.0.2`

   {% note info %}

   Virtual Private Cloud DNS resolvers have addresses of the `10.X.0.2` type, where `X` is the subnet number. Each subnet in Virtual Private Cloud has its own DNS resolver available.

   {% endnote %}

### Create a security group for the DNS forwarder {#configure-sg}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder where you are deploying your infrastructure.
  1. In the list of services, select **Virtual Private Cloud**.
  1. In the left-hand panel, select ![image](../../_assets/console-icons/shield.svg) **Security groups** and click **Create security group**.
  1. In the **Name** field, specify `dns-forwarder-sg`.
  1. In the **Network** field, select the network the Bind9 VM resides in.
  1. Under **Rules**, [create](../../vpc/operations/security-group-add-rule.md) the following traffic management rules:

      | Traffic<br/>direction | Description | Port range | Protocol | Source /<br/>Destination name | CIDR blocks /<br/>Security group |
      | --- | --- | --- | --- | --- | --- |
      | Inbound | `dns-udp` | `53` | `UDP` | `CIDR` | `172.16.2.0/24` |
      | Inbound | `dns-tcp` | `53` | `TCP` | `CIDR` | `172.16.2.0/24` |
      | Outbound | `dns-udp-forward` | `53` | `UDP` | `CIDR` | `10.129.0.0/24` |
      | Outbound | `dns-tcp-forward` | `53` | `TCP` | `CIDR` | `10.129.0.0/24` |
      | Outbound | `dns-udp-forward` | `53` | `UDP` | `CIDR` | `10.130.0.0/24` |
      | Outbound | `dns-tcp-forward` | `53` | `TCP` | `CIDR` | `10.130.0.0/24` |

      {% note info %}

      This example uses the `10.129.0.0/24` and `10.130.0.0/24` subnets hosting the `10.129.0.2` and `10.130.0.2` DNS resolvers. Replace them with the subnets of your Virtual Private Cloud subnet DNS resolvers. Virtual Private Cloud DNS resolvers have addresses of the `10.X.0.2` type, where `X` is the subnet number.

      {% endnote %}

  1. If required, add a rule for SSH access to the VM:

      | Traffic<br/>direction | Description | Port range | Protocol | Source /<br/>Destination name | CIDR blocks /<br/>Security group |
      | --- | --- | --- | --- | --- | --- |
      | Ingress | `ssh` | `22` | `TCP` | `CIDR` | `<administrative_subnet_CIDR>` |

  1. Click **Create**.

{% endlist %}

## Configure a DNS forwarder on a VM {#configure-forwarder}

1. [Connect](../../compute/operations/vm-connect/ssh.md) to the VM over SSH.

1. Install Bind9:

   ```bash
   sudo apt update
   sudo apt install -y bind9 bind9-utils dnsutils
   ```

1. Open the `/etc/bind/named.conf.options` file and specify the forwarding options:

   ```bash
   sudo nano /etc/bind/named.conf.options
   ```

   Configuration example:

   ```text
   options {
     directory "/var/cache/bind";

     recursion yes;
     allow-recursion {
       172.16.2.0/24;
       localhost;
     };
     allow-query {
       172.16.2.0/24;
       localhost;
     };

     forwarders {
       10.129.0.2;
       10.130.0.2;
     };

     dnssec-validation auto;
     listen-on { any; };
     listen-on-v6 { any; };
   };
   ```

1. Check the configuration and restart the service:

   ```bash
   sudo named-checkconf
   sudo systemctl restart bind9
   sudo systemctl enable bind9
   ```

1. Make sure the service is running:

   ```bash
   sudo systemctl status bind9 --no-pager
   ```

1. If your VM is running the `systemd-resolved` local resolver which overwrites `/etc/resolv.conf`, configure it to work with Bind9:

   ```bash
   sudo systemctl stop systemd-resolved
   sudo systemctl disable systemd-resolved
   sudo mv /etc/resolv.conf /etc/resolv.conf.backup
   ```

   Create a static `/etc/resolv.conf` file:

   ```bash
   sudo nano /etc/resolv.conf
   ```

   Add a record:

   ```text
   nameserver 127.0.0.1
   ```

1. Set up a nameserver in Ubuntu. Edit the `/run/systemd/resolve/stub-resolv.conf` file:

   ```bash
   sudo nano /run/systemd/resolve/stub-resolv.conf
   ```

   Set `nameserver` to `127.0.0.1`.

1. Test the forwarder locally:

   ```bash
   dig @127.0.0.1 NS mdb.yandexcloud.net +short
   ```

   The response should include the zone's DNS server addresses.

   Alternative check:

   ```bash
   dig @127.0.0.1 yandex.ru +short
   ```

   If forwarding is configured correctly, this command will return the domain's IP address.

## Configure a DNS client on the BareMetal server {#configure-baremetal}

1. [Connect](../../compute/operations/vm-connect/ssh.md) to the BareMetal server over SSH.

1. Set the Bind9 VM's IP address as the DNS server:

   ```bash
   sudo nano /etc/resolv.conf
   ```

   Here is an example:

   ```text
   nameserver 10.129.0.10
   ```

1. If `/etc/resolv.conf` is managed by a system service, set DNS persistently.

   **Option 1:** Use the `systemd-resolve` command for a specific interface:

   ```bash
   sudo systemd-resolve --interface ethXX --set-dns 10.129.0.10
   ```

   Where `ethXX` is the private network interface.

   **Option 2:** Edit the `/etc/systemd/resolved.conf` file:

   ```bash
   sudo nano /etc/systemd/resolved.conf
   ```

   Specify the following:

   ```text
   [Resolve]
   DNS=10.129.0.10
   Domains=~.
   ```

   Apply the settings:

   ```bash
   sudo systemctl restart systemd-resolved
   ```

1. Test DNS resolution:

   ```bash
   dig mdb.yandexcloud.net +short
   ```

   Test resolution of the Managed Service for PostgreSQL cluster host FQDN:

   ```bash
   dig c-<cluster_ID>-<host_number>.mdb.yandexcloud.net +short
   ```

   The commands should return cluster host IP addresses from the Virtual Private Cloud subnet, e.g., `10.129.0.29` for the master and `10.130.0.15` for the replica.

## Test FQDN access to the Managed Service for PostgreSQL cluster {#check-postgresql}

1. Install the CA certificate:

   ```bash
   mkdir -p ~/.postgresql && \
   wget "https://storage.yandexcloud.net/cloud-certs/CA.pem" \
     --output-document ~/.postgresql/root.crt && \
   chmod 0600 ~/.postgresql/root.crt
   ```

1. Install the PostgreSQL client:

   ```bash
   sudo apt update && sudo apt install -y postgresql-client
   ```

1. Connect to the database using FQDNs:

   ```bash
   psql "host=<master_FQDN>,<replica_FQDN> port=6432 sslmode=verify-full dbname=<DB_name> user=<user_name> target_session_attrs=read-write"
   ```

   You can find the connection parameters for your cluster in the management console on the Managed Service for PostgreSQL cluster page.

## Check the result {#check-result}

After you complete the setup:

1. The server in the BareMetal segment successfully resolves domain names in the `mdb.yandexcloud.net` zone.
1. Managed Service for PostgreSQL сluster host FQDNs are resolved to Virtual Private Cloud IP addresses.
1. PostgreSQL connection is established using the FQDNs, so you do not need to manually specify IP addresses.

{% note warning %}

* Use static IP addresses for the DNS forwarder VM and the BareMetal server to avoid DNS resolution issues upon restart.
* Regularly check Bind9 logs to detect issues with DNS requests:

  ```bash
  sudo journalctl -u bind9 -f
  ```

* If you change the subnet hosting the Managed Service for PostgreSQL cluster, update the DNS resolver addresses in the `forwarders` Bind9 configuration parameter.

{% endnote %}

## How to delete the resources you created {#clear-out}

To stop using resources and avoid additional costs:

1. [Delete](../../compute/operations/vm-control/vm-delete.md) the VM with the DNS forwarder.
1. [Delete](../../vpc/operations/security-group-delete.md) the security group created for the DNS forwarder.
1. If you no longer need the test cluster, [delete](../../managed-postgresql/operations/cluster-delete.md) the Managed Service for PostgreSQL cluster.
1. If you used Yandex Cloud Interconnect to set up connectivity for testing purposes only, delete the associated network settings and Cloud Interconnect resources.