Repository navigation
Security
MrJSA edited this page Nov 2, 2026
·
3 revisions
- Keep
.envprivate (chmod 600 .env); it contains the database password and is never part of the repository. - Use a random database password (
openssl rand -hex 24), set before the first start (see Installation). The backend warns in its log (SECURITY: …) when the password from.env.example, the old default or one shorter than 16 characters is used. - Set
UPDATE_REQUIRE_SIGNED=truein.env, so only signed releases are installed (see Updates). - Do not open ports 8080, 4000 or 8081 in the firewall (see Installation, step 7). Keep
PUBLISH_ADDR=127.0.0.1when a reverse proxy serves the domains: ports published by Docker or Podman bypass ufw. - Restrict the admin domain further (VPN, IP allow-list or HTTP basic auth) if only a few people need it (examples in Installation with Podman#7-caddy-as-reverse-proxy and Own Reverse Proxy).
- Backups contain customer data, password hashes and your payment/email keys. They are encrypted to your age public key; keep the private key in two places off the server (see Backups). Keep the backup repository private anyway and turn on two-factor authentication for your GitHub account.
- Only restore backups you made yourself (see Restoring a Backup).
Containers
- The database is on its own internal network (
db_net): only the backend can reach it, and it has no internet access. Storefront, admin and the proxy cannot even resolve its name. -
Backend (user
shop, uid 10001), storefront and admin (usernode) run without root rights, with all capabilities dropped that they don't need. Log files are limited to 10 MB per file. -
NO_NEW_PRIVILEGES=trueadditionally stops programs from gaining privileges through setuid binaries. Recommended with Docker; leave itfalsewith Podman on AppArmor systems (Debian, Ubuntu), where it stops PostgreSQL from starting.
Logins and forms
- Limits per visitor IP: 10 failed admin logins and 10 failed customer logins per 15 minutes; account registrations, password resets, verification e-mails and newsletter sign-ups are limited per hour. IPv6 visitors count per /64 network.
- Failed logins on one account add a short, growing pause (1, 2, 4 … up to 60 seconds) instead of locking the account, so nobody can lock you out of your admin account by guessing wrong on purpose.
- Password checks (bcrypt) run on a few CPU cores at most, so a login flood can't slow down the whole server.
- The visitor IP comes from
X-Forwarded-Foronly behind a reverse proxy on the same server (PUBLISH_ADDR=127.0.0.1); with the ports open to the network it is taken from the connection, because the header could be forged.TRUST_PROXYin.envoverrides this (see Own Reverse Proxy).
Backups
- Encrypted with age before they leave the server; only your private key opens them. Without a public key no backup is uploaded at all (see Backups).
Database
- Every database migration runs in one transaction: a failing update can never leave a half-changed database.
- Restoring a backup runs only SQL:
psqlruns in restricted mode, so a backup file that contains psql commands (which could start programs on the server) is refused and nothing is changed.
Updates
- The updater service can control Docker/Podman on the host (that is how it rebuilds the shop). It has no published port,
is only reachable by the backend over a private network and requires a token generated on first start. Remove the
updaterservice fromdocker-compose.ymlif you prefer updating manually. - It installs only releases signed with a key that the installed version trusts (
deploy/updater/allowed_signers), backs up the database first (only root can read these dumps; the last 10 are kept) and goes back to the previous version when the shop does not come back healthy. - Files the updater changes in the checkout are owned by
root; usesudofor manual git commands in/opt/rustwebshop.
Please don't open a public issue for security problems: report them privately to the maintainer (github.com/MrJSA). Leave out passwords, keys and customer data (see Reporting Issues).
Getting started
Running the shop
- Admin Overview
- Updates
- Release Channels
- Domains
- Restoring a Backup
- Own Reverse Proxy
- Troubleshooting
- Security
Help & feedback