Overview
Managing SSH keys in LXC (Linux Containers) is essential for secure, passwordless authentication. This guide covers how to export and configure SSH public keys from a host system to an LXC container, enabling secure remote access without password prompts.
LXC containers are lightweight virtualization solutions that share the host kernel while maintaining isolated user spaces. Unlike full virtual machines, containers have minimal overhead, making SSH key management a common requirement for automation and remote administration.
Prerequisites
Before proceeding, ensure the following requirements are met:
- LXC tooling installed on the host system (
lxcorlxdcommands available) - SSH server installed inside the container (
openssh-server) - Target user exists in the container with a home directory
.sshdirectory exists with proper permissions in the container
The .ssh directory must have 700 permissions, and authorized_keys file
must have 600 permissions for SSH to accept the keys.
Upload SSH Keys to a Container
Method 1: Pipe Public Key via lxc exec
The most straightforward approach uses lxc exec to pipe the public key content directly into the container's authorized_keys file:
1cat <public_key_file_on_host> | lxc exec <container> -- sh -c "cat >> /home/ubuntu/.ssh/authorized_keys"Command breakdown:
| Component | Description |
|---|---|
cat <public_key_file_on_host> | Reads the public key file on the host (e.g., ~/.ssh/id_rsa.pub) |
lxc exec <container> | Executes a command inside the specified LXC container |
-- sh -c "..." | Runs a shell command within the container namespace |
cat >> ...authorized_keys | Appends the piped content to the authorized_keys file |
Method 2: Using lxc file push
For more control over file transfers, use lxc file push to directly copy files into the container:
1# Push a single public key file2lxc file push ~/.ssh/id_rsa.pub <container>/home/ubuntu/.ssh/authorized_keys --mode=6003
4# Or append to existing keys by pulling, appending, and pushing back5lxc file pull <container>/home/ubuntu/.ssh/authorized_keys /tmp/container_keys6cat ~/.ssh/id_rsa.pub >> /tmp/container_keys7lxc file push /tmp/container_keys <container>/home/ubuntu/.ssh/authorized_keys --mode=600Method 3: Multiple Keys at Once
When deploying multiple SSH keys (e.g., for team access), combine them before transfer:
1# Combine multiple public keys into one file2cat ~/.ssh/id_rsa.pub ~/.ssh/id_ed25519.pub /path/to/team_keys.pub > /tmp/all_keys.pub3
4# Push combined keys to container5cat /tmp/all_keys.pub | lxc exec <container> -- sh -c "cat >> /home/ubuntu/.ssh/authorized_keys"Verify SSH Directory Permissions
Incorrect permissions are the most common cause of SSH key authentication failures. Verify and fix permissions inside the container:
1# Enter the container and check permissions2lxc exec <container> -- bash -c "ls -la /home/ubuntu/.ssh/"3
4# Fix permissions if needed5lxc exec <container> -- bash -c "chmod 700 /home/ubuntu/.ssh && chmod 600 /home/ubuntu/.ssh/authorized_keys && chown -R ubuntu:ubuntu /home/ubuntu/.ssh"Expected permissions:
| Path | Permission | Octal |
|---|---|---|
/home/ubuntu/.ssh | drwx------ | 700 |
/home/ubuntu/.ssh/authorized_keys | -rw------- | 600 |
Restart SSH Service
If needed
After modifying SSH configuration or adding new keys, restart the SSH daemon to ensure changes take effect:
Restart ssh on remote
1lxc exec VMName -- systemctl restart sshAlternative: Reload Without Full Restart
For minimal disruption on production containers, use reload instead of restart:
1# Reload SSH configuration without dropping existing connections2lxc exec <container> -- systemctl reload sshd3
4# Verify SSH service status5lxc exec <container> -- systemctl status sshd --no-pagerTest SSH Connection
After configuring keys, verify the connection works:
1# Get container IP address2lxc list <container> --format=csv -c 4 | cut -d' ' -f13
4# Test SSH connection (replace IP with actual address)5ssh -i ~/.ssh/id_rsa ubuntu@<container_ip> "echo 'SSH key authentication successful!'"Proxmox VE Specific: Using pct Commands
For Proxmox VE environments, the pct (Proxmox Container Toolkit) provides alternative methods for container management:
1# Enter container namespace directly2pct enter <CTID>3
4# Execute command inside container5pct exec <CTID> -- cat /home/ubuntu/.ssh/authorized_keys6
7# Push SSH keys using pct push8pct push <CTID> ~/.ssh/id_rsa.pub /home/ubuntu/.ssh/authorized_keys --perms 600The pct command is specific to Proxmox VE. For standalone LXC/LXD
installations, use the lxc commands shown in previous sections.
Cloud-Init Integration
For automated deployments, configure SSH keys during container creation using Cloud-Init:
1# Create container with SSH key via Cloud-Init (LXD)2lxc launch ubuntu:22.04 my-container --config=user.user-data="#cloud-config3ssh_authorized_keys:4 - $(cat ~/.ssh/id_rsa.pub)5users:6 - name: ubuntu7 ssh_authorized_keys:8 - $(cat ~/.ssh/id_rsa.pub)9 sudo: ALL=(ALL) NOPASSWD:ALL10 shell: /bin/bash11"For Proxmox VE with Cloud-Init enabled templates:
1# Set SSH public key for Cloud-Init VM/Container2qm set <VMID> --sshkey ~/.ssh/id_rsa.pub3
4# For containers with Cloud-Init support5pct set <CTID> --sshkeys ~/.ssh/id_rsa.pubTroubleshooting
Common Issues and Solutions
| Issue | Possible Cause | Solution |
|---|---|---|
| Permission denied (publickey) | Wrong file permissions | Run chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys inside container |
| Connection refused | SSH not running | Start SSH: lxc exec <container> -- systemctl start ssh |
| Host key verification failed | Changed container/reinstall | Remove old key: ssh-keygen -R <container_ip> |
| Key not accepted | Wrong key format | Ensure key is in OpenSSH format, not PuTTY PPK |
Debug SSH Connection
Enable verbose SSH output to diagnose connection issues:
1# Verbose SSH connection for debugging2ssh -vvv -i ~/.ssh/id_rsa ubuntu@<container_ip>3
4# Check SSH daemon logs inside container5lxc exec <container> -- journalctl -u ssh -n 50 --no-pagerVerify SELinux/AppArmor Contexts
On systems with mandatory access control, verify security contexts:
1# Check AppArmor status (Ubuntu/Debian)2lxc exec <container> -- aa-status3
4# For SELinux systems, restore contexts5lxc exec <container> -- restorecon -Rv /home/ubuntu/.ssh/Security Best Practices
- Use Ed25519 keys — Modern, secure, and faster than RSA
- Disable password authentication — Set
PasswordAuthentication noin/etc/ssh/sshd_config - Limit SSH access by user — Use
AllowUsersdirective in SSH config - Use non-root users — Avoid adding keys to the root account
- Rotate keys regularly — Remove unused keys from
authorized_keys - Enable fail2ban — Protect against brute-force attacks
1# Disable password authentication inside container2lxc exec <container> -- sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config3lxc exec <container> -- sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config4lxc exec <container> -- systemctl reload ssh