Skip to content

Latest commit

 

History

History
178 lines (133 loc) · 5.12 KB

Ubuntu.md

File metadata and controls

178 lines (133 loc) · 5.12 KB

Ubuntu Server

Setting up rootless podman on a fresh Ubuntu 24.10 server.

Warning

Perform sudo apt update && sudo apt upgrade immediately. Reboot system.

SSH

SSH is optional, but highly encouraged. OpenSSH is installed by default and sshd is running by default.

## Generate strong key on your laptop or workstation/desktop
## If you already have keys DO NOT overwrite your previous keys

ssh-keygen -t ed25519 -a 32 -f ~/.ssh/$localhost-to-$remotehost

## Optionally set a passphrase

## Copy key to Ubuntu
ssh-copy-id username@remote_host

Override sshd config

We don't want to allow anyone to login as root remotely ever. You must be a sudoer with public key auth to elevate to root.

SSH into your server and run

printf '%s\n' 'PermitRootLogin no' | sudo tee /etc/ssh/sshd_config.d/01-root.conf
printf '%s\n' \
    'PubkeyAuthentication yes' \
    'PasswordAuthentication no' | sudo tee /etc/ssh/sshd_config.d/01-pubkey.conf

Save file and then run systemctl restart ssh Before closing your session, open a new terminal and test SSH is functioning correctly.

Podman

Podman is a daemonless container hypervisor. This document prepares a fully rootless environment for our containers to run in.

Install

sudo apt install podman systemd-container

## Make sure podman is running
systemctl enable --now podman

Note

Read the docs. man podman-systemd.unit

Prepare host networking stack

Pasta or slirp4netns

Note

As of Podman 5.0 Pasta is the default rootless networking tool.

Podman 5.0 is available in standard Ubuntu repo since 24.10.

Both are installed with podman see rootless networking for configuration

Allow rootless binding port 80+

Modify range of unprivileged ports

Note

This is only necessary if you are setting up the reverse proxy (or any service on ports <1024).

printf '%s\n' 'net.ipv4.ip_unprivileged_port_start=80' | sudo tee /etc/sysctl.d/99-unprivileged-port-binding.conf
sysctl -w 'net.ipv4.ip_unprivileged_port_start=80'

Prepare container user

This user will be the owner of all containers with no login shell or root privileges.

Container user should have range of uid/gid automatically generated. See subuid and subgid tutorial to verify range or create if it does not exist.

Note $ctuser is a placeholder, replace with your username

# Prepare a group id outside of the normal range
sudo groupadd --gid 2000 $ctuser
# Create user with restrictions
# We need the $HOME to live in
sudo useradd --create-home \
    --shell /usr/bin/false \
    --password $ctuser_pw \
    --no-user-group \
    --gid $ctuser \
    --groups systemd-journal \
    --uid 2000 \
    $ctuser
# Lock user from password login
sudo usermod --lock $ctuser
# Start $ctuser session at boot without login
loginctl enable-linger $ctuser

Note

Consider removing bash history entry that contains the password entered above

Setup $ctuser env

Note

Use machinectl instead of sudo or su to get a shell that is fully isolated from the original session. See the developers comments on the problem with su as well as the purpose of machinectl shell

# Switch to $ctuser
# Note do not remove the trailing @
machinectl shell $ctuser@ /bin/bash
# Create dirs
mkdir -p ~/.config/{containers/systemd,environment.d}
# Prepare `systemd --user` env
echo 'XDG_RUNTIME_DIR=/run/user/2000' >> ~/.config/environment.d/10-xdg.conf
# Enable container auto-update
podman system migrate
# WARNING: Set strict versions for all containers or risk catastrophe
systemctl --user enable --now podman-auto-update
exit

Podman fails autostart

In Podman < 5.3 containers may fail to autostart because user level units cannot depend on system level units (in this case network-online.target)

Podman >= 5.3 should ship with a workaround user unit that can be used podman-user-wait-network-online.service, use that instead of the fix below.

See this github issue for workarounds, the workaround below is what worked for me. The google.com ping can be replaced with your preferred (reachable) ip/host

To fix this, create the following

# ~/.config/systemd/user/network-online.service
[Unit]
Description=User-level proxy to system-level network-online.target

[Service]
Type=oneshot
ExecStart=sh -c 'until ping -c 1 google.com; do sleep 5; done'

[Install]
WantedBy=default.target
# ~/.config/systemd/user/network-online.target
[Unit]
Description=User-level network-online.target
Requires=network-online.service
Wants=network-online.service
After=network-online.service

Then enable the service systemctl --user enable network-online.service

In quadlets add the following:

[Unit]
After=network-online.target