5 Commits

Author SHA1 Message Date
librelad
4063283db1 feat(rootless): proper AppArmor profile for pasta network driver
The Debian-shipped passt AppArmor profile (/etc/apparmor.d/usr.bin.passt)
denies the accesses pasta needs to plumb rootlesskit's netns:
  - ptrace_read on the rootlesskit child to enter its user namespace
  - read /run/user/<uid>/dockerd-rootless/netns (the netns file)
  - read /proc/<pid>/net/{tcp,tcp6,udp,udp6} for implicit port forwarding

Without these the rootless docker daemon fails with:
  pasta failed with exit code 1:
  Couldn't open user namespace /proc/<pid>/ns/user: Permission denied

scripts/docker/install/rootless/rootless_apparmor.sh:
  New installRootlessApparmorForPasta() — idempotent fixup.
  1. Adds `include if exists <local/usr.bin.passt>` to the main profile
     (one line; re-adding is a no-op via grep).
  2. Writes /etc/apparmor.d/local/usr.bin.passt with the four rules
     pasta needs. The /local/ pattern is the standard Debian AppArmor
     hook for site-managed overrides — survives `apt upgrade passt`
     because it's outside the package's managed paths.
  3. Reloads via apparmor_parser -r.

Called from installDockerRootless after the override.conf write, gated
on $rootless_net == pasta. slirp4netns installs skip it.

This box was already manually patched while debugging the pasta swap —
the installer-side change makes it idempotent across reinstalls and
applies the same fix on any other host that installs rootless docker
with pasta as the net driver.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-26 23:13:04 +01:00
librelad
e56e6918a7 refactor(network): drop dead 'migrate apps to new subnet' machinery
The migrate/ helpers were either uncallable or no-ops:

- migrateAppsToNewNetwork + updateComposeFileNetwork: never called from
  anywhere. The intended sed-on-compose subnet rewrite would also have
  fought the tag system / network_resources DB.
- checkAppNetworkCompatibility: called from updateDockerNetworkConfig as
  a gate, but never explicitly returns, so it's effectively always-true
  and both branches do the same work. Pure noise.
- getInstalledApps: only used by the above.
- updateDockerNetworkConfig: collapses to a 2-line 'CFG := docker's
  reported subnet' adoption — inlined into check_docker_network.sh as
  adoptDockerSubnet(), which is what it actually does.

The legitimate 'subnet changed, refresh apps' path is already covered by
the idempotent per-app reinstall (dockerInstallApp ... reset_network=true
→ clears DB allocations → installer re-runs → ipUpdateComposeTags picks
fresh IPs from the current CFG_NETWORK_SUBNET). Migration (infrastructure
regen) vs restore (data) stays clean: reinstall regenerates compose+IPs,
restore lays data on top. No new pathway needed.

Files dropped:
  scripts/docker/network/migrate/migrate_apps_to_new_network.sh
  scripts/docker/network/migrate/migrate_check_app_network_compatibility.sh
  scripts/docker/network/migrate/migrate_get_installed_apps.sh
  scripts/docker/network/migrate/migrate_update_compose_file_network.sh
  scripts/docker/network/migrate/migrate_update_docker_network_config.sh

Plus the now-empty migrate/ subdir; files_docker.sh regenerated to drop
the references.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-26 16:11:13 +01:00
librelad
7f797273dd refactor(wireguard): inline the host-conflict guard, drop central allowed_install
dockerCheckAllowedInstall was a one-app `case` whose only active caller was the
wireguard app itself — so inline its check (abort if a host WireGuard exists at
/etc/wireguard/params, which would collide on the wg kernel module + UDP 51820)
directly into containers/wireguard/wireguard.sh and delete
scripts/docker/app/checks/allowed_install.sh.

The protection is unchanged; wireguard is now fully self-contained and the last
app name leaves central install code. Regenerated arrays. (The only remaining
dockerCheckAllowedInstall references are in scripts/unused/ — retired apps,
never sourced.)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-26 01:21:08 +01:00
librelad
5c928fe9c0 feat(privilege): mode-aware privileged-op helper
Single place that decides how a privileged op runs by Docker mode:
- runFileOp / runFileWrite: /docker data-plane ops — rooted uses sudo (identical
  to today), rootless runs as the unprivileged install user (no root).
- runSystem: genuine system-admin ops, sudo in both modes, funnelled here so it
  can later be confined to a scoped sudoers allowlist.
Call sites converted to these are byte-for-byte unchanged under rooted, so
existing/live boxes can't regress; rootless gets the de-privileged path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-23 20:35:18 +01:00
librelad
875a60f90f LibrePortal v0.1.0 — initial release
A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys,
Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun
VPN routing, and a web dashboard to manage it all.

Free & open forever to self-host; optional paid hosted services fund it.
See PROMISE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-21 20:37:54 +01:00