TL;DR: Ubuntu vanilla LXC container template comes with ubuntu sudoer with an empty password and ssh allowed. You need to take care of that 😀
Ok, relatively recently I've realized (in a HARD way) that when LXC containers create an ubuntu user with sudoer privileges and an EMPTY password. And uhm,they're also allowed to accept SSH connections (kudos Ubuntu team!)
I think the Ubuntu Gremlins came up with this brilliant idea for AWS and Azure, but they definitely didn't have you in mind.
So, if you're a solopreneur or a small company "IT section" that doesn't have a whole DevOps team full of people smarter than you - and you like to fiddle with Linux Containers (for fun and profit) - you should probably read further, unless you enjoy mining bitcoins for script kiddies in China. If you do - you do you, I'm not judging. (Okay, maybe I'm judging a little, try finding better hobbies, I would recommend hiking.)
Run this inside the container, after you finish whatever you wanted to do, of course:
# Disable SSH password authentication entirely
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config
systemctl restart ssh
# And delete the default ubuntu user for good measure
deluser --remove-home ubuntu 2>/dev/null || true
That closes the door for password logins entirely, including the creepy invisible guest account named ubuntu
.
But if you want a permanent fix, and not something you'll forget until the next container launch, you can nuke the default user creation at the source, cloud-init.
Here's the sequence of commands to make your LXC template behave like a proper adult.
Run this inside your base container (for example, name it something like ubuntu-base
, pinky-piggletoon
to keep it with the Ubuntu-naming):
lxc exec ubuntu-base -- bash
mkdir -p /etc/cloud/cloud.cfg.d
tee /etc/cloud/cloud.cfg.d/99-disable-ubuntu.cfg >/dev/null <<'EOF'
# Disable default ubuntu user creation
users:
- default
disable_root: true
ssh_pwauth: false
system_info:
default_user:
name: root
lock_passwd: true
EOF
touch /etc/cloud/cloud-init.disabled
systemctl disable cloud-init
systemctl stop cloud-init
deluser --remove-home ubuntu 2>/dev/null || true
exit
That's it. Now every new container cloned from ubuntu-base
will start without the ubuntu
user, and SSH password login will be disabled by default.
You can even check:
lxc exec test-clean -- bash -c "grep ubuntu /etc/shadow || echo '✅ clean clone, no ubuntu user created'"