Sshd_config mising from ubuntu 22 image?

The image downloaded from remote images (https://images.linuxcontainers.org) do not have sshd_config under /etc/ssh. Any specific reason to remove it?

root@incus-node2:~#incus config show main-master --expanded | grep image.description
  image.description: Ubuntu jammy amd64 (20240828_07:42)
root@incus-node2:~#incus image list
+-------+--------------+--------+-------------------------------------+--------------+-----------+-----------+----------------------+
| ALIAS | FINGERPRINT  | PUBLIC |             DESCRIPTION             | ARCHITECTURE |   TYPE    |   SIZE    |     UPLOAD DATE      |
+-------+--------------+--------+-------------------------------------+--------------+-----------+-----------+----------------------+
| uc22  | 25547c3bc70c | no     | Ubuntu jammy amd64 (20240828_07:42) | x86_64       | CONTAINER | 123.22MiB | 2024/08/28 18:57 UTC |
+-------+--------------+--------+-------------------------------------+--------------+-----------+-----------+----------------------+

root@incus-node2:~#incus exec main-master – bash -c “ls -l /etc/ssh/”
total 4
-rw-r–r-- 1 root root 1650 Jun 26 13:11 ssh_config
drwxr-xr-x 1 root root 0 Jun 26 13:11 ssh_config.d

While Checking same on lxd (with ubuntu remote repo) I could see the entire contents of /etc/ssh directory there including sshd_config file.

lxc exec ssh-test – bash -c “ls -l /etc/ssh/ | grep -w ‘sshd_config’”
-rw-r–r-- 1 root root 3254 Jun 26 13:11 sshd_config
drwxr-xr-x 2 root root 3 Aug 21 02:14 sshd_config.d

I guess I can’t use the ubuntu image repo as remote repo with incus. Even after adding it its now displaying any images there.

Is this the only method to get ubuntu 22 cloud image now?

I have specific use case where these machine continers using sshpass gets some scripts form each other. Thats why sshd_config is needed on each one

Regarding sshd_config: it’s missing because the openssh-server package isn’t installed. Just install that package if you need it.

Is this the only method to get ubuntu 22 cloud image now?

No, you can simply do:

incus launch images:ubuntu/22.04/cloud foobar

This confirms that openssh-server isn’t included by default:

# incus exec foobar -- dpkg-query -l | grep openssh
ii  openssh-client               1:8.9p1-3ubuntu0.10                     amd64        secure shell (SSH) client, for secure access to remote machines
# 
1 Like

You can build you own images, but I recommend using cloud init to install the package when you first launch the instance. You can add the configuration to your default profile.

1 Like

To give a concrete example, you can just paste this (multiline) command:

incus launch images:ubuntu/22.04/cloud foobar -c user.user-data="#cloud-config
disable_root: false
users: []
ssh_authorized_keys:
  - ssh-rsa etcetcetc
packages:
  - openssh-server
"

For a scripted build, if you want to wait until cloud-init has completed its job, it’s a bit trickier. I use this function:

incus-wait-cloud-init() {
  vm="$1"

  for i in {1..60}; do
    incus exec "$vm" -- systemctl is-active cloud-init && incus exec "$vm" -- cat /run/cloud-init/result.json && return
    sleep 1
  done
  echo "Timed out waiting for cloud-init to complete"
  exit 1
}
1 Like

The images at https://images.linuxcontainers.org/ are quite lean, which means that they do not have openssh-server, neither curl, nor wget, etc.

The exact wording though, is that these images do not include by default those packages and in fact any packages that are not universally required. This is quite important when you launch hundreds of instances. Every bit of unneeded packages will add up, and take space and memory.

As already mentioned, you can setup your system with the appropriate profile so that any instance that you create, will install upon creation, the packages of your liking.

Create an Incus profile called, for example, addpackages and add the following.

$ incus profile create addpackages
Profile addpackages created
$ incus profile edit addpackages
...
$ incus profile show addpackages
config:
  cloud-init.user-data: |
    #cloud-config
    package_update: true
    package_upgrade: true
    package_reboot_if_required: true
    packages:
      - openssh-server
description: Install extra packages
devices: {}
name: addpackages
used_by:
project: default
$ 

Then, launch a container with that added profile. We must include the default profile as well, along with the additional profile. Note that you can add the instructions of the additional profile to your default profile so that all your instances will get those packages installed upon creation (of each instance).

$ incus launch images:debian/12/cloud mycontainer --profile default --profile addpackages
$ incus shell mycontainer
root@mycontainer:~# apt policy openssh-server
openssh-server:
  Installed: 1:9.2p1-2+deb12u3
  Candidate: 1:9.2p1-2+deb12u3
  Version table:
 *** 1:9.2p1-2+deb12u3 500
        500 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages
        100 /var/lib/dpkg/status
     1:9.2p1-2+deb12u2 500
        500 http://deb.debian.org/debian bookworm/main amd64 Packages
root@mycontainer:~# logout
1 Like

Hi, I tried adding these lines to already existing profile. Launced instance with that. but the openssh-server package is not gettign installed.

root@incus-node2:~#incus profile show k8s
config:
  cloud-init.user-data: |
    #cloud-config
    package_update: true
    package_upgrade: true
    package_reboot_if_required: true
    packages:
      - openssh-server
  limits.cpu: "4"
  limits.memory: 4GB
  limits.memory.swap: "false"
  linux.kernel_modules: ip_tables,ip6_tables,nf_nat,overlay,br_netfilter
  raw.lxc: "lxc.apparmor.profile=unconfined\nlxc.cap.drop= \nlxc.cgroup.devices.allow=a\nlxc.mount.auto=proc:rw
    sys:rw"
  security.nesting: "true"
  security.privileged: "true"
description: LXD profile for Kubernetes

Other parameters in config like cpu, ram etc are getting applied correctly.

root@incus-node2:~#incus launch images:ubuntu/22.04 main-master --profile k8s

root@incus-node2:~#incus exec main-master -- dpkg-query -l | grep openssh
ii  openssh-client              1:8.9p1-3ubuntu0.10                     amd64        secure shell (SSH) client, for secure access to remote machines

You can debug what went wrong, by looking into the instance at /var/log/cloud-init*log.

In your case, the image should be images:ubuntu/22.04/cloud. Because without that /cloud part, the image does not have support for cloud-init.

incus exec my-container -- cloud-init status --wait

That is how I generally wait for cloud init. It will also show you if there was an error.

Thank you. I had tried systemctl is-system-running --wait which didn’t do the job. Your version works fine.

Hi All,

How would I include a simple script to run each time of launch via cloud-init in default profile.

Below in script. I tried to use runcmd way…but ended up having syntax errors in yaml for profile.

cat >> ~/.bashrc << EOF
if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi

For package I could use packages and it works fine.

There are two parts here.

The first part is to get the bash-completion package to get installed upon creation of the instance. I think this is covered in the earlier example above. Ask if you want an example for that.

The second part is how to get a shell into the instance so that the shell will make use of the bash-completion. If that package is installed, then a login shell will automatically get the bash-completion enabled. Which means that you probably do not need something extra to configure.

Let’s see. We launch an instance, then get a login shell (incus shell is su -l, therefore a login shell which loads up all config files). Without bash-completion, when we cd .<TAB>, it shows both files and directories. That’s wrong; you cannot cd into a file. We then install the package, logout and log in again, and now completion works. cd .<TAB> shows only the .ssh/ directory, which is the outcome of bash-completion working fine.

$ incus launch images:debian/12/cloud myinstance
Launching myinstance
$ incus shell myinstance
root@myinstance:~# cd .<TAB>
./        ../       .bashrc   .profile  .ssh/     
root@myinstance:~# touch one two
root@myinstance:~# cd 
.bashrc   one       .profile  .ssh/     two       
root@myinstance:~# apt install bash-completion
...
root@myinstance:~# logout
$ incus shell myinstance
root@myinstance:~# cd .<TAB>
root@myinstance:~# cd .ssh/
root@myinstance:~/.ssh# logout
$

Double tab is not only helpful for around navigation, but suggestions like package name etc.

e.g. Try below on brand new incus container or VM

apt policy zfs <>

on ubuntu/OS is suggests all available packages starting with zfs name. It won’t work here.

Now install bash-complition and the small script I posted in my previous post.

After ths run again

apt policy zfs <>

This time it will show you packages available. Makes things easier.

I used the double-tab as an example to demonstrate whether completion is loaded or not. Another way is to run complete (as a command) and see whether there are rules loaded. I think that demonstrating visual with double-tab was a good choice.
Indeed, there are many other facilities that are provided with the shell completion that not so many users are aware of them.

Note that among all programs that provide configuration for Bash completion, Incus is one of them. The completion rules can be found at /usr/share/bash-completion/completions/ and a program just needs to put in there their own completion rules.

Here are the Incus rules, /usr/share/bash-completion/completions/incus.