~dricottone/huttese

5ed93cbaa88262498220562cb4be640cf7d72617 — Dominic Ricottone 2 years ago 0ae257c
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.
15 files changed, 291 insertions(+), 261 deletions(-)

M .gitignore
A LICENSE.md
M Makefile.docker
M Makefile.podman
M README.md
M sr/Dockerfile.aarch64
M sr/Dockerfile.x86
D sr/etc/nginx/http.d/lists.conf
M sr/etc/nginx/http.d/test.conf
R sr/etc/postfix/{generic => generic.changeme}
R sr/etc/postfix/sasl/{sasl_passwd => sasl_passwd.changeme}
R sr/etc/sr.ht/{config.ini => config.ini.changeme}
D sr/etc/sr.ht/lists.config.ini
A sr/etc/ssh/sshd_config
M sr/etc/supervisor/conf.d/supervisord.conf
M .gitignore => .gitignore +18 -1
@@ 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


A LICENSE.md => LICENSE.md +14 -0
@@ 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.


M Makefile.docker => Makefile.docker +37 -29
@@ 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

M Makefile.podman => Makefile.podman +15 -8
@@ 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

M README.md => README.md +19 -6
@@ 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.


M sr/Dockerfile.aarch64 => sr/Dockerfile.aarch64 +28 -33
@@ 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

M sr/Dockerfile.x86 => sr/Dockerfile.x86 +26 -31
@@ 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

D sr/etc/nginx/http.d/lists.conf => sr/etc/nginx/http.d/lists.conf +0 -61
@@ 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;
	}
}


M sr/etc/nginx/http.d/test.conf => sr/etc/nginx/http.d/test.conf +0 -33
@@ 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;
	}
}


R sr/etc/postfix/generic => sr/etc/postfix/generic.changeme +0 -0
R sr/etc/postfix/sasl/sasl_passwd => sr/etc/postfix/sasl/sasl_passwd.changeme +0 -0
R sr/etc/sr.ht/config.ini => sr/etc/sr.ht/config.ini.changeme +10 -10
@@ 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

D sr/etc/sr.ht/lists.config.ini => sr/etc/sr.ht/lists.config.ini +0 -48
@@ 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]


A sr/etc/ssh/sshd_config => sr/etc/ssh/sshd_config +118 -0
@@ 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


M sr/etc/supervisor/conf.d/supervisord.conf => sr/etc/supervisor/conf.d/supervisord.conf +6 -1
@@ 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