Some update

This commit is contained in:
Minecon724 2025-08-17 21:43:59 +02:00
commit e92a7e2e62
Signed by: Minecon724
GPG key ID: A02E6E67AB961189
13 changed files with 94 additions and 128 deletions

4
.gitignore vendored
View file

@ -1,2 +1,2 @@
run/
control-server/build/
/run/
/control-server/build/

76
.vscode/settings.json vendored
View file

@ -1,76 +0,0 @@
{
"files.associations": {
"ostream": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"cctype": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"concepts": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"format": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"numbers": "cpp",
"ranges": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"typeinfo": "cpp",
"variant": "cpp",
"text_encoding": "cpp",
"queue": "cpp",
"filesystem": "cpp",
"any": "cpp",
"condition_variable": "cpp",
"coroutine": "cpp",
"source_location": "cpp",
"future": "cpp",
"mutex": "cpp",
"stop_token": "cpp",
"thread": "cpp",
"list": "cpp",
"semaphore": "cpp",
"stdfloat": "cpp",
"fstream": "cpp"
}
}

View file

@ -24,12 +24,11 @@ RUN mkdir -p build \
FROM docker.io/nginx:${NGINX_TAG}
ENV DOMAIN="example.localhost"
#ENV DOMAIN="example.localhost"
ENV SERVER_ID="server"
ENV RELOAD_FILE="/var/run/nginx-reload"
ENV ACME_CHALLENGE_URL="http://acme-challenge.${DOMAIN}/.well-known/acme-challenge/"
ENV CONTROL_DOMAIN="control.localhost"
ENV CONTROL_TOKEN="Tr0ub4dor&3"
ENV ACME_CHALLENGE_URL='http://acme-challenge.${DOMAIN}/.well-known/acme-challenge'
#ENV CONTROL_DOMAIN="control.localhost"
#ENV CONTROL_TOKEN="Tr0ub4dor&3"
COPY nginx /etc/nginx/
COPY certificates /etc/ssl/

View file

@ -1,30 +1,30 @@
This is a container that helps host a static website.
This is a container that helps host a website.
## Configuration
**Requires** the following mounts:
- `/etc/ssl/certs/$DOMAIN`: For certificates (`fullchain.pem` and `privkey.pem`)
- `/var/www/html/$DOMAIN`: Website files, `index.html` goes right here
- `/etc/ssl/certs/<domain>`: For certificates, `fullchain.pem` and `privkey.pem`. Also includes the control domain. Can be read-only if you don't use the built-in (control server) certificate management.
- `/var/www/html/<domain>`: Website files, `index.html` goes right here, mount this read-only
**Requires** the following environment variables:
- `DOMAIN`: The domain
- `ACME_CHALLENGE_HOST`: The source of `.well-known/acme-challenge`
- `DOMAINS`: One or more domains to handle, separated with `,`s or spaces
- `ACME_CHALLENGE_HOST`: The source of `.well-known/acme-challenge`. Proxied, may be internal. Don't forget to add
- `CONTROL_DOMAIN`: Domain to access the control server
- `CONTROL_TOKEN`: Token to access the control server
You're also encouraged to provide your own:
- `/etc/ssl/dhparam.pem`, generated with:
- `/etc/ssl/dhparam.pem` (read-only), generated with:
```bash
openssl dhparam -out dhparam.pem 4096
```
- `/etc/ssl/snakeoil.key` & `/etc/ssl/snakeoil.pem`, generated with:
- `/etc/ssl/snakeoil.key` (read-only) & `/etc/ssl/snakeoil.pem` (read-only), generated with:
```bash
openssl req -new -x509 -days 398 -noenc -out snakeoil.pem -keyout snakeoil.key -subj "/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd"
```
- `SERVER_ID`: How to call this server (for info)
- **Mount** `/var/run/nginx-reload`: modify this file to reload nginx
- `SERVER_ID`: Label this server (informational, not used currently)
## Control server
Authorize as you normally would with a Bearer token.
Authorize as you normally do with a Bearer token.
If you get an empty response, watch the status code!
@ -41,5 +41,13 @@ Endpoints:
- `/reload`: Reloads nginx
- `/certificate/<domain>`: Uploads a certificate (POST, upload like a form with field names `certificate` and `private_key`)
## Custom nginx configs
Put custom configuration templates in the `/templates/` directory
Stock config files, mount (read-only) to replace:
- Control: `control.conf.template` ([default](nginx/templates/control.conf.template))
- Website: `website.conf.btemplate` ([default](nginx/templates/website.conf.template)) (not used hence diff extension)
- Specific website: `website-$DOMAIN.conf.template` (generated)
## TODO
- support for multiple domains

View file

@ -4,7 +4,7 @@ services:
context: .
dockerfile: Containerfile
environment:
DOMAIN: example.localhost
DOMAINS: example.localhost
SERVER_ID: development
ACME_CHALLENGE_URL: https://files.catbox.moe/xpfyfh
CONTROL_DOMAIN: control.localhost
@ -16,4 +16,5 @@ services:
volumes:
- ./run/html:/var/www/html
- ./run/certs:/etc/ssl/certs
- ./run/reload:/var/run/nginx-reload

View file

@ -0,0 +1,17 @@
#!/bin/sh
set -euo pipefail
: "${DOMAINS?Error: DOMAINS environment variable is not set.}"
: "${CONTROL_DOMAIN?Error: CONTROL_DOMAIN environment variable is not set.}"
: "${CONTROL_TOKEN?Error: CONTROL_TOKEN environment variable is not set.}"
for domain in ${DOMAINS//,/ }; do
echo "Detected domain: $domain"
if [ "$domain" = "$CONTROL_DOMAIN" ]; then
echo "Domain must not equal control domain"
exit 1
fi
done

View file

@ -0,0 +1,14 @@
#!/bin/sh
set -euo pipefail
if [ -e "/templates" ]; then
cp -r templates/. /etc/nginx/templates/
fi
for domain in ${DOMAINS//,/ }; do
cp -n /etc/nginx/templates/website.conf.btemplate /etc/nginx/templates/website-$domain.conf.template
sed -i "s/\$DOMAIN/$domain/g" /etc/nginx/templates/website-$domain.conf.template
sed -i "s/\${DOMAIN}/$domain/g" /etc/nginx/templates/website-$domain.conf.template
done

View file

@ -1,29 +0,0 @@
#!/bin/sh
set -euo pipefail
: "${DOMAIN?Error: DOMAIN environment variable is not set.}"
: "${CONTROL_DOMAIN?Error: CONTROL_DOMAIN environment variable is not set.}"
CERTIFICATE_ROOT="/etc/ssl"
setup_snakeoil_cert() {
local domain="$1"
local cert_dir="$CERTIFICATE_ROOT/certs/$domain"
mkdir -p "$cert_dir"
cp -n "$CERTIFICATE_ROOT/snakeoil.pem" "$cert_dir/fullchain.pem"
cp -n "$CERTIFICATE_ROOT/snakeoil.key" "$cert_dir/privkey.pem"
chmod 644 "$cert_dir/fullchain.pem"
chmod 600 "$cert_dir/privkey.pem"
}
for domain_to_setup in "$DOMAIN" "$CONTROL_DOMAIN"; do
echo "Ensuring certificate for domain: $domain_to_setup"
setup_snakeoil_cert "$domain_to_setup"
done
echo "Placeholder certificate setup complete."

View file

@ -0,0 +1,23 @@
#!/bin/sh
set -euo pipefail
CERTIFICATE_ROOT="/etc/ssl"
setup_snakeoil_cert() {
local domain="$1"
local cert_dir="$CERTIFICATE_ROOT/certs/$domain"
mkdir -p "$cert_dir"
cp -n "$CERTIFICATE_ROOT/snakeoil.key" "$cert_dir/privkey.pem"
cp -n "$CERTIFICATE_ROOT/snakeoil.pem" "$cert_dir/fullchain.pem"
chmod 600 "$cert_dir/privkey.pem" || true
chmod 600 "$cert_dir/fullchain.pem" || true
}
for domain in ${DOMAINS//,/ } $CONTROL_DOMAIN; do
echo "Ensuring certificate for domain: $domain"
setup_snakeoil_cert "$domain"
done

View file

@ -6,4 +6,6 @@ CONTROL_SERVER_SOCKET="/var/run/control-server.sock"
NGINX_PID_FILE="/var/run/nginx.pid"
CERTIFICATE_PATH="/etc/ssl/certs"
# TODO run this as user
control_server $CONTROL_SERVER_SOCKET $NGINX_PID_FILE $CERTIFICATE_PATH &

View file

@ -13,9 +13,9 @@ http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# looking for $remote_addr and $http_user_agent?
log_format main '$remote_user [$time_local] "$request" '
'$status $body_bytes_sent bytes "$http_referer" '
'"$http_x_forwarded_for"';
'$status $body_bytes_sent bytes "$http_referer" ';
access_log /var/log/nginx/access.log main; # /dev/null to disable
@ -57,7 +57,7 @@ http {
ssl_stapling_verify on;
# async 'resolver' is important for proper operation of OCSP stapling
resolver [2001:4860:4860::8888] 8.8.8.8;
# resolver [2001:4860:4860::8888] 8.8.8.8;
# If certificates are marked OCSP Must-Staple, consider managing the
# OCSP stapling cache with an external script, e.g. certbot-ocsp-fetcher

View file

@ -18,4 +18,10 @@ server {
proxy_pass http://unix:/var/run/control-server.sock;
}
location /.well-known/acme-challenge {
set $target ${ACME_CHALLENGE_URL};
proxy_buffering off;
proxy_pass $target;
}
}

View file

@ -13,7 +13,8 @@ server {
index index.html;
location /.well-known/acme-challenge {
set $target ${ACME_CHALLENGE_URL};
proxy_buffering off;
proxy_pass ${ACME_CHALLENGE_URL};
proxy_pass $target;
}
}