From 8e7d672190d6e640661b1f3df6fb57538b9dc78f Mon Sep 17 00:00:00 2001 From: Florent Guiotte Date: Sun, 11 Sep 2022 12:33:19 +0200 Subject: [PATCH] Add taskserver --- .gitattributes | 1 + .gitignore | 1 + README.md | 2 + docker-compose.yml | 26 +++++++++-- taskserver/Dockerfile | 13 ++++++ taskserver/README.md | 16 +++++++ .../etc/cont-init.d/14-install-cert-generator | 20 ++++++++ .../etc/cont-init.d/15-generate-server-certs | 20 ++++++++ .../etc/cont-init.d/16-generate-user-certs | 15 ++++++ taskserver/root/etc/cont-init.d/20-copy-certs | 29 ++++++++++++ .../root/etc/cont-init.d/30-bootstrap-taskd | 43 ++++++++++++++++++ .../root/etc/cont-init.d/35-fix-permissions | 8 ++++ .../root/etc/cont-init.d/90-diagnostics | 6 +++ taskserver/root/etc/services.d/taskd-logs/run | 5 ++ taskserver/root/etc/services.d/taskd/run | 5 ++ taskserver/taskserver.env | Bin 0 -> 516 bytes 16 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 taskserver/Dockerfile create mode 100644 taskserver/README.md create mode 100644 taskserver/root/etc/cont-init.d/14-install-cert-generator create mode 100644 taskserver/root/etc/cont-init.d/15-generate-server-certs create mode 100644 taskserver/root/etc/cont-init.d/16-generate-user-certs create mode 100644 taskserver/root/etc/cont-init.d/20-copy-certs create mode 100644 taskserver/root/etc/cont-init.d/30-bootstrap-taskd create mode 100644 taskserver/root/etc/cont-init.d/35-fix-permissions create mode 100644 taskserver/root/etc/cont-init.d/90-diagnostics create mode 100644 taskserver/root/etc/services.d/taskd-logs/run create mode 100644 taskserver/root/etc/services.d/taskd/run create mode 100644 taskserver/taskserver.env diff --git a/.gitattributes b/.gitattributes index 679eefc..6c14b67 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ ovh.ini filter=git-crypt diff=git-crypt syncthing/config.xml filter=git-crypt diff=git-crypt *.pem filter=git-crypt diff=git-crypt +*.env filter=git-crypt diff=git-crypt diff --git a/.gitignore b/.gitignore index 58e7a2b..5aac5c4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ swag/nginx/worker_processes.conf syncthing/ flood/.local swag/www +taskserver/client_certs/ diff --git a/README.md b/README.md index 458e1e0..df2f76e 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ ## Setup +Once DNS are properly setup on host: + 1. Create OVH token : + `Get *`, `Put *`, ... 2. Paste token in `swag/dns-conf/ovh.ini` diff --git a/docker-compose.yml b/docker-compose.yml index dcc775f..2069510 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,7 +19,6 @@ services: image: lscr.io/linuxserver/swag container_name: swag restart: always - dns: 1.1.1.1 cap_add: - NET_ADMIN environment: @@ -41,7 +40,6 @@ services: image: ihatemoney/ihatemoney container_name: money restart: always - dns: 1.1.1.1 volumes: - money-data:/database environment: @@ -67,7 +65,6 @@ services: image: jesec/rtorrent container_name: rtorrent user: 1000:100 - dns: 1.1.1.1 restart: unless-stopped command: -o network.port_range.set=6881-6881,system.daemon.set=true environment: @@ -82,7 +79,6 @@ services: radarr: image: lscr.io/linuxserver/radarr:latest container_name: radarr - dns: 1.1.1.1 environment: - PUID=1000 - PGID=1000 @@ -99,7 +95,6 @@ services: syncthing: image: lscr.io/linuxserver/syncthing:latest container_name: syncthing - dns: 1.1.1.1 hostname: drmanhattan #optional environment: - PUID=1000 @@ -173,9 +168,30 @@ services: # XXX: Missing "nginx-extra" in my build? + taskserver: + build: taskserver + container_name: taskserver + hostname: a.guiotte.fr + restart: always + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/Paris + env_file: + - taskserver/taskserver.env + ports: + - "53589:53589" + volumes: + - taskserver-data:/var/taskd + - taskserver-certs:/ssl_certs + - ./taskserver/client_certs:/client_certs + + volumes: money-data: zotero-data: lychee-db: lychee-config: lychee-pictures: + taskserver-data: + taskserver-certs: diff --git a/taskserver/Dockerfile b/taskserver/Dockerfile new file mode 100644 index 0000000..4a923c6 --- /dev/null +++ b/taskserver/Dockerfile @@ -0,0 +1,13 @@ +FROM ghcr.io/linuxserver/baseimage-alpine:3.16 + +RUN apk --no-cache add taskd + +ENV TASKDDATA=/var/taskd +VOLUME /var/taskd + +COPY root/ / + +VOLUME /ssl_certs/ /client_certs/ +EXPOSE 53589 + +ENTRYPOINT ["/init"] diff --git a/taskserver/README.md b/taskserver/README.md new file mode 100644 index 0000000..85ac2b4 --- /dev/null +++ b/taskserver/README.md @@ -0,0 +1,16 @@ +# Taskserver + +Written with the help of +. + + +## Certs renewal + +Once a year recreate the container and copy the `client_certs` dir! On +the client: + +```shell +scp -r florent@a.guiotte.fr:~/docker/taskserver/client_certs/* ~/.config/task/certs +task config taskd.credentials -- watch/user/$(cat ~/.config/task/certs/user-uuid) +task sync init +``` diff --git a/taskserver/root/etc/cont-init.d/14-install-cert-generator b/taskserver/root/etc/cont-init.d/14-install-cert-generator new file mode 100644 index 0000000..6137873 --- /dev/null +++ b/taskserver/root/etc/cont-init.d/14-install-cert-generator @@ -0,0 +1,20 @@ +#!/usr/bin/with-contenv sh +#shellsheck shell=sh + +printf "Installing the certificate generator\n" +apk --no-cache add curl gnutls-utils +mkdir -p /opt/src/taskd +# get a copy of the repo wich also contains the certificate generation scripts +curl -sSL https://api.github.com/repos/gothenburgbitfactory/taskserver/tarball/master -o /tmp/taskd.tar.gz +tar xzf /tmp/taskd.tar.gz -C /opt/src/taskd --strip 1 +# set the variables for the certs to be generated (as defined in +# taskserver.env) +{ + echo "BITS=$TASKD_CERT_BITS"; + echo "EXPIRATION_DAYS=$TASKD_CERT_EXPIRATION_DAYS"; + echo "ORGANIZATION=\"$TASKD_CERT_ORGANIZATION\""; + echo "CN=$(hostname -f)"; + echo "COUNTRY=$TASKD_CERT_COUNTRY"; + echo "STATE=\"$TASKD_CERT_STATE\""; + echo "LOCALITY=\"$TASKD_CERT_LOCALITY\""; +} > /opt/src/taskd/pki/vars diff --git a/taskserver/root/etc/cont-init.d/15-generate-server-certs b/taskserver/root/etc/cont-init.d/15-generate-server-certs new file mode 100644 index 0000000..df05aca --- /dev/null +++ b/taskserver/root/etc/cont-init.d/15-generate-server-certs @@ -0,0 +1,20 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh + +if [ -s "$TASKDDATA/ca.cert.pem" ]; then + printf "Server certificates found, not generating any.\n" +else + # Use the generate script to make the CA and server certificates + printf "No server certificates found, generating them...\n" + cd /opt/src/taskd/pki || exit 1 + ./generate + # move generated certs to volumes so they're not lost when the container is + # destroyed, and so that they can be accessed from other containers if needed + cp ./client.key.pem /ssl_certs/ + cp ./client.cert.pem /ssl_certs/ + cp ./server.key.pem /ssl_certs/ + cp ./server.cert.pem /ssl_certs/ + cp ./ca.key.pem /ssl_certs/ + cp ./ca.cert.pem /ssl_certs/ + cp ./ca.cert.pem /client_certs/ +fi diff --git a/taskserver/root/etc/cont-init.d/16-generate-user-certs b/taskserver/root/etc/cont-init.d/16-generate-user-certs new file mode 100644 index 0000000..1ddfa37 --- /dev/null +++ b/taskserver/root/etc/cont-init.d/16-generate-user-certs @@ -0,0 +1,15 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh + +if [ -s "$TASKDDATA/$TASKD_USERNAME.cert.pem" ]; then + printf "User certificate for %s found, not generating again\n" "$TASKD_USERNAME" +else + # Now we generate the user certificate that will go on the client machine + printf "No certificate found for %s, generating user certificate...\n" "$TASKD_USERNAME" + cd /opt/src/taskd/pki || exit 1 + ./generate.client "$TASKD_USERNAME" + # move cert and key to a volume so they're not lost when the container is + # removed and so that they're accessible outside the taskd container + cp "$TASKD_USERNAME".cert.pem /client_certs/"$TASKD_USERNAME".cert.pem + cp "$TASKD_USERNAME".key.pem /client_certs/"$TASKD_USERNAME".key.pem +fi diff --git a/taskserver/root/etc/cont-init.d/20-copy-certs b/taskserver/root/etc/cont-init.d/20-copy-certs new file mode 100644 index 0000000..c738371 --- /dev/null +++ b/taskserver/root/etc/cont-init.d/20-copy-certs @@ -0,0 +1,29 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh + +# Regroup all certificates where taskd will look for them +if [ -s "$TASKDDATA/server.cert.pem" ]; then + printf "Server certificates found in %s, not overwriting\n" "$TASKDDATA" + # put the certs in the ssl_certs volume to avoid mismatch between /ssl_certs + # and the ones the server is using + cp "$TASKDDATA/server.key.pem" /ssl_certs + cp "$TASKDDATA/server.cert.pem" /ssl_certs +else + printf "No server certificates in %s, copying them over...\n" "$TASKDDATA" + cp /ssl_certs/server.key.pem "$TASKDDATA" + cp /ssl_certs/server.cert.pem "$TASKDDATA" +fi + +if [ -s "$TASKDDATA/$TASKD_USERNAME.cert.pem" ]; then + printf "Client certificates for user %s found in %s, not overwriting\n" "$TASKD_USERNAME" "$TASKDDATA" + # put the certs in the client_certs volume to avoid mismatch between + # /client_certs and the ones the server is using + cp "$TASKDDATA/ca.cert.pem" /client_certs + cp "$TASKDDATA/$TASKD_USERNAME.key.pem" /client_certs + cp "$TASKDDATA/$TASKD_USERNAME.cert.pem" /client_certs +else + printf "No certificates for user %s in %s, copying them over...\n" "$TASKD_USERNAME" "$TASKDDATA" + cp /client_certs/ca.cert.pem "$TASKDDATA" + cp "/client_certs/$TASKD_USERNAME.key.pem" "$TASKDDATA" + cp "/client_certs/$TASKD_USERNAME.cert.pem" "$TASKDDATA" +fi diff --git a/taskserver/root/etc/cont-init.d/30-bootstrap-taskd b/taskserver/root/etc/cont-init.d/30-bootstrap-taskd new file mode 100644 index 0000000..52f3d40 --- /dev/null +++ b/taskserver/root/etc/cont-init.d/30-bootstrap-taskd @@ -0,0 +1,43 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh +# with help from https://blog.polettix.it/setup-a-taskwarrior-server/ + +# if we already have a config file, we don't want to overwrite it +if [ -s "$TASKDDATA/config" ]; then + printf "%s/config file found, skipping bootstrap\n" "$TASKDDATA" +else + printf "%s/config file not found, bootstrapping taskd\n" "$TASKDDATA" + # configure taskd, create the organization and user + taskd init + touch "$TASKDDATA/taskd.log" + touch "$TASKDDATA/taskd.pid" + chown taskd "$TASKDDATA/taskd.log" + chown taskd "$TASKDDATA/taskd.pid" + taskd config --force server "$(hostname -f):53589" + taskd config --force log "$TASKDDATA"/taskd.log + taskd config --force pid.file "$TASKDDATA"/taskd.pid + taskd config --force server.key "$TASKDDATA"/server.key.pem + taskd config --force server.cert "$TASKDDATA"/server.cert.pem + taskd config --force server.crl "$TASKDDATA"/server.crl.pem + taskd config --force ca.cert "$TASKDDATA"/ca.cert.pem +fi + +if find "$TASKDDATA/orgs" -name "$TASKD_ORGNAME" | grep "$TASKD_ORGNAME"; then + printf "Organization %s found, not regenerating it\n" "$TASKD_ORGNAME" +else + printf "Organization %s not found, generating it...\n" "$TASKD_ORGNAME" + taskd add org "$TASKD_ORGNAME" +fi + +if grep -qrw "$TASKDDATA/orgs/$TASKD_ORGNAME/users" -e "user=$TASKD_USERNAME"; then + printf "User %s already exists, not recreating it\n" "$TASKD_USERNAME" + # extract the UUID anyway + grep -rw "$TASKDDATA/orgs/$TASKD_ORGNAME/users" -e "user=$TASKD_USERNAME" | sed '/.*\([0-9a-f\-]\{36\}\).*/!d;s//\1/g' > /client_certs/"$TASKD_USERNAME-uuid" +else + printf "User %s didn't exist, creating it...\n" "$TASKD_USERNAME" + # use tee to still write to stdout but also save output to file + taskd add user "$TASKD_ORGNAME" "$TASKD_USERNAME" | tee /client_certs/"$TASKD_USERNAME-uuid" + # now remove the rest of the output and only keep the uuid, useful for + # configuring taskwarrior on the client machine + sed -i '/.*\([0-9a-f\-]\{36\}\)/!d;s//\1/g' /client_certs/"$TASKD_USERNAME-uuid" +fi diff --git a/taskserver/root/etc/cont-init.d/35-fix-permissions b/taskserver/root/etc/cont-init.d/35-fix-permissions new file mode 100644 index 0000000..010b306 --- /dev/null +++ b/taskserver/root/etc/cont-init.d/35-fix-permissions @@ -0,0 +1,8 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh + +# make the taskd data dir rw for the user running taskd +chown -R taskd:taskd "$TASKDDATA" +# make client certs readable for every user to work around UID and GID mapping +# inconsistencies across hosts +chmod +r /client_certs/* diff --git a/taskserver/root/etc/cont-init.d/90-diagnostics b/taskserver/root/etc/cont-init.d/90-diagnostics new file mode 100644 index 0000000..d9fee1a --- /dev/null +++ b/taskserver/root/etc/cont-init.d/90-diagnostics @@ -0,0 +1,6 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh + +# some debug info, useful when running CI tests mostly +s6-setuidgid taskd taskd diagnostics +ls -clash "$TASKDDATA" diff --git a/taskserver/root/etc/services.d/taskd-logs/run b/taskserver/root/etc/services.d/taskd-logs/run new file mode 100644 index 0000000..e38c29b --- /dev/null +++ b/taskserver/root/etc/services.d/taskd-logs/run @@ -0,0 +1,5 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh + +# write a copy of the log in the container's console for easier monitoring/inspection +exec tail -F "$TASKDDATA/taskd.log" diff --git a/taskserver/root/etc/services.d/taskd/run b/taskserver/root/etc/services.d/taskd/run new file mode 100644 index 0000000..9fd4e23 --- /dev/null +++ b/taskserver/root/etc/services.d/taskd/run @@ -0,0 +1,5 @@ +#!/usr/bin/with-contenv sh +#shellcheck shell=sh + +# user taskd will run the taskserver, running as root is asking for trouble +exec s6-setuidgid taskd taskd server diff --git a/taskserver/taskserver.env b/taskserver/taskserver.env new file mode 100644 index 0000000000000000000000000000000000000000..ae26d97b6e3a2b79b73303be74fc79de6aa00f95 GIT binary patch literal 516 zcmV+f0{i^{M@dveQdv+`0N1Gt;-lBa64fu6rC_Qj5m+{vQVBKR179U=Om#Bs-kO+ zSEdI$yb0dbB@ns@NrM*JhSfc`_LBZ(V3BMx;+xTUUa%6dOvbqADH*eSJ(thW2~{k|&MkS&fnmqhmvB@4eiD~^-${3ECv1U>*+6-?WyJE4a`M*8go_&yFNn$S6u7Ko?7P7>p%_WA81gb|-c44Lq4(jcmU21INQ$y+eh^ca_z!0w7N>gd>7c zyaI`L$p8wR(h4SBDP%wPh;Gy?U3g9wZAMBasA0`+W6^5B_`*fD=TV|Jt7cMEx&mOc zMO%~Z9m2o~l9rHc&kQ*0pJXYy+x41W-YB0+s-->|^x!o-KvzTVVXbX1dsB*z2fOv6 zwCLzawbWsLkm$!{;}8^xpF+&C3>j(*g5Us6L6xgnlB)3KYzyc(;w^9C+uJPBQps|Y z*YaGwQpF)oc7`l<+;_?Zb&xqy;oi3HbR;42tV@b