From 5ed93cbaa88262498220562cb4be640cf7d72617 Mon Sep 17 00:00:00 2001 From: Dominic Ricottone Date: Sat, 10 Sep 2022 22:50:51 -0500 Subject: [PATCH] Version 1.0 Fully functional and mature implementation for x86 and aarch64, for docker and podman. The process from source code to live deployment is now reproducible and documented in both the README and the Makefile recipes. Git repos are now accessible by SSH or HTTP(S). The `lists.sr.ht` functionality is deferred as out-of-scope and the `builds.sr.ht` functionality is permanently declared out-of-scope. Running the maintenance cron jobs is a TODO, as the relevence to this project is dubious. --- .gitignore | 19 ++- LICENSE.md | 14 +++ Makefile.docker | 66 +++++----- Makefile.podman | 23 ++-- README.md | 25 +++- sr/Dockerfile.aarch64 | 61 +++++---- sr/Dockerfile.x86 | 57 ++++----- sr/etc/nginx/http.d/lists.conf | 61 --------- sr/etc/nginx/http.d/test.conf | 33 ----- sr/etc/postfix/{generic => generic.changeme} | 0 .../{sasl_passwd => sasl_passwd.changeme} | 0 .../sr.ht/{config.ini => config.ini.changeme} | 20 +-- sr/etc/sr.ht/lists.config.ini | 48 ------- sr/etc/ssh/sshd_config | 118 ++++++++++++++++++ sr/etc/supervisor/conf.d/supervisord.conf | 7 +- 15 files changed, 291 insertions(+), 261 deletions(-) create mode 100644 LICENSE.md delete mode 100644 sr/etc/nginx/http.d/lists.conf rename sr/etc/postfix/{generic => generic.changeme} (100%) rename sr/etc/postfix/sasl/{sasl_passwd => sasl_passwd.changeme} (100%) rename sr/etc/sr.ht/{config.ini => config.ini.changeme} (92%) delete mode 100644 sr/etc/sr.ht/lists.config.ini create mode 100644 sr/etc/ssh/sshd_config diff --git a/.gitignore b/.gitignore index a83bafe..f9095d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,22 @@ +# keys sr/etc/sr.ht/pgp.key sr/etc/sr.ht/pgp.pubkey -**/datadir +sr/etc/ssh/ssh_host_dsa_key +sr/etc/ssh/ssh_host_dsa_key.pub +sr/etc/ssh/ssh_host_ecdsa_key +sr/etc/ssh/ssh_host_ecdsa_key.pub +sr/etc/ssh/ssh_host_ed25519_key +sr/etc/ssh/ssh_host_ed25519_key.pub +sr/etc/ssh/ssh_host_rsa_key +sr/etc/ssh/ssh_host_rsa_key.pub + +# symlinked files Makefile sr/Dockerfile + +# configuration files that also contain sensitive keys/passwords +#TODO: find a better way to hide sensitive information +sr/etc/postfix/generic +sr/etc/postfix/sasl/sasl_passwd +sr/etc/sr.ht/config.ini + diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..5a4bbfe --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,14 @@ +Zero-Clause BSD +=============== + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/Makefile.docker b/Makefile.docker index 1b8cc3a..b9fbf7e 100644 --- a/Makefile.docker +++ b/Makefile.docker @@ -27,6 +27,9 @@ SRHT_LOCALVERSION=1 CERTDIR=/var/deploy/certs +keys: + ssh-keygen -A -f etc/ssh/ + cleanup: $(CONMAN) network disconnect --force $(HUTTESE_NETWORK) $(HUTTESE_REDIS) >/dev/null 2>&1 || true $(CONMAN) network disconnect --force $(HUTTESE_NETWORK) $(HUTTESE_POSTGRES) >/dev/null 2>&1 || true @@ -46,12 +49,8 @@ setup: && $(CONMAN) tag $(REDIS_TARGET) $(REDIS_LOCALNAME) $(CONMAN) run --detach --name $(HUTTESE_REDIS) --restart always \ $(REDIS_LOCALNAME) - #if I need persistence later: - # --mount type=bind,src=$(REDIS_DATADIR),dst=/data \ - # $(REDIS_LOCALNAME) redis-server --save 60 1 --loglevel warning $(CONMAN) network connect --alias $(HUTTESE_REDIS) \ $(HUTTESE_NETWORK) $(HUTTESE_REDIS) - # redis is now available at redis://huttredis:6379 $(CONMAN) inspect $(POSTGRES_LOCALNAME) >/dev/null 2>&1 \ || $(CONMAN) pull $(POSTGRES_TARGET) \ @@ -63,15 +62,20 @@ setup: $(POSTGRES_LOCALNAME) -c 'config_file=/etc/postgresql/postgresql.conf' $(CONMAN) network connect --alias $(HUTTESE_POSTGRES) \ $(HUTTESE_NETWORK) $(HUTTESE_POSTGRES) - # postgres is now available at postgresql://postgres@huttpg:5432 image: + # these are only necessary if on aarch64 + cp -r /var/deploy/build/huttese-apk/pkg sr/pkg + cp -r /var/deploy/build/huttese-apk/keys sr/etc/apk/keys + $(CONMAN) inspect $(SRHT_LOCALNAME) >/dev/null 2>&1 \ || $(CONMAN) build \ --tag $(SRHT_LOCALNAME):latest \ --tag $(SRHT_LOCALNAME):$(SRHT_LOCALVERSION) \ sr/ + rm -rf sr/pkg sr/etc/apk/keys + dbinit: image $(CONMAN) inspect $(HUTTESE_NETWORK) >/dev/null 2>&1 $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 @@ -83,54 +87,45 @@ dbinit: image $(CONMAN) exec $(HUTTESE_POSTGRES) \ createdb -U postgres todo.sr.ht - $(CONMAN) run --name $(HUTTESE_SRHT)_dbinit \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbinit --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) metasrht-initdb - $(CONMAN) rm $(HUTTESE_SRHT)_dbinit - $(CONMAN) run --name $(HUTTESE_SRHT)_dbinit \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbinit --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) gitsrht-initdb - $(CONMAN) rm $(HUTTESE_SRHT)_dbinit - $(CONMAN) run --name $(HUTTESE_SRHT)_dbinit \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbinit --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) todosrht-initdb - $(CONMAN) rm $(HUTTESE_SRHT)_dbinit dbmigrate: image $(CONMAN) inspect $(HUTTESE_NETWORK) >/dev/null 2>&1 $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 - $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) srht-migrate meta.sr.ht -a upgrade head - $(CONMAN) rm $(HUTTESE_SRHT)_dbmigrate - $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) metasrht-migrate -a upgrade head - $(CONMAN) rm $(HUTTESE_SRHT)_dbmigrate - $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) srht-migrate git.sr.ht -a upgrade head - $(CONMAN) rm $(HUTTESE_SRHT)_dbmigrate - $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) gitsrht-migrate -a upgrade head - $(CONMAN) rm $(HUTTESE_SRHT)_dbmigrate - $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) srht-migrate todo.sr.ht -a upgrade head - $(CONMAN) rm $(HUTTESE_SRHT)_dbmigrate - $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate \ + $(CONMAN) run --name $(HUTTESE_SRHT)_dbmigrate --rm \ --network $(HUTTESE_NETWORK) \ $(SRHT_LOCALNAME) todosrht-migrate -a upgrade head - $(CONMAN) rm $(HUTTESE_SRHT)_dbmigrate start: image $(CONMAN) inspect $(HUTTESE_NETWORK) >/dev/null 2>&1 @@ -138,8 +133,12 @@ start: image $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_REDIS) >/dev/null 2>&1 $(CONMAN) run --detach --name $(HUTTESE_SRHT) --restart always \ - --hostname tatooine --hostname dominic-ricottone.com \ - --publish 0.0.0.0:80:80 --publish 0.0.0.0:443:443\ + --hostname tatooine \ + --hostname dominic-ricottone.com \ + --hostname meta.dominic-ricottone.com \ + --hostname git.dominic-ricottone.com \ + --hostname todo.dominic-ricottone.com \ + --publish 0.0.0.0:80:80 --publish 0.0.0.0:443:443 --publish 0.0.0.0:8822:22 \ --mount type=bind,src=$(GIT_DATADIR),dst=/var/lib/git \ --mount type=bind,src=$(CERTDIR),dst=/var/lets-encrypt \ $(SRHT_LOCALNAME) @@ -152,8 +151,17 @@ adduser: $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_REDIS) >/dev/null 2>&1 - @echo "USAGE: USER_EMAIL=me@example.com USER_NAME=me make adduser" - $(CONMAN) exec -it $(HUTTESE_SRHT) metasrht-manageuser -e $(USER_EMAIL) -t admin $(USER_NAME) + $(CONMAN) exec -it $(HUTTESE_SRHT) metasrht-manageuser -e $(USER_EMAIL) -t active_free $(USER_NAME) \ + || echo "USAGE: USER_EMAIL=me@example.com USER_NAME=me make adduser" + +USER_EMAIL?= +USER_NAME?= +addadmin: + $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 + $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_REDIS) >/dev/null 2>&1 + + $(CONMAN) exec -it $(HUTTESE_SRHT) metasrht-manageuser -e $(USER_EMAIL) -t admin $(USER_NAME) \ + || echo "USAGE: USER_EMAIL=me@example.com USER_NAME=me make adduser" shell: image $(CONMAN) inspect $(HUTTESE_NETWORK) >/dev/null 2>&1 @@ -163,14 +171,14 @@ shell: image $(CONMAN) exec -it $(HUTTESE_SRHT) sh stop: - $(CONMAN) stop $(SRHT_LOCALNAME) + $(CONMAN) stop $(HUTTESE_SRHT) restart: $(CONMAN) inspect $(HUTTESE_NETWORK) >/dev/null 2>&1 $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 $(CONMAN) inspect -f '{{.State.Running}}' $(HUTTESE_REDIS) >/dev/null 2>&1 - $(CONMAN) restart $(SRHT_LOCALNAME) + $(CONMAN) restart $(HUTTESE_SRHT) clean: $(CONMAN) rm --force $(HUTTESE_SRHT) >/dev/null 2>&1 || true diff --git a/Makefile.podman b/Makefile.podman index 7cfb5ac..f59b5d2 100644 --- a/Makefile.podman +++ b/Makefile.podman @@ -27,6 +27,9 @@ SRHT_LOCALVERSION=1 CERTDIR=/var/deploy/certs +keys: + ssh-keygen -A -f etc/ssh/ + pod: $(PODMAN) pod exists $(HUTTESE_POD) >/dev/null 2>&1 \ || $(PODMAN) pod create --name $(HUTTESE_POD) \ @@ -35,7 +38,7 @@ pod: --add-host=meta.dominic-ricottone.com:127.0.0.1 \ --add-host=git.dominic-ricottone.com:127.0.0.1 \ --add-host=todo.dominic-ricottone.com:127.0.0.1 \ - --publish 0.0.0.0:80:80 --publish 0.0.0.0:443:443 + --publish 0.0.0.0:80:80 --publish 0.0.0.0:443:443 --publish 0.0.0.0:8822:22 cleanup: $(PODMAN) rm --force $(HUTTESE_REDIS) >/dev/null 2>&1 || true @@ -51,10 +54,6 @@ setup: pod $(PODMAN) run --detach --name $(HUTTESE_REDIS) --restart always \ --pod podracing \ $(REDIS_LOCALNAME) - #if I need persistence later: - # --mount type=bind,src=$(REDIS_DATADIR),dst=/data \ - # $(REDIS_LOCALNAME) redis-server --save 60 1 --loglevel warning - # redis is now available at redis://localhost:6379 $(PODMAN) inspect $(POSTGRES_LOCALNAME) >/dev/null 2>&1 \ || $(PODMAN) pull $(POSTGRES_TARGET) \ @@ -65,7 +64,6 @@ setup: pod --mount type=bind,src=$(POSTGRES_DATADIR),dst=/var/lib/postgresql/data,Z \ --mount type=bind,src=$(POSTGRES_CONF),dst=/etc/postgresql/postgresql.conf,Z \ $(POSTGRES_LOCALNAME) -c 'config_file=/etc/postgresql/postgresql.conf' - # postgres is now available at postgresql://postgres@localhost:5432 image: # these are only necessary if on aarch64 @@ -145,8 +143,17 @@ adduser: $(PODMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 $(PODMAN) inspect -f '{{.State.Running}}' $(HUTTESE_REDIS) >/dev/null 2>&1 - @echo "USAGE: USER_EMAIL=me@example.com USER_NAME=me make adduser" - $(PODMAN) exec -it $(HUTTESE_SRHT) metasrht-manageuser -e $(USER_EMAIL) -t admin $(USER_NAME) + $(PODMAN) exec -it $(HUTTESE_SRHT) metasrht-manageuser -e $(USER_EMAIL) -t active_free $(USER_NAME) \ + || echo "USAGE: USER_EMAIL=me@example.com USER_NAME=me make adduser" + +USER_EMAIL?= +USER_NAME?= +addadmin: + $(PODMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 + $(PODMAN) inspect -f '{{.State.Running}}' $(HUTTESE_REDIS) >/dev/null 2>&1 + + $(PODMAN) exec -it $(HUTTESE_SRHT) metasrht-manageuser -e $(USER_EMAIL) -t admin $(USER_NAME) \ + || echo "USAGE: USER_EMAIL=me@example.com USER_NAME=me make adduser" shell: $(PODMAN) inspect -f '{{.State.Running}}' $(HUTTESE_POSTGRES) >/dev/null 2>&1 diff --git a/README.md b/README.md index bca0a04..9c1d0d1 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,13 @@ Sourcehut is only officially supported on x86 Alpine Linux. I say **challenge accepted**. This repo walks through the process of running Sourcehut within containers (either `docker` or `podman`, possibly other runtimes as well) and even on ARM processors. +See the [huttese-apk project](https://git.dominic-ricottone.com/~dricottone/huttese-apk). ## Usage +Locate all the `*.changeme` files and add your own information in place of my redacted information. + Select the recipes for your container runtime: `Makefile.docker` or `Makefile.podman`. `ln -s Makefile.selection Makefile` to get going from there. @@ -18,6 +21,9 @@ Note that hosting on an ARM machine will additionally require building the APKs. See huttese-apk for more information. Run `make setup && make image && make dbinit && make start`. +Then `USER_NAME=admin USER_EMAIL=admin@example.com make addadmin` to setup an admin account. +Consider also `USER_NAME=me USER_EMAIL=me@example.com make adduser` to setup non-admin accounts. +Then `make shell` and `passwd git` to enable SSH access to git. For subsequent use, run `make image && make dbmigrate && make start`. @@ -31,14 +37,21 @@ If you even want to throw out the postgres database, try `sudo rm -f pg/datadir` ## To-Do -Copy some notable improvements from podman process to docker process. +There are cron jobs involved with administration: + + `gitsrht-periodic` runs `git gc` to save storage + + it also syncs S3 storage, which does not matter here + + `metasrht-daily` expires audit logs to save storage + + it also processes payments for billing, which does not matter here +I should look into options for running these from the host system. + +`lists.sr.ht` will require handling inbound mail, which seems like a whole lot of not fun, but could be managed. -For podman process, add cron jobs as systemd timers on the host system. +`builds.sr.ht` requires virtualization by way of qemu running inside a Docker container. Not really within scope of this project. -Need to figure out how to secure pgp keys, worker private key, network private key, and webhook private key. -Currently just manually cutting from commits. -Consider a `configure` script to manage the selection of `Makefile.*`, `Dockerfile.*`. +## License -Consider `lists.sr.ht`, `builds.sr.ht`. +I am supporting this infrastructure only to the ends of maintaining my own deployment. +Good luck. +I license everything under BSD 0 clause, except for subrepositories where a different license is specified. diff --git a/sr/Dockerfile.aarch64 b/sr/Dockerfile.aarch64 index 62a030b..6ca8802 100644 --- a/sr/Dockerfile.aarch64 +++ b/sr/Dockerfile.aarch64 @@ -1,47 +1,42 @@ FROM alpine:3.15 -COPY etc/apk/repositories.aarch64 /etc/apk/repositories + +# apk COPY pkg /var/huttese-apk -COPY etc/apk/keys/me@dominic-ricottone.com.rsa.pub /etc/apk/keys/me@dominic-ricottone.com.rsa.pub -RUN apk update -RUN apk add postfix meta.sr.ht git.sr.ht todo.sr.ht supervisor nginx fcgiwrap spawn-fcgi py3-gunicorn +COPY etc/apk/repositories.aarch64 /etc/apk/repositories +COPY etc/apk/keys/*.rsa.pub /etc/apk/keys/ +RUN apk add --no-cache postfix meta.sr.ht git.sr.ht todo.sr.ht supervisor nginx fcgiwrap spawn-fcgi git-daemon py3-gunicorn openssh -# setup directories -RUN mkdir /etc/postfix/sasl && chmod 700 /etc/postfix/sasl +# supervisor RUN mkdir /var/log/supervisord -# setup nginx -COPY etc/nginx/nginx.conf /etc/nginx/nginx.conf -COPY etc/nginx/graphql.conf /etc/nginx/graphql.conf -COPY etc/nginx/headers.conf /etc/nginx/headers.conf -COPY etc/nginx/web.conf /etc/nginx/web.conf -COPY etc/nginx/http.d/test.conf /etc/nginx/http.d/test.conf +# nginx +COPY etc/nginx/*.conf /etc/nginx/ +COPY etc/nginx/http.d/*.conf /etc/nginx/http.d/ COPY --chown=nginx:nginx usr/share/nginx/html/index.html /usr/share/nginx/html/index.html -COPY --chown=nginx:nginx usr/share/nginx/html/test.cgi /usr/share/nginx/html/test.cgi -COPY --chown=nginx:nginx usr/share/nginx/html/test.php /usr/share/nginx/html/test.php -COPY etc/nginx/http.d/default.conf /etc/nginx/http.d/default.conf -COPY etc/nginx/http.d/git.conf /etc/nginx/http.d/git.conf -#COPY etc/nginx/http.d/lists.conf /etc/nginx/http.d/lists.conf -COPY etc/nginx/http.d/meta.conf /etc/nginx/http.d/meta.conf -COPY etc/nginx/http.d/todo.conf /etc/nginx/http.d/todo.conf - -# setup postfix -COPY etc/postfix/main.cf /etc/postfix/main.cf -COPY etc/postfix/master.cf /etc/postfix/master.cf -COPY etc/postfix/transport /etc/postfix/transport -RUN postmap /etc/postfix/transport -COPY etc/postfix/generic /etc/postfix/generic -RUN postmap /etc/postfix/generic + +# postfix +RUN mkdir /etc/postfix/sasl && chmod 700 /etc/postfix/sasl +COPY etc/postfix/main.cf etc/postfix/master.cf etc/postfix/transport etc/postfix/generic /etc/postfix/ COPY etc/postfix/sasl/sasl_passwd /etc/postfix/sasl/sasl_passwd -RUN postmap /etc/postfix/sasl/sasl_passwd +RUN postmap /etc/postfix/transport \ + && postmap /etc/postfix/generic \ + && postmap /etc/postfix/sasl/sasl_passwd + +# sshd +COPY etc/ssh/* /etc/ssh/ +RUN touch /var/log/gitsrht-shell && chmod 666 /var/log/gitsrht-shell \ + && touch /var/log/gitsrht-update-hook && chmod 666 /var/log/gitsrht-update-hook \ + && chmod 600 /etc/ssh/*_key \ + && chmod 644 /etc/ssh/*_key.pub -# setup sourcehut +# sourcehut VOLUME /var/lib/git -COPY etc/sr.ht/config.ini /etc/sr.ht/config.ini -COPY etc/sr.ht/pgp.key /etc/sr.ht/pgp.key -COPY etc/sr.ht/pgp.pubkey /etc/sr.ht/pgp.pubkey +RUN chown git:git /var/lib/git +COPY etc/sr.ht/config.ini etc/sr.ht/pgp.key etc/sr.ht/pgp.pubkey /etc/sr.ht/ -# setup supervisor +# run USER root +EXPOSE 22 EXPOSE 80 EXPOSE 443 COPY etc/supervisor/conf.d/supervisord.conf /etc/supervisor/conf.d/supervisord.conf diff --git a/sr/Dockerfile.x86 b/sr/Dockerfile.x86 index 78d7c87..c9b4737 100644 --- a/sr/Dockerfile.x86 +++ b/sr/Dockerfile.x86 @@ -1,46 +1,41 @@ FROM alpine:3.15 + +# apk COPY etc/apk/repositories.x86 /etc/apk/repositories RUN wget --quiet --output-document=/etc/apk/keys/alpine@sr.ht.rsa.pub https://mirror.sr.ht/alpine/alpine@sr.ht.rsa.pub -RUN apk update -RUN apk add postfix meta.sr.ht git.sr.ht todo.sr.ht supervisor nginx fcgiwrap spawn-fcgi py3-gunicorn +RUN apk add --no-cache postfix meta.sr.ht git.sr.ht todo.sr.ht supervisor nginx fcgiwrap spawn-fcgi git-daemon py3-gunicorn openssh -# setup directories -RUN mkdir /etc/postfix/sasl && chmod 700 /etc/postfix/sasl +# supervisor RUN mkdir /var/log/supervisord -# setup nginx -COPY etc/nginx/nginx.conf /etc/nginx/nginx.conf -COPY etc/nginx/graphql.conf /etc/nginx/graphql.conf -COPY etc/nginx/headers.conf /etc/nginx/headers.conf -COPY etc/nginx/web.conf /etc/nginx/web.conf -COPY etc/nginx/http.d/test.conf /etc/nginx/http.d/test.conf +# nginx +COPY etc/nginx/*.conf /etc/nginx/ +COPY etc/nginx/http.d/*.conf /etc/nginx/http.d/ COPY --chown=nginx:nginx usr/share/nginx/html/index.html /usr/share/nginx/html/index.html -COPY --chown=nginx:nginx usr/share/nginx/html/test.cgi /usr/share/nginx/html/test.cgi -COPY --chown=nginx:nginx usr/share/nginx/html/test.php /usr/share/nginx/html/test.php -COPY etc/nginx/http.d/default.conf /etc/nginx/http.d/default.conf -COPY etc/nginx/http.d/git.conf /etc/nginx/http.d/git.conf -#COPY etc/nginx/http.d/lists.conf /etc/nginx/http.d/lists.conf -COPY etc/nginx/http.d/meta.conf /etc/nginx/http.d/meta.conf -COPY etc/nginx/http.d/todo.conf /etc/nginx/http.d/todo.conf - -# setup postfix -COPY etc/postfix/main.cf /etc/postfix/main.cf -COPY etc/postfix/master.cf /etc/postfix/master.cf -COPY etc/postfix/transport /etc/postfix/transport -RUN postmap /etc/postfix/transport -COPY etc/postfix/generic /etc/postfix/generic -RUN postmap /etc/postfix/generic + +# postfix +RUN mkdir /etc/postfix/sasl && chmod 700 /etc/postfix/sasl +COPY etc/postfix/main.cf etc/postfix/master.cf etc/postfix/transport etc/postfix/generic /etc/postfix/ COPY etc/postfix/sasl/sasl_passwd /etc/postfix/sasl/sasl_passwd -RUN postmap /etc/postfix/sasl/sasl_passwd +RUN postmap /etc/postfix/transport \ + && postmap /etc/postfix/generic \ + && postmap /etc/postfix/sasl/sasl_passwd + +# sshd +COPY etc/ssh/* /etc/ssh/ +RUN touch /var/log/gitsrht-shell && chmod 666 /var/log/gitsrht-shell \ + && touch /var/log/gitsrht-update-hook && chmod 666 /var/log/gitsrht-update-hook \ + && chmod 600 /etc/ssh/*_key \ + && chmod 644 /etc/ssh/*_key.pub -# setup sourcehut +# sourcehut VOLUME /var/lib/git -COPY etc/sr.ht/config.ini /etc/sr.ht/config.ini -COPY etc/sr.ht/pgp.key /etc/sr.ht/pgp.key -COPY etc/sr.ht/pgp.pubkey /etc/sr.ht/pgp.pubkey +RUN chown git:git /var/lib/git +COPY etc/sr.ht/config.ini etc/sr.ht/pgp.key etc/sr.ht/pgp.pubkey /etc/sr.ht/ -# setup supervisor +# run USER root +EXPOSE 22 EXPOSE 80 EXPOSE 443 COPY etc/supervisor/conf.d/supervisord.conf /etc/supervisor/conf.d/supervisord.conf diff --git a/sr/etc/nginx/http.d/lists.conf b/sr/etc/nginx/http.d/lists.conf deleted file mode 100644 index d67f928..0000000 --- a/sr/etc/nginx/http.d/lists.conf +++ /dev/null @@ -1,61 +0,0 @@ -server { - listen 80; - server_name lists.dominic-ricottone.com; - - location / { - return 302 https://$server_name$request_uri; - } - - location ^~ /.well-known { - root /var/www; - } - - location = /robots.txt { - root /var/www; - } -} - -server { - listen 443 ssl http2; - gzip on; - gzip_types text/css text/html; - server_name lists.dominic-ricottone.com; - - ssl_certificate /var/lets-encrypt/inter.lets-encrypt.cert; - ssl_certificate_key /var/lets-encrypt/inter.lets-encrypt.key; - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; - ssl_prefer_server_ciphers on; - - client_max_body_size 100M; - - location / { - proxy_read_timeout 300s; - proxy_connect_timeout 75s; - proxy_pass http://localhost:5006; - include headers.conf; - add_header Content-Security-Policy "default-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'"; - include web.conf; - } - - location /query { - proxy_read_timeout 300s; - proxy_connect_timeout 75s; - proxy_pass http://localhost:5106; - include graphql.conf; - } - - location /static { - root /usr/lib/python3.9/site-packages/listssrht; - expires 30d; - } - - location ^~ /.well-known { - root /var/www; - } - - location = /robots.txt { - root /var/www; - } -} - diff --git a/sr/etc/nginx/http.d/test.conf b/sr/etc/nginx/http.d/test.conf index 64e0b22..4e35e1c 100644 --- a/sr/etc/nginx/http.d/test.conf +++ b/sr/etc/nginx/http.d/test.conf @@ -7,39 +7,6 @@ server { ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; ssl_prefer_server_ciphers on; server_name _; - root /usr/share/nginx/html; - - location ~ [^/]\.cgi(/|$) { - fastcgi_split_path_info ^(.+?\.cgi)(/.*)$; - if (!-f $document_root$fastcgi_script_name) { - return 404; - } - - fastcgi_param HTTP_PROXY ""; - - fastcgi_pass localhost:9000; - fastcgi_index index.php; - - include fastcgi_params; - - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - } - - location ~ [^/]\.php(/|$) { - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - if (!-f $document_root$fastcgi_script_name) { - return 404; - } - - fastcgi_param HTTP_PROXY ""; - - fastcgi_pass localhost:9000; - fastcgi_index index.php; - - include fastcgi_params; - - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - } } diff --git a/sr/etc/postfix/generic b/sr/etc/postfix/generic.changeme similarity index 100% rename from sr/etc/postfix/generic rename to sr/etc/postfix/generic.changeme diff --git a/sr/etc/postfix/sasl/sasl_passwd b/sr/etc/postfix/sasl/sasl_passwd.changeme similarity index 100% rename from sr/etc/postfix/sasl/sasl_passwd rename to sr/etc/postfix/sasl/sasl_passwd.changeme diff --git a/sr/etc/sr.ht/config.ini b/sr/etc/sr.ht/config.ini.changeme similarity index 92% rename from sr/etc/sr.ht/config.ini rename to sr/etc/sr.ht/config.ini.changeme index 2eb2e0c..0e7642e 100644 --- a/sr/etc/sr.ht/config.ini +++ b/sr/etc/sr.ht/config.ini.changeme @@ -3,7 +3,7 @@ site-name=tatooine site-info=https://dominic-ricottone.com site-blurb=hutt owner-name=Dominic Ricottone -owner-email=me@dominic-ricottone.com +owner-email=REDACTED global-domain=dominic-ricottone.com environment=production @@ -31,15 +31,15 @@ s3-secret-key= [mail] smtp-host=tatooine smtp-port=25 -smtp-from=hutt@tatooine +smtp-from=root@tatooine smtp-encryption=insecure smtp-auth=none smtp-user= smtp-password= # Email address to dump exceptions at? -error-to=root@tatooine -error-from=hutt@tatooine +error-to=REDACTED +error-from=root@tatooine pgp-privkey=/etc/sr.ht/pgp.key pgp-pubkey=/etc/sr.ht/pgp.pubkey @@ -57,9 +57,9 @@ debug-host=0.0.0.0 debug-port=5001 api-origin=http://git.dominic-ricottone.com:5101 # try: meta.localhost/oauth -oauth-client-id=CHANGEME -oauth-client-secret=CHANGEME -repos=/rar/lib/git/ +oauth-client-id=REDACTED +oauth-client-secret=REDACTED +repos=/var/lib/git/ post-update-script=/usr/bin/gitsrht-update-hook outgoing-domain=tatooine @@ -145,9 +145,9 @@ debug-host=0.0.0.0 debug-port=5003 api-origin=http://todo.dominic-ricottone.com:5103 # try: meta.localhost/oauth -oauth-client-id= -oauth-client-secret= -notify-from=hutt@tatooine +oauth-client-id=REDACTED +oauth-client-secret=REDACTED +notify-from=root@tatooine # SQLAlchemy connection string connection-string=postgresql://postgres@localhost:5432/todo.sr.ht?sslmode=disable diff --git a/sr/etc/sr.ht/lists.config.ini b/sr/etc/sr.ht/lists.config.ini deleted file mode 100644 index 28d61ac..0000000 --- a/sr/etc/sr.ht/lists.config.ini +++ /dev/null @@ -1,48 +0,0 @@ -[lists.sr.ht] -origin=http://localhost:5006 -# try: meta.localhost/oauth -oauth-client-id= -oauth-client-secret= -api-origin=http://localhost:5106 -posting-domain=lists.tatooine -allow-new-lists=no - -# debug host -debug-host=0.0.0.0 -debug-port=5006 - -# SQLAlchemy connection string -#connection-string=postgresql://postgres@huttpg:5432/lists.sr.ht -connection-string=postgresql://postgres@huttpg:5432/lists.sr.ht?sslmode=disable -migrate-on-upgrade=yes - -# Webhooks connection string -webhooks=redis://huttredis:6379/1 - -# Celery connection string -redis=redis://huttredis:6379/0 - -# Trusted upstream SMTP server generating Authentication-Results header fields -msgauth-server=tatooine - - -[lists.sr.ht::worker] -protocol=lmtp -sock=/tmp/lists.sr.ht-lmtp.sock -sock-group=postfix - -# Content types to reject? -reject-mimetypes=text/html - -# URL for rejection notice? -reject-url=https://man.sr.ht/lists.sr.ht/etiquette.md - - -[lists.sr.ht::api] -max-complexity=200 -max-duration=90s -internal-ipnet=127.0.0.0/8,::1/128,192.168.0.0/16,10.0.0.0/8 - - -[lists.sr.ht::redirects] - diff --git a/sr/etc/ssh/sshd_config b/sr/etc/ssh/sshd_config new file mode 100644 index 0000000..1eaf186 --- /dev/null +++ b/sr/etc/ssh/sshd_config @@ -0,0 +1,118 @@ +# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options override the +# default value. + +#Port 22 +#AddressFamily any +#ListenAddress 0.0.0.0 +#ListenAddress :: + +#HostKey /etc/ssh/ssh_host_rsa_key +#HostKey /etc/ssh/ssh_host_ecdsa_key +#HostKey /etc/ssh/ssh_host_ed25519_key + +# Ciphers and keying +#RekeyLimit default none + +# Logging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +#PermitRootLogin prohibit-password +#StrictModes yes +#MaxAuthTries 6 +#MaxSessions 10 + +#PubkeyAuthentication yes + +# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 +# but this is overridden so installations will only check .ssh/authorized_keys +AuthorizedKeysFile .ssh/authorized_keys + +#AuthorizedPrincipalsFile none + +AuthorizedKeysCommand /usr/bin/gitsrht-dispatch "%u" "%h" "%t" "%k" +AuthorizedKeysCommandUser root + +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +#PasswordAuthentication yes +#PermitEmptyPasswords no + +# Change to no to disable s/key passwords +#KbdInteractiveAuthentication yes + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +# Set this to 'yes' to enable PAM authentication, account processing, +# and session processing. If this is enabled, PAM authentication will +# be allowed through the KbdInteractiveAuthentication and +# PasswordAuthentication. Depending on your PAM configuration, +# PAM authentication via KbdInteractiveAuthentication may bypass +# the setting of "PermitRootLogin without-password". +# If you just want the PAM account and session checks to run without +# PAM authentication, then enable this but set PasswordAuthentication +# and KbdInteractiveAuthentication to 'no'. +#UsePAM no + +#AllowAgentForwarding yes +# Feel free to re-enable these if your use case requires them. +AllowTcpForwarding no +GatewayPorts no +X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PermitTTY yes +#PrintMotd yes +#PrintLastLog yes +#TCPKeepAlive yes +PermitUserEnvironment SRHT_* +#Compression delayed +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS no +#PidFile /run/sshd.pid +#MaxStartups 10:30:100 +#PermitTunnel no +#ChrootDirectory none +#VersionAddendum none + +# no default banner path +#Banner none + +# override default of no subsystems +Subsystem sftp /usr/lib/ssh/sftp-server + +# Example of overriding settings on a per-user basis +#Match User anoncvs +# X11Forwarding no +# AllowTcpForwarding no +# PermitTTY no +# ForceCommand cvs server + diff --git a/sr/etc/supervisor/conf.d/supervisord.conf b/sr/etc/supervisor/conf.d/supervisord.conf index bd570fd..c3877a9 100644 --- a/sr/etc/supervisor/conf.d/supervisord.conf +++ b/sr/etc/supervisor/conf.d/supervisord.conf @@ -18,7 +18,7 @@ redirect_stderr=true [program:spawn-fcgi] autorestart=true -command=spawn-fcgi -n -u nginx -p 9000 -- /usr/bin/fcgiwrap -f +command=spawn-fcgi -n -u git -p 9000 -- /usr/bin/fcgiwrap -f redirect_stderr=true [program:metasrht] @@ -42,6 +42,7 @@ user=meta [program:gitsrht] autorestart=true command=gunicorn gitsrht.app:app -b 127.0.0.1:5001 -c /etc/sr.ht/git.sr.ht.gunicorn.conf.py +environment=HOME=/var/lib/git redirect_stderr=true user=git @@ -86,4 +87,8 @@ autostart=true command=nginx -g 'daemon off;' redirect_stderr=true +[program:sshd] +autostart=true +command=/usr/sbin/sshd -D -e +redirect_stderr=true -- 2.45.2