[Yandex Cloud documentation](../../../index.md) > [Tutorials](../../index.md) > Basic infrastructure > VPNs > [Establishing network connectivity with the help of IPsec gateways](index.md) > Deploying S2S VPN using strongSwan in Yandex Cloud

# Deploying S2S VPN using strongSwan in Yandex Cloud


Follow this tutorial to deploy a secure site-to-site (S2S) VPN connection between a cloud infrastructure in Yandex Cloud and a remote site using a [strongSwan](https://www.strongswan.org/)-based IPsec gateway. We will do this using the [strongSwan S2S VPN](https://yandex.cloud/en/marketplace/products/yc/ipsec-sgw) application from the [Yandex Cloud Apps](https://yandex.cloud/en/services/cloud-apps/) folder. This application automates the deployment and basic configuration of your IPsec tunnel, allowing you to:

* Quickly create a secure channel over the public internet.
* Encrypt traffic between subnets.
* Integrate cloud resources into the corporate network while maintaining control over routing.

{% note info %}

This off-the-shelf application automates infrastructure deployment in Yandex Cloud.

When using strongSwan S2S VPN at a remote location (your on-premises data center, branch office, or another cloud), manual configuration is required.

{% endnote %}

To deploy a secure connection:

1. [Get your cloud ready](#before-you-begin).
1. [Create a service account](#create-service-account).
1. [Create a cloud network](#create-vpc).
1. [Reserve a public static IP address](#reserve-public-static-ip).
1. [Create an SSH key pair](#create-ssh-keys).
2. [Deploy the application](#app-deploy).

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


## Required paid resources {#paid-resources}

The cost of infrastructure deployment for this solution includes:

* Fee for a continuously running VM (see [Yandex Compute Cloud pricing](../../../compute/pricing.md)).
* Fee for a static external IP address (see [Yandex Virtual Private Cloud pricing](../../../vpc/pricing.md)).
* Fee for outbound traffic (see [Yandex Virtual Private Cloud pricing](../../../vpc/pricing.md)).


## Get your cloud ready {#before-you-begin}

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


## Create a service account {#create-service-account}

Create an `s2s-vpn-sa` [service account](../../../iam/concepts/users/service-accounts.md) to automatically create resources when you install the application. Assign the `resource-manager.admin`, `iam.admin`, `compute.admin`, and `vpc.admin` roles to it.

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to **Identity and Access Management**.
  1. Click **Create service account**.
  1. Name the service account: `s2s-vpn-sa`.
  1. Click **Add role** and select these roles:
      * `resource-manager.admin`
      * `iam.admin`
      * `compute.admin`
      * `vpc.admin`

  1. Click **Create**.

- Yandex Cloud CLI {#cli}

  If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../../cli/quickstart.md#install).

  The folder used by default is the one specified when [creating](../../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

  1. Create a service account named `s2s-vpn-sa`:

      ```bash
      yc iam service-account create --name s2s-vpn-sa
      ```

      Result:

      ```text
      id: nfersamh4sjq********
      folder_id: b1gc1t4cb638********
      created_at: "2023-03-21T10:36:29.726397755Z"
      name: s2s-vpn-sa
      ```

      Save the ID of the `s2s-vpn-sa` service account (`id`) and the ID of the folder where you created it (`folder_id`).

  1. Assign the `resource-manager.admin`, `iam.admin`, `compute.admin`, and `vpc.admin` roles for the folder to the service account:

      ```bash
      yc resource-manager folder add-access-binding <folder_ID> \
        --role resource-manager.admin \
        --subject serviceAccount:<service_account_ID>

      yc resource-manager folder add-access-binding <folder_ID> \
        --role iam.admin \
        --subject serviceAccount:<service_account_ID>

      yc resource-manager folder add-access-binding <folder_ID> \
        --role compute.admin \
        --subject serviceAccount:<service_account_ID>

      yc resource-manager folder add-access-binding <folder_ID> \
        --role vpc.admin \
        --subject serviceAccount:<service_account_ID>
      ```

      Result:

      ```text
      done (1s)
      ```

- API {#api}

  To create a service account, use the [create](../../../iam/api-ref/ServiceAccount/create.md) method for the [ServiceAccount](../../../iam/api-ref/ServiceAccount/index.md) resource or the [ServiceAccountService/Create](../../../iam/api-ref/grpc/ServiceAccount/create.md) gRPC API call.

  To assign the roles for a folder to a service account, use the [setAccessBindings](../../../iam/api-ref/ServiceAccount/setAccessBindings.md) method for the [ServiceAccount](../../../iam/api-ref/ServiceAccount/index.md) resource or the [ServiceAccountService/SetAccessBindings](../../../iam/api-ref/grpc/ServiceAccount/setAccessBindings.md) gRPC API call.

{% endlist %}

## Create a cloud network {#create-vpc}

Create a [cloud network](../../../vpc/concepts/network.md) to host the VM.

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to **Virtual Private Cloud**.
  1. At the top right, click **Create network**.
  1. In the **Name** field, specify `s2s-vpn-network`.
  1. In the **Advanced** field, disable **Create subnets**.
  1. Click **Create network**.

- Yandex Cloud CLI {#cli}

  Run this command:

  ```bash
  yc vpc network create s2s-vpn-network
  ```

  Result:

  ```text
  id: enp1gg8kr3pv********
  folder_id: b1gt6g8ht345********
  created_at: "2023-12-20T20:08:11Z"
  name: s2s-vpn-network
  default_security_group_id: enppne4l2eg5********
  ```

- API {#api}

  To create a cloud network, use the [create](../../../vpc/api-ref/Network/create.md) REST API method for the [Network](../../../vpc/api-ref/Network/index.md) resource or the [NetworkService/Create](../../../vpc/api-ref/grpc/Network/create.md) gRPC API call.

{% endlist %}


## Reserve a public static IP address {#reserve-public-static-ip}

Reserve a static [public IP address](../../../vpc/concepts/address.md#public-addresses) for the VM the application will be installed on.

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to **Virtual Private Cloud**.
  1. In the left-hand panel, select ![image](../../../_assets/console-icons/map-pin.svg) **Public IP addresses** and click **Reserve public IP address**.
  1. In the window that opens, select `ru-central1-b` in the **Availability zone** field and click ** Reserve**.

{% endlist %}


## Create an SSH key pair {#create-ssh-keys}

To connect to a [VM](../../../compute/concepts/vm.md) over SSH, you will need a key pair: the public key resides on the VM, and the private one is kept by the user. This method is more secure than with a username and password.

{% note info %}

SSH connections using a login and password are disabled by default on public Linux images that are provided by Yandex Cloud.

{% endnote %}

To create a key pair:

{% list tabs group=operating_system %}

- Linux/macOS {#linux-macos}

  1. Open the terminal.
  1. Use the `ssh-keygen` command to create a new key:
  
      ```bash
      ssh-keygen -t ed25519 -C "<optional_comment>"
      ```
  
      You can specify an empty string in the `-C` parameter to avoid adding a comment, or you may not specify the `-C` parameter at all: in this case, a default comment will be added.
  
      After running this command, you will be prompted to specify the name and path to the key files, as well as enter the password for the private key. If you only specify the name, the key pair will be created in the current directory. The public key will be saved in a file with the `.pub` extension, while the private key, in a file without extension.
  
      By default, the command prompts you to save the key under the `id_ed25519` name in the following directory: `/home/<username>/.ssh`. If there is already an SSH key named `id_ed25519` in this directory, you may accidentally overwrite it and lose access to the resources it is used in. Therefore, you may want to use unique names for all SSH keys.

- Windows 10/11 {#windows}

  If you do not have [OpenSSH](https://en.wikipedia.org/wiki/OpenSSH) installed yet, follow this [guide](https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui) to install it.
  
  1. Run `cmd.exe` or `powershell.exe` (make sure to update PowerShell before doing so).
  1. Use the `ssh-keygen` command to create a new key:
  
      ```shell
      ssh-keygen -t ed25519 -C "<optional_comment>"
      ```
  
      You can specify an empty string in the `-C` parameter to avoid adding a comment, or you may not specify the `-C` parameter at all: in this case, a default comment will be added.
  
      After running this command, you will be prompted to specify the name and path to the key files, as well as enter the password for the private key. If you only specify the name, the key pair will be created in the current directory. The public key will be saved in a file with the `.pub` extension, while the private key, in a file without extension.
  
      By default, the command prompts you to save the key under the `id_ed25519` name in the following folder: `C:\Users\<username>/.ssh`. If there is already an SSH key named `id_ed25519` in this directory, you may accidentally overwrite it and lose access to the resources it is used in. Therefore, you may want to use unique names for all SSH keys.

- Windows 7/8 {#windows7-8}

  Create keys using the PuTTY app:
  
  1. [Download](https://www.putty.org) and install PuTTY.
  1. Add the folder with PuTTY to the `PATH` variable:
  
      1. Click **Start** and type **Change system environment variables** in the Windows search bar.
      1. Click **Environment Variables...** at the bottom right.
      1. In the window that opens, find the `PATH` parameter and click **Edit**.
      1. Add your folder path to the list.
      1. Click **OK**.
  
  1. Launch the PuTTYgen app.
  1. Select **EdDSA** as the pair type to generate. Click **Generate** and move the cursor in the field above it until key creation is complete.
  
      ![ssh_generate_key](../../../_assets/compute/ssh-putty/ssh_generate_key.png)
  
  1. In **Key passphrase**, enter a strong password. Enter it again in the field below.
  1. Click **Save private key** and save the private key. Do not share its key phrase with anyone.
  1. Click **Save public key** and save the public key to a file named `<key_name>.pub`.

{% endlist %}


## Deploy the application {#app-deploy}

### Install the application {#install-app}

As a result of the installation, the following Yandex Cloud resources will be automatically created:

* [Service account](../../../iam/concepts/users/service-accounts.md)
* [Subnet](../../../vpc/concepts/network.md#subnet)
* [IP_address](../../../vpc/concepts/address.md#public-addresses)
* [Route table](../../../vpc/concepts/routing.md#rt-vm)
* [Security group](../../../vpc/concepts/security-groups.md)
* [VM](../../../compute/concepts/vm.md)

{% note warning %}

[Make sure](../../../quota-manager/operations/read-quotas.md) the target cloud has not reached its quota:

* **Number of service accounts**
* **Number of subnets**
* **Number of static public IP addresses**
* **Number of routing tables**
* **Number of static routes**
* **Number of security groups**
* **Number of instances**
* **Number of disks**
* **Total SSD capacity**
* **Total RAM for instances**

If any quota has been used up, create a quota increase request and wait for it to be granted.

{% endnote %}

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to **Cloud Apps**.
  1. In the left-hand panel, select ![image](../../../_assets/console-icons/shopping-cart.svg) **Marketplace**.
  1. In the **Search products** field, type `strongswan`, select **strongSwan S2S VPN**, and click **Use**.
  1. In the window that opens, specify the following:

      * **Name**: `s2s-vpn`.
      * **Service account**: `s2s-vpn-sa`.
      * **VPC network**: `s2s-vpn-network`.
      * **New subnet CIDR**: `10.130.0.0/24`.
      * **New subnet zone**: `ru-central1-b`.
      * **Remote gateway IP address**: IP address of the remote VPN gateway that will be added to the strongSwan configuration.
      * **Remote subnet CIDRs**: Comma-separated list of subnets as CIDRs that will be automatically added to the route table.
      * **SSH key**: Contents of the public SSH key created [earlier](#create-ssh-keys).
      * **IPsec IKE Proposal**: `aes128gcm16-prfsha256-ecp256`.
      * **IPsec ESP Proposal**: `aes128gcm16`.
      * **IPsec PSK**: IPsec Pre-Shared Key (PSK) that will be specified in the strongSwan configuration.

  1. Click **Install** and wait for the installation to complete.

{% endlist %}


### Bind the route table {#bind-table}

To route traffic between a cloud and remote networks through the VPN tunnel, bind the route table and subnet.

{% list tabs group=instructions %}

- Management console {#console}

  1. Navigate to **Virtual Private Cloud**.
  1. In the left-hand panel, select ![image](../../../_assets/console-icons/nodes-right.svg) **Subnets**.
  1. In the line of the automatically created `ipsec-sgw-...` subnet, click ![image](../../../_assets/console-icons/ellipsis.svg) → **Link routing table** and select the automatically created `ipsec-sgw-...` table.
  1. Click **Link**.

- Yandex Cloud CLI {#cli}

  Run this command:

  ```bash
  yc vpc subnet update <name_of_automatically_created_subnet> \
    --route-table-name=<name_of_automatically_created_table>
  ```

  Result:

  ```text
  id: e9b6n3jj3gh6********
  folder_id: b1g681qpemb4********
  created_at: "2024-05-19T13:24:58Z"
  name: ipsec-sgw-ru-central1-b
  network_id: enppoggov6ub********
  zone_id: ru-central1-b
  v4_cidr_blocks:
    - 10.1.0.0/16
  route_table_id: enp4v8foko6s********
  dhcp_options: {}
  ```

- API {#api}

  To associate a route table with a subnet, use the [update](../../../vpc/api-ref/Subnet/update.md) REST API method for the [Subnet](../../../vpc/api-ref/Subnet/index.md) resource or the [SubnetService/Update](../../../vpc/api-ref/grpc/Subnet/update.md) gRPC API call.

  {% note warning %}
  
  The API method will assign default values to all the parameters of the object you are modifying unless you explicitly provide them in your request. To avoid this, list the settings you want to change in the `updateMask` parameter as a single comma-separated string.
  
  {% endnote %}

{% endlist %}


### Configure the VM {#configure-vm}

After you install the application, perform the final configuration of the IPsec gateway on the VM.

1. [Connect](../../../compute/operations/images-with-pre-installed-software/operate.md#vm-connect) to the VM over SSH. To this using the `admin` username and the private SSH key you [created earlier](#create-ssh-keys).
1. Get administrator permissions:

    ```bash
    sudo su
    ```

1. Go to the administrator's home folder and run the script:

    ```bash
    cd /root
    ./update.sh
    ```

    The system will create the `ipsec-*.txt` files in the `/root` folder. You can use these files as an example when configuring a connection on a remote endpoint.

    {% note tip %}

    If the IP ranges of Yandex Cloud and the remote network match, you may need to use Source NAT. Do it by running this command:

    ```bash
    iptables \
      -t nat \
      -A POSTROUTING \
      -s <local_subnet> \
      -d <remote_subnet> \
      -j SNAT \
      --to-source <new_address>
    ```

    {% endnote %}


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

To stop paying for the resources you created:

* Uninstall strongSwan S2S VPN:

    1. Navigate to **Cloud Apps**.
    1. In the line with the application, click ![image](../../../_assets/console-icons/ellipsis.svg) → **Delete** and confirm the deletion.

        Deleting the application will delete all resources associated with it.

* [Delete](../../../vpc/operations/delete-route-table.md) the route table.
* [Delete](../../../iam/operations/sa/delete.md) the service account.
* [Delete](../../../vpc/operations/address-delete.md) the static public IP address.
* [Delete](../../../vpc/operations/network-delete.md) the cloud network.