Deploy model: listen port, token files, state directory owner #41
@@ -313,7 +313,12 @@ exec chpst -u app:app /usr/local/bin/app \
|
|||||||
- Port 8080 is the only one the app must leave free: the health check, the
|
- Port 8080 is the only one the app must leave free: the health check, the
|
||||||
metrics and ban management are all on it, under `/_smallwebwaf/`. The image's
|
metrics and ban management are all on it, under `/_smallwebwaf/`. The image's
|
||||||
health check passes while `smallwebwaf` answers and the app accepts
|
health check passes while `smallwebwaf` answers and the app accepts
|
||||||
connections.
|
connections. `SWWAF_LISTEN_ADDR` can move `smallwebwaf` to another port, which
|
||||||
|
the app then leaves free instead; the health check follows it, and traefik's
|
||||||
|
labels must point at it. The address part of `SWWAF_LISTEN_ADDR` stays empty
|
||||||
|
(for example `:9000`, never `127.0.0.1:9000`), so `smallwebwaf` keeps
|
||||||
|
listening on every address: traefik reaches it on the container's address, and
|
||||||
|
the health check on `127.0.0.1`.
|
||||||
- `smallwebwaf` keeps its state files in `/var/lib/smallwebwaf`. Mount a volume
|
- `smallwebwaf` keeps its state files in `/var/lib/smallwebwaf`. Mount a volume
|
||||||
there to keep bans and client history when a deploy replaces the container;
|
there to keep bans and client history when a deploy replaces the container;
|
||||||
without one, it still starts.
|
without one, it still starts.
|
||||||
|
|||||||
@@ -1170,8 +1170,9 @@ The image holds:
|
|||||||
- The `smallwebwaf` binary, and a user of its own, `smallwebwaf` (uid and gid
|
- The `smallwebwaf` binary, and a user of its own, `smallwebwaf` (uid and gid
|
||||||
65532).
|
65532).
|
||||||
- The service directory `/etc/service/smallwebwaf`, whose `run` script waits one
|
- The service directory `/etc/service/smallwebwaf`, whose `run` script waits one
|
||||||
second (`sleep 1`), makes `SWWAF_STATE_DIR` belong to the `smallwebwaf` user,
|
second (`sleep 1`), makes `SWWAF_STATE_DIR` and every file in it belong to the
|
||||||
and starts `smallwebwaf` as that user with runit's `chpst`.
|
`smallwebwaf` user, and starts `smallwebwaf` as that user with runit's
|
||||||
|
`chpst`.
|
||||||
- The directory `/var/lib/smallwebwaf` for the state files, and
|
- The directory `/var/lib/smallwebwaf` for the state files, and
|
||||||
`/etc/smallwebwaf/rules.d` with the default rule file (see "Rule files").
|
`/etc/smallwebwaf/rules.d` with the default rule file (see "Rule files").
|
||||||
- Port 8080 declared (`EXPOSE 8080`), and the health check described below
|
- Port 8080 declared (`EXPOSE 8080`), and the health check described below
|
||||||
@@ -1261,18 +1262,24 @@ The two processes:
|
|||||||
status into its directory under `/etc/service`.
|
status into its directory under `/etc/service`.
|
||||||
|
|
||||||
The health check: the image's `HEALTHCHECK` passes while `smallwebwaf` answers
|
The health check: the image's `HEALTHCHECK` passes while `smallwebwaf` answers
|
||||||
`GET /_smallwebwaf/healthz` on `127.0.0.1:8080` and the app accepts connections
|
`GET /_smallwebwaf/healthz` on `127.0.0.1`, at the port in `SWWAF_LISTEN_ADDR`,
|
||||||
at the address in `SWWAF_UPSTREAM_URL`, and fails when either does not. The
|
and the app accepts connections at the address in `SWWAF_UPSTREAM_URL`, and
|
||||||
container therefore shows as healthy only while both processes are up. An app
|
fails when either does not. The container therefore shows as healthy only while
|
||||||
with a health check of its own can replace the image's `HEALTHCHECK` with one
|
both processes are up. An app with a health check of its own can replace the
|
||||||
that checks both.
|
image's `HEALTHCHECK` with one that checks both.
|
||||||
|
|
||||||
Ports: `smallwebwaf` listens on port 8080 on every address and on no other port;
|
Ports: `smallwebwaf` listens on port 8080 on every address and on no other port;
|
||||||
its health check, metrics and ban management are all on that listener, under
|
its health check, metrics and ban management are all on that listener, under
|
||||||
`/_smallwebwaf/` (see "Admin endpoints"). The app must leave port 8080 free. It
|
`/_smallwebwaf/` (see "Admin endpoints"). `SWWAF_LISTEN_ADDR` may set another
|
||||||
listens on `127.0.0.1:8081` only, so that nothing outside the container reaches
|
port: the image's health check takes its port from that setting, and traefik's
|
||||||
it except through `smallwebwaf`: an app that listens on every address can be
|
port label (`traefik.http.services.<name>.loadbalancer.server.port`) must name
|
||||||
reached around `smallwebwaf` by anything that reaches the container.
|
the same port, and the app must leave that port free. The address part of
|
||||||
|
`SWWAF_LISTEN_ADDR` stays empty (for example `:9000`, never `127.0.0.1:9000`),
|
||||||
|
so `smallwebwaf` keeps listening on every address: traefik reaches it on the
|
||||||
|
container's address, and the health check on `127.0.0.1`. The app listens on
|
||||||
|
`127.0.0.1:8081` only, so that nothing outside the container reaches it except
|
||||||
|
through `smallwebwaf`: an app that listens on every address can be reached
|
||||||
|
around `smallwebwaf` by anything that reaches the container.
|
||||||
|
|
||||||
State: `smallwebwaf` keeps its state files in `/var/lib/smallwebwaf`
|
State: `smallwebwaf` keeps its state files in `/var/lib/smallwebwaf`
|
||||||
(`SWWAF_STATE_DIR`), a directory of its own beside the app's data, which the app
|
(`SWWAF_STATE_DIR`), a directory of its own beside the app's data, which the app
|
||||||
@@ -1280,13 +1287,21 @@ keeps in directories of its own, such as `/var/lib/app`. Without a volume there,
|
|||||||
the files live in the container: they survive a restart of the container and are
|
the files live in the container: they survive a restart of the container and are
|
||||||
lost when a deploy replaces it. A volume mounted at `/var/lib/smallwebwaf`,
|
lost when a deploy replaces it. A volume mounted at `/var/lib/smallwebwaf`,
|
||||||
named or a host directory, keeps them across deploys; the `run` script of
|
named or a host directory, keeps them across deploys; the `run` script of
|
||||||
`smallwebwaf` makes it belong to the `smallwebwaf` user, so a host directory
|
`smallwebwaf` makes it and every file in it belong to the `smallwebwaf` user, so
|
||||||
mounted there needs no change of owner. It is a volume of its own, separate from
|
a host directory mounted there needs no change of owner, and files an earlier
|
||||||
the app's, holds a few tens of MiB at most with the defaults (see "Persistent
|
owner left in it can be read and replaced. It is a volume of its own, separate
|
||||||
state"), and needs no backup beyond whatever the host already does. The image
|
from the app's, holds a few tens of MiB at most with the defaults (see
|
||||||
declares no volume, since every app image built on it would inherit it.
|
"Persistent state"), and needs no backup beyond whatever the host already does.
|
||||||
Milestone 2 (https://git.eeqj.de/sneak/smallwebwaf/issues/14) writes no state
|
The image declares no volume, since every app image built on it would inherit
|
||||||
files and needs no volume.
|
it. Milestone 2 (https://git.eeqj.de/sneak/smallwebwaf/issues/14) writes no
|
||||||
|
state files and needs no volume.
|
||||||
|
|
||||||
|
Tokens: a token given as a file (`SWWAF_ADMIN_TOKEN_FILE`,
|
||||||
|
`SWWAF_METRICS_TOKEN_FILE`) is out of the app's reach only while the
|
||||||
|
`smallwebwaf` user alone can read the file. The operator makes the file on the
|
||||||
|
host, owned by uid 65532, the `smallwebwaf` user, with mode `0400`, and mounts
|
||||||
|
the directory that holds it into the container read-only; the container sees the
|
||||||
|
same owner and mode.
|
||||||
|
|
||||||
Forwarded headers: the app's TCP peer is `smallwebwaf` on `127.0.0.1`, and the
|
Forwarded headers: the app's TCP peer is `smallwebwaf` on `127.0.0.1`, and the
|
||||||
`X-Forwarded-For` the app receives ends with traefik's address, which
|
`X-Forwarded-For` the app receives ends with traefik's address, which
|
||||||
@@ -1305,7 +1320,8 @@ and runs the one container as it runs any app, with the app's traefik labels,
|
|||||||
environment variables and volumes. The labels route to port 8080
|
environment variables and volumes. The labels route to port 8080
|
||||||
(`traefik.http.services.<name>.loadbalancer.server.port=8080`), any `SWWAF_`
|
(`traefik.http.services.<name>.loadbalancer.server.port=8080`), any `SWWAF_`
|
||||||
settings go with the app's environment variables, and the volume for
|
settings go with the app's environment variables, and the volume for
|
||||||
`/var/lib/smallwebwaf` goes beside the app's own.
|
`/var/lib/smallwebwaf` goes beside the app's own, as does the directory that
|
||||||
|
holds any token file.
|
||||||
|
|
||||||
- The endpoints of `smallwebwaf` are reached through traefik like any other
|
- The endpoints of `smallwebwaf` are reached through traefik like any other
|
||||||
request, for example `https://app.example.invalid/_smallwebwaf/metrics` for a
|
request, for example `https://app.example.invalid/_smallwebwaf/metrics` for a
|
||||||
@@ -1504,7 +1520,7 @@ settings go with the app's environment variables, and the volume for
|
|||||||
stops the start. The app starts with the same environment variables as
|
stops the start. The app starts with the same environment variables as
|
||||||
`smallwebwaf`, so it can read a token given as one; a token given as a file
|
`smallwebwaf`, so it can read a token given as one; a token given as a file
|
||||||
that only the `smallwebwaf` user can read (`SWWAF_ADMIN_TOKEN_FILE`,
|
that only the `smallwebwaf` user can read (`SWWAF_ADMIN_TOKEN_FILE`,
|
||||||
`SWWAF_METRICS_TOKEN_FILE`) is out of the app's reach.
|
`SWWAF_METRICS_TOKEN_FILE`) is out of the app's reach (see "Deployment").
|
||||||
- GeoJS, the default lookup source: every new visitor's address goes to a third
|
- GeoJS, the default lookup source: every new visitor's address goes to a third
|
||||||
party, and a swarm of fresh addresses, when lookups peak, is when GeoJS may
|
party, and a swarm of fresh addresses, when lookups peak, is when GeoJS may
|
||||||
slow down or block `smallwebwaf`. Keeping answers for 7 days and asking about
|
slow down or block `smallwebwaf`. Keeping answers for 7 days and asking about
|
||||||
|
|||||||
Reference in New Issue
Block a user