---
title: Configure SSH by using the virtctl CLI tool
---

# Configure SSH by using the virtctl CLI tool {#virt-using-virtctl-ssh}

You can add a public SSH key to a virtual machine (VM) and connect to the VM by running the `virtctl ssh` command, or add the `virtctl port-foward` command to your `.ssh/config` file and connect to the VM by using OpenSSH.

> [!IMPORTANT]
> The `virtctl ssh` command method is not recommended for high traffic loads because it places a burden on the API server.

You can add public SSH keys to Red Hat Enterprise Linux (RHEL) 9 VMs at runtime or at first boot to VMs with guest operating systems that can be configured by using a cloud-init data source.

> [!TIP]
> You can copy the `virtctl ssh` command in the web console by selecting **Copy SSH command** from the options ![](/openshift-docs-markdown/images/kebab.png "Options menu") menu beside a VM on the **VirtualMachines** page.
>
> Alternatively, right-click the VM in the tree view and select **Copy SSH command** from the menu to copy the `virtctl ssh` command.

## About static and dynamic SSH key management {#virt-about-static-and-dynamic-ssh-keys_virt-using-virtctl-ssh}

You can add public SSH keys to virtual machines (VMs) statically at first boot or dynamically at runtime.

> [!NOTE]
> Only Red Hat Enterprise Linux (RHEL) 9 supports dynamic key injection.

### Static SSH key management {#static-key-management_virt-using-virtctl-ssh}

You can add a statically managed SSH key to a VM with a guest operating system that supports configuration by using a cloud-init data source. The key is added to the virtual machine (VM) at first boot.

You can add the key by using one of the following methods:

- Add a key to a single VM when you create it by using the web console or the command line.
- Add a key to a project by using the web console. Afterwards, the key is automatically added to the VMs that you create in this project.

Use cases:

- As a VM owner, you can provision all your newly created VMs with a single key.

### Dynamic SSH key management {#dynamic-key-management_virt-using-virtctl-ssh}

You can enable dynamic SSH key management for a VM with Red Hat Enterprise Linux (RHEL) 9 installed. Afterwards, you can update the key during runtime. The key is added by the QEMU guest agent, which is installed with Red Hat boot sources.

When dynamic key management is disabled, the default key management setting of a VM is determined by the image used for the VM.

Use cases:

- Granting or revoking access to VMs: As a cluster administrator, you can grant or revoke remote VM access by adding or removing the keys of individual users from a `Secret` object that is applied to all VMs in a namespace.
- User access: You can add your access credentials to all VMs that you create and manage.
- Ansible provisioning:

  - As an operations team member, you can create a single secret that contains all the keys used for Ansible provisioning.
  - As a VM owner, you can create a VM and attach the keys used for Ansible provisioning.
- Key rotation:

  - As a cluster administrator, you can rotate the Ansible provisioner keys used by VMs in a namespace.
  - As a workload owner, you can rotate the key for the VMs that you manage.

## Manage static keys {#virt-static-key-management-vm_virt-using-virtctl-ssh}

You can add a statically managed public SSH key when you create a virtual machine (VM) by using the OpenShift Container Platform web console or the command line. The key is added as a cloud-init data source when the VM boots for the first time.

You can also add a public SSH key to a project when you create a VM by using the web console. The key is saved as a secret and is added automatically to all VMs that you create.

> [!NOTE]
> If you add a secret to a project and then delete the VM, the secret is retained because it is a namespace resource. You must delete the secret manually.

### Adding a key when creating a VM from a template {#virt-adding-key-creating-vm-template_static-key}

You can add a statically managed public SSH key when you create a virtual machine (VM) by using the OpenShift Container Platform web console. The key is added to the VM as a cloud-init data source at first boot. This method does not affect cloud-init user data.

Optional: You can add a key to a project. Afterwards, this key is added automatically to VMs that you create in the project.

**Prerequisites**

- You generated an SSH key pair by running the `ssh-keygen` command.

**Procedure**

1. Navigate to **Virtualization** → **Catalog** in the web console.
2. Click a template tile.

   The guest operating system must support configuration from a cloud-init data source.
3. Click **Customize VirtualMachine**.
4. Click **Next**.
5. Click the **Scripts** tab.
6. If you have not already added a public SSH key to your project, click the edit icon beside **Authorized SSH key** and select one of the following options:

   - **Use existing**: Select a secret from the secrets list.
   - **Add new**:

     1. Browse to the SSH key file or paste the file in the key field.
     2. Enter the secret name.
     3. Optional: Select **Automatically apply this key to any new VirtualMachine you create in this project**.
7. Click **Save**.
8. Click **Create VirtualMachine**.

   The **VirtualMachine details** page displays the progress of the VM creation.

**Verification**

- Click the **Scripts** tab on the **Configuration** tab.

  The secret name is displayed in the **Authorized SSH key** section.

### Creating a VM from an instance type by using the web console {#virt-creating-vm-instancetype_static-key}

You can add a statically managed SSH key when you create a virtual machine (VM) from an instance type by using the OpenShift Container Platform web console. The key is added to the VM as a cloud-init data source at first boot. This method does not affect cloud-init user data.

**Procedure**

1. In the web console, navigate to **Virtualization** → **Catalog**.

   The **InstanceTypes** tab opens by default.

   > [!NOTE]
   > When configuring a downward-metrics device on an IBM Z(R) system that uses a VM preference, set the `spec.preference.name` value to `rhel.9.s390x` or another available preference with the format `*.s390x`.
2. Heterogeneous clusters only: To filter the bootable volumes using the options provided, click **Architecture**.
3. Select either of the following options:

   - Select a suitable bootable volume from the list. If the list is truncated, click the **Show all** button to display the entire list.

     > [!NOTE]
     > The bootable volume table lists only those volumes in the `openshift-virtualization-os-images` namespace that have the `instancetype.kubevirt.io/default-preference` label.

     - Optional: Click the star icon to designate a bootable volume as a favorite. Starred bootable volumes appear first in the volume list.
   - Click **Add volume** to upload a new volume or to use an existing persistent volume claim (PVC), a volume snapshot, or a `containerDisk` volume. Click **Save**.

     Logos of operating systems that are not available in the cluster are shown at the bottom of the list. You can add a volume for the required operating system by clicking the **Add volume** link.

     In addition, there is a link to the **Create a Windows bootable volume** quick start. The same link appears in a popover if you hover the pointer over the question mark icon next to the *Select volume to boot from* line.

     Immediately after you install the environment or when the environment is disconnected, the list of volumes to boot from is empty. In that case, three operating system logos are displayed: Windows, RHEL, and Linux. You can add a new volume that meets your requirements by clicking the **Add volume** button.

   1. If you have not already added a public SSH key to your project, click the edit icon beside **Authorized SSH key** in the **VirtualMachine details** section.
   2. Select one of the following options:

      - **Use existing**: Select a secret from the secrets list.
      - **Add new**: Follow these steps:

        1. Browse to the public SSH key file or paste the file in the key field.
        2. Enter the secret name.
        3. Optional: Select **Automatically apply this key to any new VirtualMachine you create in this project**.
   3. Click **Save**.
4. Optional: If you are creating a Windows VM, you can mount a Windows driver disk:

   1. Click the **Customize VirtualMachine** button.
   2. On the **VirtualMachine details** page, click **Storage**.
   3. Select the **Mount Windows drivers disk** checkbox.
5. Optional: Click **View YAML & CLI** to view the YAML file. Click **CLI** to view the CLI commands. You can also download or copy either the YAML file contents or the CLI commands.
6. Click **Create VirtualMachine**.

**Result**

After the VM is created, you can monitor the status on the **VirtualMachine details** page.

### Adding a key when creating a VM by using the CLI {#virt-adding-public-key-vm-cli_static-key}

You can add a statically managed public SSH key when you create a virtual machine (VM) by using the command line. The key is added to the VM at first boot.

The key is added to the VM as a cloud-init data source. This method separates the access credentials from the application data in the cloud-init user data. This method does not affect cloud-init user data.

**Prerequisites**

- You generated an SSH key pair by running the `ssh-keygen` command.
- You have installed the OpenShift CLI (`oc`).

**Procedure**

1. Create a manifest file for a `VirtualMachine` object and a `Secret` object.

   Example manifest:

   ```yaml
   apiVersion: kubevirt.io/v1
   kind: VirtualMachine
   metadata:
     name: example-vm
     namespace: example-namespace
   spec:
     dataVolumeTemplates:
       - metadata:
           name: example-vm-volume
         spec:
           sourceRef:
             kind: DataSource
             name: rhel9
             namespace: openshift-virtualization-os-images
           storage:
             resources: {}
     instancetype:
       name: u1.medium
     preference:
       name: rhel.9
     runStrategy: Always
     template:
       spec:
         domain:
           devices: {}
         volumes:
           - dataVolume:
               name: example-vm-volume
             name: rootdisk
           - cloudInitNoCloud:
               userData: |-
                 #cloud-config
                 user: cloud-user
             name: cloudinitdisk
         accessCredentials:
           - sshPublicKey:
               propagationMethod:
                 noCloud: {}
               source:
                 secret:
                   secretName: authorized-keys
   ---
   apiVersion: v1
   kind: Secret
   metadata:
     name: authorized-keys
   data:
     key: c3NoLXJzYSB...
   ```

   - `spec.template.spec.volumes.cloudInitNoCloud` specifies the `cloudInitNoCloud` data source.
   - `spec.template.spec.accessCredentials.sshPublicKey.source.secret.secretName` specifies the `Secret` object name.
   - `data.key` specifies the public SSH key.
2. Create the `VirtualMachine` and `Secret` objects by running the following command:

   ```terminal
   $ oc create -f <manifest_file>.yaml
   ```
3. Start the VM by running the following command:

   ```terminal
   $ virtctl start vm example-vm -n example-namespace
   ```

**Verification**

- Get the VM configuration:

  ```terminal
  $ oc describe vm example-vm -n example-namespace
  ```

  Example output:

  ```yaml
  apiVersion: kubevirt.io/v1
  kind: VirtualMachine
  metadata:
    name: example-vm
    namespace: example-namespace
  spec:
    template:
      spec:
        accessCredentials:
          - sshPublicKey:
              propagationMethod:
                noCloud: {}
              source:
                secret:
                  secretName: authorized-keys
  # ...
  ```

## Manage dynamic keys {#virt-adding-dynamic-key-vm_static-key}

You can enable dynamic key injection for a virtual machine (VM) by using the OpenShift Container Platform web console or the command line. Then, you can update the key at runtime.

> [!NOTE]
> Only Red Hat Enterprise Linux (RHEL) 9 supports dynamic key injection.

If you disable dynamic key injection, the VM inherits the key management method of the image from which it was created.

### Enabling dynamic key injection when creating a VM from a template {#virt-adding-key-creating-vm-template_dynamic-key}

You can enable dynamic public SSH key injection when you create a virtual machine (VM) from a template by using the OpenShift Container Platform web console. Then, you can update the key at runtime.

> [!NOTE]
> Only Red Hat Enterprise Linux (RHEL) 9 supports dynamic key injection.

The key is added to the VM by the QEMU guest agent, which is installed with RHEL 9.

**Prerequisites**

- You generated an SSH key pair by running the `ssh-keygen` command.

**Procedure**

1. Navigate to **Virtualization** → **Catalog** in the web console.
2. Click the **Red Hat Enterprise Linux 9 VM** tile.
3. Click **Customize VirtualMachine**.
4. Click **Next**.
5. Click the **Scripts** tab.
6. If you have not already added a public SSH key to your project, click the edit icon beside **Authorized SSH key** and select one of the following options:

   - **Use existing**: Select a secret from the secrets list.
   - **Add new**:

     1. Browse to the SSH key file or paste the file in the key field.
     2. Enter the secret name.
     3. Optional: Select **Automatically apply this key to any new VirtualMachine you create in this project**.
7. Set **Dynamic SSH key injection** to on.
8. Click **Save**.
9. Click **Create VirtualMachine**.

   The **VirtualMachine details** page displays the progress of the VM creation.

**Verification**

- Click the **Scripts** tab on the **Configuration** tab.

  The secret name is displayed in the **Authorized SSH key** section.

### Creating a VM from an instance type by using the web console {#virt-creating-vm-instancetype_dynamic-key}

You can enable dynamic SSH key injection when you create a virtual machine (VM) from an instance type by using the OpenShift Container Platform web console. Then, you can add or revoke the key at runtime.

> [!NOTE]
> Only Red Hat Enterprise Linux (RHEL) 9 supports dynamic key injection.

The key is added to the VM by the QEMU guest agent, which is installed with RHEL 9.

**Procedure**

1. In the web console, navigate to **Virtualization** → **Catalog**.

   The **InstanceTypes** tab opens by default.

   > [!NOTE]
   > When configuring a downward-metrics device on an IBM Z(R) system that uses a VM preference, set the `spec.preference.name` value to `rhel.9.s390x` or another available preference with the format `*.s390x`.
2. Heterogeneous clusters only: To filter the bootable volumes using the options provided, click **Architecture**.
3. Select either of the following options:

   - Select a suitable bootable volume from the list. If the list is truncated, click the **Show all** button to display the entire list.

     > [!NOTE]
     > The bootable volume table lists only those volumes in the `openshift-virtualization-os-images` namespace that have the `instancetype.kubevirt.io/default-preference` label.

     - Optional: Click the star icon to designate a bootable volume as a favorite. Starred bootable volumes appear first in the volume list.
   - Click **Add volume** to upload a new volume or to use an existing persistent volume claim (PVC), a volume snapshot, or a `containerDisk` volume. Click **Save**.

     Logos of operating systems that are not available in the cluster are shown at the bottom of the list. You can add a volume for the required operating system by clicking the **Add volume** link.

     In addition, there is a link to the **Create a Windows bootable volume** quick start. The same link appears in a popover if you hover the pointer over the question mark icon next to the *Select volume to boot from* line.

     Immediately after you install the environment or when the environment is disconnected, the list of volumes to boot from is empty. In that case, three operating system logos are displayed: Windows, RHEL, and Linux. You can add a new volume that meets your requirements by clicking the **Add volume** button.
4. Click the **Red Hat Enterprise Linux 9 VM** tile.

   1. If you have not already added a public SSH key to your project, click the edit icon beside **Authorized SSH key** in the **VirtualMachine details** section.
   2. Select one of the following options:

      - **Use existing**: Select a secret from the secrets list.
      - **Add new**: Follow these steps:

        1. Browse to the public SSH key file or paste the file in the key field.
        2. Enter the secret name.
        3. Optional: Select **Automatically apply this key to any new VirtualMachine you create in this project**.
   3. Click **Save**.
5. Set **Dynamic SSH key injection** in the **VirtualMachine details** section to on.
6. Optional: If you are creating a Windows VM, you can mount a Windows driver disk:

   1. Click the **Customize VirtualMachine** button.
   2. On the **VirtualMachine details** page, click **Storage**.
   3. Select the **Mount Windows drivers disk** checkbox.
7. Optional: Click **View YAML & CLI** to view the YAML file. Click **CLI** to view the CLI commands. You can also download or copy either the YAML file contents or the CLI commands.
8. Click **Create VirtualMachine**.

**Result**

After the VM is created, you can monitor the status on the **VirtualMachine details** page.

### Enabling dynamic SSH key injection by using the web console {#virt-editing-vm-dynamic-key-injection_dynamic-key}

You can enable dynamic key injection for a virtual machine (VM) by using the OpenShift Container Platform web console. Then, you can update the public SSH key at runtime.

The key is added to the VM by the QEMU guest agent, which is installed with Red Hat Enterprise Linux (RHEL) 9 and later.

**Prerequisites**

- The guest operating system is RHEL 9 or later.

**Procedure**

1. Navigate to **Virtualization** → **VirtualMachines** in the web console.
2. Select a VM to open the **VirtualMachine details** page.
3. On the **Configuration** tab, click **Scripts**.
4. If you have not already added a public SSH key to your project, click the edit icon beside **Authorized SSH key** and select one of the following options:

   - **Use existing**: Select a secret from the secrets list.
   - **Add new**:

     1. Browse to the SSH key file or paste the file in the key field.
     2. Enter the secret name.
     3. Optional: Select **Automatically apply this key to any new VirtualMachine you create in this project**.
5. Set **Dynamic SSH key injection** to on.
6. Click **Save**.

### Enabling dynamic key injection by using the CLI {#virt-enabling-dynamic-key-injection-cli_dynamic-key}

You can enable dynamic key injection for a virtual machine (VM) by using the command line. Then, you can update the public SSH key at runtime.

> [!NOTE]
> Only Red Hat Enterprise Linux (RHEL) 9 supports dynamic key injection.

The key is added to the VM by the QEMU guest agent, which is installed automatically with RHEL 9.

**Prerequisites**

- You generated an SSH key pair by running the `ssh-keygen` command.
- You have installed the OpenShift CLI (`oc`).

**Procedure**

1. Create a manifest file for a `VirtualMachine` object and a `Secret` object.

   Example manifest:

   ```yaml
   apiVersion: kubevirt.io/v1
   kind: VirtualMachine
   metadata:
     name: example-vm
     namespace: example-namespace
   spec:
     dataVolumeTemplates:
       - metadata:
           name: example-vm-volume
         spec:
           sourceRef:
             kind: DataSource
             name: rhel9
             namespace: openshift-virtualization-os-images
           storage:
             resources: {}
     instancetype:
       name: u1.medium
     preference:
       name: rhel.9
     runStrategy: Always
     template:
       spec:
         domain:
           devices: {}
         volumes:
           - dataVolume:
               name: example-vm-volume
             name: rootdisk
           - cloudInitNoCloud:
               userData: |-
                 #cloud-config
                 runcmd:
                 - [ setsebool, -P, virt_qemu_ga_manage_ssh, on ]
             name: cloudinitdisk
         accessCredentials:
           - sshPublicKey:
               propagationMethod:
                 qemuGuestAgent:
                   users: ["cloud-user"]
               source:
                 secret:
                   secretName: authorized-keys
   ---
   apiVersion: v1
   kind: Secret
   metadata:
     name: authorized-keys
   data:
     key: c3NoLXJzYSB...
   ```

   - `spec.template.spec.volumes.cloudInitNoCloud` defines the data source, for example `userData`.
   - `spec.template.spec.accessCredentials.sshPublicKey.source.secret.secretName` defines the `secret` object name.
   - `data.key` within the `secret` object defines the full public SSH key.
2. Create the `VirtualMachine` and `Secret` objects by running the following command:

   ```terminal
   $ oc create -f <manifest_file>.yaml
   ```
3. Start the VM by running the following command:

   ```terminal
   $ virtctl start vm example-vm -n example-namespace
   ```

**Verification**

- Get the VM configuration by running the following command:

  ```terminal
  $ oc describe vm example-vm -n example-namespace
  ```

  Example output:

  ```yaml
  apiVersion: kubevirt.io/v1
  kind: VirtualMachine
  metadata:
    name: example-vm
    namespace: example-namespace
  spec:
    template:
      spec:
        accessCredentials:
          - sshPublicKey:
              propagationMethod:
                qemuGuestAgent:
                  users: ["cloud-user"]
              source:
                secret:
                  secretName: authorized-keys
  # ...
  ```

### Using the virtctl ssh command {#virt-using-virtctl-ssh-command_dynamic-key}

You can use the `virtctl ssh` command to access a running virtual machine instance (VMI). The command accepts VM or VMI targets.

**Prerequisites**

- You installed the `virtctl` command-line tool.
- You added a public SSH key to the VM.
- You have an SSH client installed.
- The environment where you installed the `virtctl` tool has the cluster permissions required to access the VM. For example, you ran `oc login` or you set the `KUBECONFIG` environment variable.

**Procedure**

1. Run the `virtctl ssh` command:

   ```terminal
   $ virtctl -n <namespace> ssh <username>@vm/<vm_name> -i <ssh_key>
   ```

   You must specify the resource type (`vmi/` or `vm/`) before the VM name.

   For example:

   ```terminal
   $ virtctl -n my-namespace ssh cloud-user@vm/example-vm -i my-key
   ```

## Using the virtctl port-forward command {#virt-using-virtctl-port-forward-command_dynamic-key}

You can use your local OpenSSH client and the `virtctl port-forward` command to connect to a running virtual machine (VM). You can use this method with Ansible to automate the configuration of VMs.

This method is recommended for low-traffic applications because port-forwarding traffic is sent over the control plane. This method is not recommended for high-traffic applications such as Rsync or Remote Desktop Protocol because it places a heavy burden on the API server.

**Prerequisites**

- You have installed the `virtctl` client.
- The virtual machine you want to access is running.
- The environment where you installed the `virtctl` tool has the cluster permissions required to access the VM. For example, you ran `oc login` or you set the `KUBECONFIG` environment variable.

**Procedure**

1. Add the following text to the `~/.ssh/config` file on your client machine:

   ```terminal
   Host vm/*
     ProxyCommand virtctl port-forward --stdio=true %h %p
   ```
2. Connect to the VM by running the following command:

   ```terminal
   $ ssh <user>@vm/<vm_name>.<namespace>
   ```
