Use
The guest
What every container and VM comes with, what lives where and where your own changes belong.
Access
- Log in only as root with an SSH key, without a password. A root password only exists with the module desktop – for RDP, not for SSH.
- Without network:
pct enter <ID>(container) or the serial consoleqm terminal <ID>(VM) on the Proxmox host. - More keys: add them to
/root/.ssh/authorized_keys.
What every guest comes with
| Debian 13 | no third-party sources – unless an app needs one (Zammad, Elasticsearch), then with a key pinned in iac-core; time zone Europe/Berlin |
| Firewall | nftables: incoming only SSH and the app’s ports (some only from private networks) |
| Sandbox | the app’s services run in a systemd sandbox: only their data is writable, no needless privileges |
| Kernel | (VM) hardened sysctl values in /etc/sysctl.d/50-iac.conf, your own in 90-local.conf |
| etckeeper | every change to /etc ends up in a Git repository (git -C /etc log) |
update | one command for all updates (Update) |
| Ansible | from Debian, runs only locally and establishes the target state on install and update |
| Self-test | bash /var/lib/iac/src/core/bin/iac-smoke – the same test that runs before every image release |
Your own changes
Files that start with # managed by iac – do not edit belong to iac and are brought back to
the target state on every update. Your own changes go into the files iac provides for them:
| What | Where |
|---|---|
| Firewall rules | /etc/nftables.d/90-local.nft |
| Settings of a service | systemctl edit <service> |
| App configuration | the local file the app names (e.g. traefik.local.yaml, configuration.local.py) |
Example for an additional open port:
echo 'add rule inet iac input tcp dport 8443 accept' >> /etc/nftables.d/90-local.nft
systemctl reload nftables
What lives where
| Path | Content |
|---|---|
/etc/iac/instance.json | app, version, active modules, platform – written by iac |
/etc/iac/settings.env | settings and generated secrets of this instance (root only) |
/var/lib/iac/src/ | iac-core and the app in the installed version |
/var/log/iac/iac.log | log of every installation and every update |
When something does not work
bash /var/lib/iac/src/core/bin/iac-smoke # what runs, what does not
tail -n 100 /var/log/iac/iac.log # last run
IAC_VERBOSE=1 bash /var/lib/iac/src/core/bin/iac-install # target state again, with all details
iac-install can be repeated safely: it only establishes the target state.