64 lines
2.8 KiB
Markdown
64 lines
2.8 KiB
Markdown
# docker-mailserver "fake VPS" (one directory, nothing else)
|
|
|
|
A copy-paste setup that gives an operator (or an agent) an **interactive SSH
|
|
shell that feels like a VPS** — but the only real host data on it is your
|
|
`docker-mailserver` directory. The rest of the server's filesystem isn't
|
|
mounted, so there's nothing else to see.
|
|
|
|
Contrast with the sibling [`../docker-mailserver/`](../docker-mailserver/)
|
|
example: that one is **broker mode** — a fixed *menu* of `setup email …`
|
|
commands, no shell. This one is the opposite — a **full shell**, scoped to one
|
|
directory, for when you want to edit configs and drive `docker compose`
|
|
yourself.
|
|
|
|
## What you get
|
|
|
|
```
|
|
ssh -p 2222 agent@your-host
|
|
└─ bastion-vps key auth; forces every session into the jail
|
|
└─ docker exec -it dms-jail bash
|
|
└─ dms-jail disposable alpine + docker/compose/editors/git
|
|
ONLY real mount: your docker-mailserver directory
|
|
you land in it, read-write
|
|
```
|
|
|
|
Inside the shell you can `vim mailserver.env`, `docker compose up -d`,
|
|
`docker exec mailserver setup email add …`, `git pull`, etc.
|
|
|
|
## Setup
|
|
|
|
1. Paths are preset to `/srv/docker-mailserver` (host and in-jail, identical).
|
|
If your directory is elsewhere, edit the **two** paths in
|
|
[`docker-compose.yml`](docker-compose.yml) and keep both sides of the `:`
|
|
identical — a different in-jail path still lets you read/edit files, but
|
|
`docker compose` from the jail would resolve the stack's bind mounts to a
|
|
host path that doesn't exist and bring the mailserver up with empty data.
|
|
2. Add your key:
|
|
```bash
|
|
mkdir -p docker-data/bastion/users.d
|
|
cp ~/.ssh/id_ed25519.pub docker-data/bastion/users.d/me.pub
|
|
```
|
|
3. Launch:
|
|
```bash
|
|
docker compose up -d --build
|
|
ssh -p 2222 agent@your-host
|
|
```
|
|
|
|
## Security note — the docker-socket tradeoff
|
|
|
|
To let you run `docker compose` / restart the mailserver from the shell, the
|
|
jail is given the host docker socket. **A docker socket is host-root
|
|
equivalent** — from inside the shell, `docker run -v /:/host alpine sh` would
|
|
expose the whole host. So this is a *practical* one-directory VPS for **trusted
|
|
operators**, not a hard sandbox an adversary can't escape.
|
|
|
|
Want a real "only this directory exists" boundary instead? Remove the
|
|
`/var/run/docker.sock` mount from **both** services in the compose file. You
|
|
lose in-shell `docker compose`/restart (manage the stack from a separate
|
|
broker-mode bastion — see [`../docker-mailserver/`](../docker-mailserver/)),
|
|
but the shell then genuinely cannot reach anything but the mounted directory.
|
|
|
|
The auth boundary is your SSH key (`users.d/*.pub`) plus the bastion's
|
|
`ForceCommand`, which clients cannot bypass — a session can only ever become
|
|
the jail shell, never anything else.
|