Edit

Share via


Manage SSH for secure access to Azure Kubernetes Service (AKS) nodes

This article describes how to configure SSH access (preview) on your AKS clusters or node pools, during initial deployment or at a later time.

AKS supports the following configuration options to manage SSH access on cluster nodes:

  • Disabled SSH: Completely disable SSH access to cluster nodes for enhanced security
  • Entra ID based SSH: Use Microsoft Entra ID credentials for SSH authentication. Benefits of using Entra ID based SSH:
    • Centralized identity management: Use your existing Entra ID identities to access cluster nodes
    • No SSH key management: Eliminates the need to generate, distribute, and rotate SSH keys
    • Enhanced security: Leverage Entra ID security features like Conditional Access and MFA
    • Audit and compliance: Centralized logging of access events through Entra ID logs
    • Just-in-time access: Combine with Azure RBAC for granular access control
  • Local User SSH: Traditional SSH key-based authentication for node access

Important

AKS preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. AKS previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use. For more information, see the following support articles:

Important

AKS preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. AKS previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use. For more information, see the following support articles:

Prerequisites

  • This article requires version 2.61.0 or later of the Azure CLI. If you're using Azure Cloud Shell, the latest version is already installed there.

  • You need aks-preview version 9.0.0b1 or later.

    • If you don't already have the aks-preview extension, install it using the az extension add command:
      az extension add --name aks-preview
      
    • If you already have the aks-preview extension, update it to make sure you have the latest version using the az extension update command:
      az extension update --name aks-preview
      
  • Register the DisableSSHPreview feature flag using the az feature register command.

    az feature register --namespace "Microsoft.ContainerService" --name "DisableSSHPreview"
    

    It takes a few minutes for the status to show Registered.

  • Verify the registration status using the az feature show command.

    az feature show --namespace "Microsoft.ContainerService" --name "DisableSSHPreview"
    
  • When the status reflects Registered, refresh the registration of the Microsoft.ContainerService resource provider using the az provider register command.

    az provider register --namespace Microsoft.ContainerService
    
  • This article requires version 2.73.0 or later of the Azure CLI. If you're using Azure Cloud Shell, the latest version is already installed there.

  • You need aks-preview version 19.0.0b7 or later for Entra ID SSH.

    • If you don't already have the aks-preview extension, install it using the az extension add command:
      az extension add --name aks-preview
      
    • If you already have the aks-preview extension, update it to make sure you have the latest version using the az extension update command:
      az extension update --name aks-preview
      
  • Appropriate Azure RBAC permissions to access nodes:

    • Required action: Microsoft.Compute/virtualMachineScaleSets/*/read - to read Virtual Machine Scale Sets information
      • Required data action:
        • Microsoft.Compute/virtualMachineScaleSets/virtualMachines/login/action - to authenticate and log in to VMs as regular user.
        • Microsoft.Compute/virtualMachines/loginAsAdmin/action - to login with root user privileges.
      • Built-in role: Virtual Machine Administrator Login or Virtual Machine User Login (for non-admin access)
  • Register the EntraIdSSHPreview feature flag using the az feature register command.

    az feature register --namespace "Microsoft.ContainerService" --name "EntraIdSSHPreview"
    

    It takes a few minutes for the status to show Registered.

  • Verify the registration status using the az feature show command.

    az feature show --namespace "Microsoft.ContainerService" --name "EntraIdSSHPreview"
    
  • When the status reflects Registered, refresh the registration of the Microsoft.ContainerService resource provider using the az provider register command.

    az provider register --namespace Microsoft.ContainerService
    
  • This article requires version 2.61.0 or later of the Azure CLI. If you're using Azure Cloud Shell, the latest version is already installed there.
  • You need aks-preview version 9.0.0b1 or later to update SSH access method on nodepools.
    • If you don't already have the aks-preview extension, install it using the az extension add command:
      az extension add --name aks-preview
      
    • If you already have the aks-preview extension, update it to make sure you have the latest version using the az extension update command:
      az extension update --name aks-preview
      

Set environment variables

Set the following environment variables for your resource group, cluster name, and location:

export RESOURCE_GROUP="<your-resource-group-name>"
export CLUSTER_NAME="<your-cluster-name>"
export LOCATION="<your-azure-region>"

Limitations

  • Entra ID SSH to nodes is not yet available for Windows node pool.
  • Entra ID SSH to nodes is not supported for AKS automatic because of node resource group lockdown preventing role assignments.

Configure SSH access

To improve security and support your corporate security requirements or strategy, AKS supports disabling SSH both on the cluster and at the node pool level. Disable SSH introduces a simplified approach compared to configuring network security group rules on the AKS subnet/node network interface card (NIC). Disable SSH only supports Virtual Machine Scale Sets node pools.

When you disable SSH at cluster creation time, it takes effect after the cluster is created. However, when you disable SSH on an existing cluster or node pool, AKS doesn't automatically disable SSH. At any time, you can choose to perform a nodepool upgrade operation. The disable/enable SSH operation takes effect after the node image update is complete.

Note

When you disable SSH at the cluster level, it applies to all existing node pools. Any node pools created after this operation will have SSH enabled by default, and you'll need to run these commands again in order to disable it.

Note

kubectl debug node continues to work after you disable SSH because it doesn't depend on the SSH service.

Create a resource group

Create a resource group using the az group create command.

az group create --name $RESOURCE_GROUP --location $LOCATION

Disable SSH on a new cluster deployment

By default, the SSH service on AKS cluster nodes is open to all users and pods running on the cluster. You can prevent direct SSH access from any network to cluster nodes to help limit the attack vector if a container in a pod becomes compromised.

Use the az aks create command to create a new cluster, and include the --ssh-access disabled argument to disable SSH (preview) on all the node pools during cluster creation.

Important

After you disable the SSH service, you can't SSH into the cluster to perform administrative tasks or to troubleshoot.

Note

On a newly created cluster, disable SSH will only configure the first system node pool. All other node pools need to be configured at the node pool level.

az aks create --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --ssh-access disabled

After a few minutes, the command completes and returns JSON-formatted information about the cluster. The following example resembles the output and the results related to disabling SSH:

"securityProfile": {
  "sshAccess": "Disabled"
},

Disable SSH for a new node pool

Use the az aks nodepool add command to add a node pool, and include the --ssh-access disabled argument to disable SSH during node pool creation.

az aks nodepool add \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --ssh-access disabled

After a few minutes, the command completes and returns JSON-formatted information about the cluster indicating mynodepool was successfully created. The following example resembles the output and the results related to disabling SSH:

"securityProfile": {
  "sshAccess": "Disabled"
},

Disable SSH for an existing node pool

Important

AKS preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. AKS previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use. For more information, see the following support articles:

Use the az aks nodepool update command with the --ssh-access disabled argument to disable SSH (preview) on an existing node pool.

az aks nodepool update \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --ssh-access disabled

After a few minutes, the command completes and returns JSON-formatted information about the cluster indicating mynodepool was successfully updated. The following example resembles the output and the results related to disabling SSH:

"securityProfile": {
  "sshAccess": "Disabled"
},

For the change to take effect, you need to reimage the node pool by using the az aks nodepool upgrade command.

az aks nodepool upgrade \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --node-image-only

Important

To disable SSH on an existing cluster, you need to disable SSH for each node pool on this cluster.

Re-enable SSH access

To re-enable SSH access on a node pool, update the node pool with either --ssh-access localuser (for traditional SSH key-based access) or --ssh-access entraid (for Entra ID based access). See the respective sections for detailed instructions.

You can configure your AKS cluster to use Microsoft Entra ID (formerly Azure AD) for SSH authentication to cluster nodes. This eliminates the need to manage SSH keys and allows you to use your Entra ID credentials to access nodes securely.

Create a resource group

Create a resource group using the az group create command.

az group create --name $RESOURCE_GROUP --location $LOCATION

Enable Entra ID based SSH on a new cluster

Use the az aks create command with the --ssh-access entraid argument to enable Entra ID based SSH authentication during cluster creation.

az aks create \
    --resource-group $RESOURCE_GROUP \
    --name $CLUSTER_NAME \
    --ssh-access entraid

After a few minutes, the command completes and returns JSON-formatted information about the cluster. The following example resembles the output:

"securityProfile": {
  "sshAccess": "EntraID"
},

Enable Entra ID based SSH for a new node pool

Use the az aks nodepool add command with the --ssh-access entraid argument to enable Entra ID based SSH during node pool creation.

az aks nodepool add \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --ssh-access entraid

After a few minutes, the command completes and returns JSON-formatted information indicating mynodepool was successfully created with Entra ID based SSH. The following example resembles the output:

"securityProfile": {
  "sshAccess": "EntraID"
},

Enable Entra ID based SSH for an existing node pool

Use the az aks nodepool update command with the --ssh-access entraid argument to enable Entra ID based SSH on an existing node pool.

az aks nodepool update \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --ssh-access entraid

After a few minutes, the command completes and returns JSON-formatted information indicating mynodepool was successfully updated with Entra ID based SSH. The following example resembles the output:

"securityProfile": {
  "sshAccess": "EntraID"
},

For the change to take effect, you need to reimage the node pool by using the az aks nodepool upgrade command.

az aks nodepool upgrade \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --node-image-only

Important

To enable Entra ID based SSH on an existing cluster, you need to enable it for each node pool individually.

Local user SSH access uses traditional SSH key-based authentication. This is the default SSH access method for AKS clusters.

Create a resource group

Create a resource group using the az group create command.

az group create --name $RESOURCE_GROUP --location $LOCATION

Create an AKS cluster with SSH keys

Use the az aks create command to deploy an AKS cluster with an SSH public key. You can either specify the key or a key file using the --ssh-key-value argument, or use --ssh-access localuser to explicitly set local user SSH access.

SSH parameter Description Default value
--generate-ssh-key If you don't have your own SSH keys, specify --generate-ssh-key. The Azure CLI automatically generates a set of SSH keys and saves them in the default directory ~/.ssh/.
--ssh-key-value Public key path or key contents to install on node VMs for SSH access. For example, ssh-rsa AAAAB...snip...UcyupgH azureuser@linuxvm. ~/.ssh/id_rsa.pub
--ssh-access localuser Explicitly enable local user SSH access with key-based authentication.
--no-ssh-key If you don't require SSH keys, specify this argument. However, AKS automatically generates a set of SSH keys because the Azure Virtual Machine resource dependency doesn't support an empty SSH keys file. As a result, the keys aren't returned and can't be used to SSH into the node VMs. The private key is discarded and not saved.

Note

If no parameters are specified, the Azure CLI defaults to referencing the SSH keys stored in the ~/.ssh/id_rsa.pub file. If the keys aren't found, the command returns the message An RSA key file or key value must be supplied to SSH Key Value.

Examples:

  • To create a cluster and use the default generated SSH keys:

    az aks create --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --generate-ssh-key
    
  • To specify an SSH public key file:

    az aks create --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --ssh-key-value ~/.ssh/id_rsa.pub
    
  • To explicitly enable local user SSH access:

    az aks create --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --ssh-access localuser --generate-ssh-key
    

Enable local user SSH for a new node pool

Use the az aks nodepool add command with the --ssh-access localuser argument to enable local user SSH during node pool creation.

az aks nodepool add \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --ssh-access localuser

Enable local user SSH for an existing node pool

Important

AKS preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. AKS previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use. For more information, see the following support articles:

Use the az aks nodepool update command with the --ssh-access localuser argument to enable local user SSH on an existing node pool.

az aks nodepool update \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --ssh-access localuser

Important

For the change to take effect, you need to reimage the node pool by using the az aks nodepool upgrade command.

az aks nodepool upgrade \
    --cluster-name $CLUSTER_NAME \
    --name mynodepool \
    --resource-group $RESOURCE_GROUP \
    --node-image-only

Update SSH public key on an existing AKS cluster

Use the az aks update command to update the SSH public key (preview) on your cluster. This operation updates the key on all node pools. You can either specify a key or a key file using the --ssh-key-value argument.

Note

Updating the SSH keys is supported on Azure virtual machine scale sets with AKS clusters.

Examples:

  • To specify a new SSH public key value:

    az aks update --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --ssh-key-value 'ssh-rsa AAAAB3Nza-xxx'
    
  • To specify an SSH public key file:

    az aks update --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --ssh-key-value ~/.ssh/id_rsa.pub
    

Important

After you update the SSH key, AKS doesn't automatically update your node pool. At any time, you can choose to perform a nodepool upgrade operation. The update SSH keys operation takes effect after a node image update is complete. For clusters with Node Auto-provisioning enabled, a node image update can be performed by applying a new label to the Kubernetes NodePool custom resource.

Verify SSH service status

After disabling SSH, you can verify that the SSH service is inactive on your cluster nodes.

Use the Virtual Machine Scale Set az vmss run-command invoke command to check SSH service status.

az vmss run-command invoke --resource-group <node-resource-group> --name <vmss-name> --command-id RunShellScript --instance-id 0 --scripts "systemctl status ssh"

The following sample output shows the expected result when SSH is disabled:

{
  "value": [
    {
      "code": "ProvisioningState/succeeded",
      "displayStatus": "Provisioning succeeded",
      "level": "Info",
      "message": "Enable succeeded: \n[stdout]\n○ ssh.service - OpenBSD Secure Shell server\n     Loaded: loaded (/lib/systemd/system/ssh.service; disabled; vendor preset: enabled)\n     Active: inactive (dead) since Wed 2024-01-03 15:36:53 UTC; 25min ago\n..."
    }
  ]
}

Search for the word Active and verify that its value is Active: inactive (dead), which confirms SSH is disabled on the node.

After enabling Entra ID based SSH, you can verify that the SSH service is active and configured for Entra ID authentication on your cluster nodes.

Use the Virtual Machine Scale Set az vmss run-command invoke command to check SSH service status.

az vmss run-command invoke --resource-group <node-resource-group> --name <vmss-name> --command-id RunShellScript --instance-id 0 --scripts "systemctl status ssh"

The following sample output shows the expected result when SSH is enabled:

{
  "value": [
    {
      "code": "ProvisioningState/succeeded",
      "displayStatus": "Provisioning succeeded",
      "level": "Info",
      "message": "Enable succeeded: \n[stdout]\n● ssh.service - OpenBSD Secure Shell server\n     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)\n     Active: active (running) since Wed 2024-01-03 15:40:20 UTC; 19min ago\n..."
    }
  ]
}

Search for the word Active and verify that its value is Active: active (running), which confirms SSH is enabled on the node.

After configuring local user SSH, you can verify that the SSH service is active on your cluster nodes.

Use the Virtual Machine Scale Set az vmss run-command invoke command to check SSH service status.

az vmss run-command invoke --resource-group <node-resource-group> --name <vmss-name> --command-id RunShellScript --instance-id 0 --scripts "systemctl status ssh"

The following sample output shows the expected result when SSH is enabled:

{
  "value": [
    {
      "code": "ProvisioningState/succeeded",
      "displayStatus": "Provisioning succeeded",
      "level": "Info",
      "message": "Enable succeeded: \n[stdout]\n● ssh.service - OpenBSD Secure Shell server\n     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)\n     Active: active (running) since Wed 2024-01-03 15:40:20 UTC; 19min ago\n..."
    }
  ]
}

Search for the word Active and verify that its value is Active: active (running), which confirms SSH is enabled on the node.

Next steps

To help troubleshoot any issues with SSH connectivity to your clusters nodes, you can view the kubelet logs or view the Kubernetes master node logs.