β (beta)
ssh2incus
provides a full-featured SSH server that connects directly to
Incus containers and virtual machines. It runs on the Incus host
and intelligently routes incoming SSH connections to the appropriate instances using the Incus API, eliminating the
need to run SSH servers inside the instances.
-
Authentication: Uses existing host ssh keys by default or, additionally, ssh keys inside instances (
--inauth
) -
No-Auth Mode: Optional authentication-free mode for local and development environments (
--noauth
) -
Multiple Remotes: Connect to any remote from
incus remote list
-
Terminal Support: Full PTY (terminal) mode and remote command execution
-
File Transfer: Complete SCP and SFTP support with integrated SFTP server
-
Port Forwarding:
- Local forwarding (
ssh -L
) - Reverse forwarding (
ssh -R
) - Dynamic forwarding (
ssh -D
)
- Local forwarding (
-
SSH Agent Forwarding: Seamlessly forward your SSH agent into instance sessions
-
Process Models:
- Master process mode: Maintains SSH connections after service restart
- Daemon mode: Single process with multiple threads for resource-constrained systems
-
Incus Shell: Manage Incus over SSH
-
Compatibility:
- Built using Incus 6.x API
- Works with Incus inside Lima and Colima
- Tested with Jetbrains Gateway, VSCode, Cursor and other IDEs
- Full Ansible support
- Advanced authentication options (SSH keys, passwords, JWT, OpenID, OAuth 2.0, LDAP, etc.)
- Web browser-based terminal access to instance shells
- 24/7 technical support with prioritized feature development
Download the latest package from the Releases page and install:
apt-get install -f ./ssh2incus_0.6-0_amd64.deb
yum install ./ssh2incus-0.6-0.x86_64.rpm
Start and enable the service:
systemctl enable ssh2incus.service
systemctl start ssh2incus.service
Monitor logs:
journalctl -f -u ssh2incus.service
To establish an SSH connection to an instance running on Incus host, run:
ssh -p 2222 [remote:][instance-user@]instance-name[.project-name][+host-user]@incus-host
Where:
instance-name
: Name of a running instance (required)remote
: Remote name fromincus remote list
(optional, defaults to either current remote or remote set via-r
flag)instance-user
: User in the Incus instance (optional, defaults toroot
)project-name
: Incus project name (optional, defaults todefault
)host-user
: User on the Incus host (optional, defaults toroot
)incus-host
: Hostname or IP address of the Incus host wheressh2incus
is running (required)
Connect to instance ubuntu
as root
:
ssh -p 2222 [email protected]
Connect to instance ubuntu
as root using admin
on the host:
ssh -p 2222 [email protected]
Connect to instance ubuntu
as user ubuntu
using host user admin
:
ssh -p 2222 ubuntu@[email protected]
Connect to instance ubuntu
in project1
as user ubuntu
:
ssh -p 2222 [email protected]@1.2.3.4
Connect to instance ubuntu
in project1
on remote incus-prod
as user ubuntu
:
ssh -p 2222 incus-prod:[email protected]@1.2.3.4
Enable SSH agent forwarding to use your local SSH keys inside the instance:
- Start SSH agent locally:
eval `ssh-agent`
- Connect with agent forwarding:
ssh -A -p 2222 [email protected]
ssh2incus
automatically creates a proxy socket device in the instance and removes it when the connection closes.
Forward local port 8080 to port 80 on the instance:
To forward local port 8080
listening on 127.0.0.1
to port 80
on ubuntu
instance, run:
ssh -L 127.0.0.1:8080::80 -p 2222 [email protected]
Forward remote port 3000 on the instance to local port 8080 on your machine:
ssh -R 127.0.0.1:3000:127.0.0.1:8080 -p 2222 [email protected]
Dynamic port forwarding sets up a SOCKS5 proxy server through your SSH connection, allowing applications to route traffic through it regardless of destination port:
ssh -D 1080 -p 2222 [email protected]
You can access Incus instances through the Incus host acting as an SSH proxy or bastion.
Configure this in your ~/.ssh/config
:
Host incus1
Hostname localhost
Port 2222
ProxyJump incus-host
Host incus-host
Hostname 1.2.3.4
User root
Now connect to the ubuntu
instance as root
with:
ssh ubuntu@incus1
Security Note: Using this method provides additional security benefits since port 2222 is not exposed to the public internet.
ssh2incus
offers two operating modes to suit different environments and requirements:
Master process mode employs a primary process that spawns child processes for handling connections. This architecture provides:
- High Availability: SSH connections remain active even if the
ssh2incus
service is restarted - Fault Isolation: Issues with one connection don't affect others
- Resource Management: Better utilization of system resources for handling many concurrent connections
- Seamless Updates: Update the
ssh2incus
service without disrupting active sessions
This is the recommended mode for production environments or systems with sufficient resources.
Daemon mode runs as a single process with multiple threads, designed for:
- Low Memory Usage: Significantly reduced memory footprint
- Simple Architecture: Single-process design for embedded or resource-constrained systems
- Lighter Load: Better performance on systems with very limited resources
To enable daemon mode, modify /etc/default/ssh2incus
: remove -m
from ARGS=
.
Note: In daemon mode, all active connections will be terminated if the
ssh2incus
service is restarted.
The %shell
command provides direct access to the Incus command line interface from an SSH session,
allowing you to manage your Incus instances without needing to log into the host directly.
Only root is allowed to connect to Incus shell.
This feature is especially useful for:
- Quick management tasks without direct host access
- Systems administration from remote locations
To access the Incus shell, connect using:
ssh -p 2222 %shell@incus-host
- Interactive Incus command execution
- Ctrl+C to exit the shell cleanly
$ ssh %shell@incus-colima
incus shell emulator on colima-incus (Ctrl+C to exit)
Hit Enter or type 'help <command>' for help about any command
Type incus command:
> incus version
Client version: 6.11
Server version: 6.11
Type incus command:
> incus
ssh2incus
fully supports Ansible automation for container management, making it simple to orchestrate your
Incus instance configuration.
Create an ansible.cfg
file with optimized settings for Incus instances:
[defaults]
host_key_checking = False
remote_tmp = /tmp/.ansible-${USER}
Connect directly to ssh2incus
on port 2222:
[incus1]
# Basic instance connection
instance-a ansible_user=c1 ansible_host=1.2.3.4 ansible_port=2222
# Connection with privilege escalation
instance-b ansible_user=u1@ubuntu ansible_host=1.2.3.4 ansible_port=2222 become=yes
Use SSH configuration for a cleaner approach (requires ProxyJump configuration in ~/.ssh/config
):
[incus2]
# Basic instance connection
instance-c ansible_user=c1 ansible_host=incus1
# Connection with privilege escalation
instance-d ansible_user=u1@ubuntu ansible_host=incus1 become=yes
---
- hosts: incus1,incus2
become: no
become_method: sudo
tasks:
- command: env
- command: ip addr
By default, ssh2incus
:
- Listens on port
2222
- Permits authentication for
root
and members of theincus
,incus-admin
groups
To grant a user access permission:
sudo usermod -aG incus your-host-user
Modify ssh2incus
behavior by editing /etc/default/ssh2incus
. Add configuration flags to the ARGS=
line.
-b, --banner show banner on login
-c, --client-cert string client certificate for remote
-k, --client-key string client key for remote
-d, --debug enable debug log
-g, --groups string list of groups members of which allowed to connect (default "incus,incus-admin")
--healthcheck string enable Incus health check every X minutes, e.g. "5m"
-h, --help print help
--inauth enable authentication using instance keys
-l, --listen string listen on ":port" or "host:port" (default ":2222")
-m, --master start master process and spawn workers
--noauth disable SSH authentication completely
--pprof enable pprof
--pprof-listen string pprof listen on ":port" or "host:port" (default ":6060")
-r, --remote string default Incus remote to use
-t, --server-cert string server certificate for remote
--shell string shell access command: login, su, sush or user shell
-s, --socket string Incus socket to connect to (optional, defaults to INCUS_SOCKET env)
-u, --url string Incus remote url to connect to (should start with https://)
-v, --version print version
-w, --welcome show welcome message to users connecting to shell
To enable debug logging and restrict listening to localhost:
ARGS=-d -l 127.0.0.1:2222
Enable the optional welcome banner with the -b
flag:
┌──────────────────────────────────────────────┐
│ _ ____ _ │
│ ___ ___| |__ |___ \(_)_ __ ___ _ _ ___ │
│ / __/ __| '_ \ __) | | '_ \ / __| | | / __| │
│ \__ \__ \ | | |/ __/| | | | | (__| |_| \__ \ │
│ |___/___/_| |_|_____|_|_| |_|\___|\__,_|___/ │
└──────────────────────────────────────────────┘
👤 root 📦 a9.default 💻 colima-incus
────────────────────────────────────────────────
The banner provides useful context showing:
- Current user (👤)
- Container/VM name and project (📦)
- Remote / host system name (💻)
Since ssh2incus
listens on port 2222
by default, you'll need to configure your firewall to allow incoming connections on this port.
# Allow SSH access on port 2222
sudo ufw allow 2222/tcp
# Apply changes
sudo ufw reload
# Verify the rule was added
sudo ufw status
# Allow SSH access on port 2222
sudo firewall-cmd --permanent --add-port=2222/tcp
# Apply changes
sudo firewall-cmd --reload
# Verify the rule was added
sudo firewall-cmd --list-ports
sudo iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
sudo iptables-save > /etc/iptables/rules.v4 # Make changes persistent
sudo nft add rule inet filter input tcp dport 2222 accept
sudo nft list ruleset > /etc/nftables.conf # Make changes persistent
For production environments, consider these firewall best practices:
- Restrict Access: Limit access to port 2222 to specific IP addresses or networks
- Use SSH Bastion: Consider exposing
ssh2incus
only to your management network - Rate Limiting: Implement connection rate limiting to prevent brute force attacks
Get help from the community and developers:
- GitHub Issues: Report bugs, request features, or ask questions through the GitHub repository
- Documentation: Refer to the online documentation for detailed guides and tutorials
For organizations requiring guaranteed response times and dedicated assistance:
- Technical Support: 24/7 access to technical support engineers
- Priority Bug Fixes: Expedited resolution of critical issues
- Feature Development: Priority implementation of custom requirements
- Consulting Services: Implementation guidance and best practices
If you encounter issues with ssh2incus
:
- Check logs:
journalctl -u ssh2incus.service
- Verify service status:
systemctl status ssh2incus.service
- Test connectivity:
telnet incus-host 2222
- Enable debug mode: Set
-d
flag in/etc/default/ssh2incus
- Check permissions: Ensure your host user belongs to the proper groups (
incus
orincus-admin
)