Merge branch 'single-dockerfile' of https://github.com/osresearch/hackerspace-zone into single-dockerfile

single-dockerfile
Ubuntu 2 years ago
commit cdca84f06e
  1. 7
      Makefile
  2. 16
      README.md
  3. 69
      gitea.yaml
  4. 5
      gitea/README.md
  5. 46
      gitea/docker-compose.yaml
  6. 7
      gitea/env.production
  7. 0
      gitea/host-setup.sh
  8. 4
      gitea/keycloak.sh
  9. 14
      gitea/nginx.conf
  10. 69
      gitea/setup
  11. 36
      gitea/setup.sh
  12. 29
      wireguard/README.md
  13. 33
      wireguard/wg0-proxy.conf
  14. 28
      wireguard/wg0-server.conf

@ -7,6 +7,7 @@ MODULES += mastodon
MODULES += matrix
MODULES += nextcloud
MODULES += mobilizon
MODULES += gitea
#MODULES += pixelfed
include env.production
@ -68,6 +69,12 @@ data/%/secrets:
echo >>$@ "export $(GET_MODULE)_CLIENT_SECRET=$(call RAND,20)"
echo >>$@ "export $(GET_MODULE)_SESSION_SECRET=$(call RAND,20)"
data/gitea/secrets: data/gitea/host-setup.done
data/gitea/host-setup.done:
sudo ./gitea/host-setup.sh
mkdir -p $(dir $@)
touch $@
keycloak-setup: secrets-setup
docker exec keycloak /setup.sh

@ -4,17 +4,13 @@ Infrastructure for the self-hosted, single-sign-on, community-run services.
* Set the domain name in `env.production`
* Create the DNS entries in the domain for `login`, `cloud`, `matrix`, `dashboard`, `docs` and maybe more.
* Install dependencies:
* Install dependencies (note that `docker-compose 1.25` breaks environment variables as we use them):
```
apt install jq docker-compose
apt install prometheus
apt install python3-pip prometheus
pip3 install docker-compose
```
* Setup each of the services. `keycloak` and `nginx` are required to start the others:
```
./keycloak/setup
./nginx/setup
./start-all
```
* `make run` to startup all of the containers
* `make keycloak-setup` to setup all of the OIDC links
* `make down` to stop everything

@ -0,0 +1,69 @@
# gitea requires ssh access from the host machine, which needs special setup
# In order to create the git user and auth keys, you need to run:
#
# sudo gitea/setup.sh
#
version: "3"
services:
gitea:
image: gitea/gitea:1.17.3
container_name: gitea
env_file:
- ./env.production
environment:
- USER_UID=2222 # must match git user on host system
- USER_GID=2222
- GITEA_CLIENT_SECRET=${GITEA_CLIENT_SECRET}
- GITEA_ADMIN_PASSWORD=${GITEA_ADMIN_PASSWORD}
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=gitea-db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
- GITEA__oauth2_client__ENABLE_AUTO_REGISTRATION=true
- GITEA__openid__ENABLE_OPENID_SIGNIN=true
- GITEA__openid__ENABLE_OPENID_SIGNUP=false
- GITEA__service__DISABLE_REGISTRATION=true
- GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION=true
- GITEA__repository__DEFAULT_BRANCH=main
- GITEA__server__ROOT_URL=https://${GITEA_HOSTNAME}.${DOMAIN_NAME}/
- GITEA__server__SSH_DOMAIN=${GITEA_HOSTNAME}.${DOMAIN_NAME}
- GITEA__security__SECRET_KEY=${GITEA_SESSION_SECRET}
- GITEA__security__INSTALL_LOCK=true
entrypoint: ["/setup.sh"]
volumes:
- ./gitea/setup.sh:/setup.sh:ro
- ./data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /home/git/.ssh/:/data/git/.ssh
ports:
# - "3030:3000"
- "2222:22" # route host port 2222 to container port 22 for inbound ssh
restart: always
depends_on:
- gitea-db
gitea-db:
image: postgres:13.4-alpine
container_name: gitea-db
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea
volumes:
- ./data/gitea/postgres:/var/lib/postgresql/data
# add the gitea nginx configuration into the nginx volume
nginx:
volumes:
- ./gitea/nginx.conf:/etc/nginx/templates/gitea.conf.template:ro
# add the gitea client secrets to the keycloak-setup volume
keycloak-setup:
env_file:
- data/gitea/secrets
volumes:
- ./gitea/keycloak.sh:/keycloak-setup/gitea.sh:ro

@ -1,3 +1,6 @@
# gitea
OIDC setup is now automated
There is still a sudo step that has to happen on the host.
OIDC setup is now automated in the container.

@ -1,46 +0,0 @@
version: "3"
networks:
gitea:
external: false
services:
gitea:
image: gitea/gitea:1.16.6
env_file:
- ../env.production
- env.production
- ../data/gitea/env.secrets
environment:
- USER_UID=2222 # must match git user on host system
- USER_GID=2222
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
networks:
- gitea
volumes:
- ../data/gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- /home/git/.ssh/:/data/git/.ssh
ports:
- "3030:3000"
- "2222:22"
restart: always
depends_on:
- db
db:
image: postgres:13.4-alpine
restart: always
environment:
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
- POSTGRES_DB=gitea
volumes:
- ../data/gitea/postgres:/var/lib/postgresql/data
networks:
- gitea

@ -1,7 +0,0 @@
# gitea config for keycloak integration
# only allow open id sign-in, turn off all other registrations
GITEA__openid__ENABLE_OPENID_SIGNIN=true
GITEA__openid__ENABLE_OPENID_SIGNUP=false
#GITEA__service__DISABLE_REGISTRATION=true
GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION=true
GITEA__repository__DEFAULT_BRANCH=main

@ -0,0 +1,4 @@
#!/bin/bash -x
# Setup the gitea client connection
client-create gitea "$GITEA_HOSTNAME.$DOMAIN_NAME" "$GITEA_CLIENT_SECRET" </dev/null

@ -1,5 +1,5 @@
server {
server_name ${GITEA_HOSTNAME};
server_name ${GITEA_HOSTNAME} ${GITEA_HOSTNAME}.${DOMAIN_NAME};
client_max_body_size 128m;
sendfile on;
@ -14,17 +14,17 @@ server {
proxy_read_timeout 1800s;
location / {
proxy_pass http://host.docker.internal:3030;
proxy_pass http://gitea:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# force login with OIDC
location /user/login {
return 302 https://${GITEA_HOSTNAME}/user/oauth2/keycloak;
}
# force login with OIDC
location /user/login {
return 302 https://${GITEA_HOSTNAME}.${DOMAIN_NAME}/user/oauth2/keycloak;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem;
@ -33,5 +33,3 @@ server {
include /etc/nginx/includes/challenge.conf;
ssl_dhparam /etc/nginx/includes/ssl-dhparams.pem;
}

@ -1,69 +0,0 @@
#!/bin/bash
die() { echo >&2 "gitea: ERROR $*" ; exit 1 ; }
info() { echo >&2 "gitea: $*" ; }
DIRNAME="$(dirname $0)"
cd "$DIRNAME"
source ../env.production || die "no top level environment"
source ./env.production || die "no local environment"
DATA="../data/gitea"
SECRETS="$DATA/env.secrets"
INI="$DATA/gitea/conf/app.ini"
if [ -r "$SECRETS" ]; then
docker-compose up -d || die "unable to start"
exit 0
fi
./add-ssh-user || die "unable to add ssh user"
GITEA_CLIENT_SECRET="$(openssl rand -hex 32)"
GITEA_ADMIN_PASSWORD="$(openssl rand -hex 8)"
info "creating new secrets $SECRETS"
mkdir -p "$DATA"
cat <<EOF > "$SECRETS"
# DO NOT CHECK IN
GITEA_CLIENT_SECRET=$GITEA_CLIENT_SECRET
GITEA_ADMIN_PASSWORD=$GITEA_ADMIN_PASSWORD
GITEA__server__ROOT_URL=https://$GITEA_HOSTNAME/
GITEA__server__SSH_DOMAIN=$GITEA_HOSTNAME
GITEA__security__INSTALL_LOCK=true
GITEA__security__SECRET_KEY=$(openssl rand -hex 32)
EOF
docker-compose down 2>/dev/null
../keycloak/client-delete gitea 2>/dev/null
../keycloak/client-create <<EOF || die "unable to create gitea client"
{
"clientId": "gitea",
"rootUrl": "https://$GITEA_HOSTNAME",
"adminUrl": "https://$GITEA_HOSTNAME",
"redirectUris": [ "https://$GITEA_HOSTNAME/*" ],
"webOrigins": [ "https://$GITEA_HOSTNAME" ],
"clientAuthenticatorType": "client-secret",
"secret": "$GITEA_CLIENT_SECRET"
}
EOF
docker-compose up -d || die "unable to start container"
info "waiting for startup..."
sleep 5
info "adding oauth login"
docker-compose exec -u git gitea \
gitea admin auth add-oauth \
--name "keycloak" \
--provider "openidConnect" \
--key "gitea" \
--secret "$GITEA_CLIENT_SECRET" \
--auto-discover-url "https://${KEYCLOAK_HOSTNAME}/realms/${REALM}/.well-known/openid-configuration" \
--group-claim-name "groups" \
--admin-group "admin" \
|| die "unable to add oauth interface"

@ -0,0 +1,36 @@
#!/bin/bash -x
# This is *container* setup for the OIDC stuff
export APP_NAME="${DOMAIN_NAME} Gitea"
OIDC_CANARY="/data/oidc.done"
if [ -r "$OIDC_CANARY" ]; then
# based on https://github.com/go-gitea/gitea/blob/main/Dockerfile
exec "/usr/bin/entrypoint" "/bin/s6-svscan" "/etc/s6";
fi
# We have to do some setup, so start things and wait for the config
# file to appear so that we can edit it.
"/usr/bin/entrypoint" "/bin/s6-svscan" "/etc/s6" &
echo >&2 "*** Sleeping for setup"
sleep 30
echo >&2 "*** Adding OIDC login for $DOMAIN_NAME"
su -s /bin/sh git <<EOF || exit 1
gitea admin auth add-oauth \
--name "keycloak" \
--provider "openidConnect" \
--key "gitea" \
--secret "${GITEA_CLIENT_SECRET}" \
--auto-discover-url "https://${KEYCLOAK_HOSTNAME}.${DOMAIN_NAME}/realms/${REALM}/.well-known/openid-configuration" \
--group-claim-name "groups" \
--admin-group "admin" \
EOF
touch "${OIDC_CANARY}"
echo >&2 "*** Done, maybe it works?"
exit 0

@ -0,0 +1,29 @@
# Wireguard proxy setup
This is for a server that is inside of a firewall or behind a NAT gateway
that doesn't have a static IP address. A cheap $6/month DigitalOcean droplet
can be created that will route *all* internet traffic to the server, allowing
it to change IP.
* On both proxy and the server:
```
sudo apt install wireguard-tools net-tools
wg genkey \
| sudo tee /etc/wireguard/wg0.key \
| wg pubkey \
| sudo tee /etc/wireguard/wg0.pub
sudo chmod -R go-rwx /etc/wireguard
```
* Copy `wireguard/wg0-proxy.conf` to `/etc/wireguard/wg0.conf` on the proxy
* On the **proxy** edit `/etc/wireguard/wg0.conf`:
* Change `${SERVER_PUBKEY}` to the public key that was output on the server
* Copy `wireguard/wg0-server.conf` to `/etc/wireguard/wg0.conf` on the server.
* On the **server** edit `/etc/wireguard/wg0.conf`:
* Change `${PROXY_IP}` to the public IP address of the proxy (two places)
* Change `${PROXY_PUBKEY}` to the public key output on the proxy (two places)
* Change `${SERVER_GW}` to the gateway address used to reach the internet from the server
* On both machines run `sudo wg-quick up /etc/wireguard/wg0.conf`

@ -0,0 +1,33 @@
[Interface]
Address = 192.168.4.1/24
ListenPort = 51820
PostUp = wg set %i private-key /etc/wireguard/%i.key
# Enable IP masquerading for the remote host
PostUp = echo 1 > /proc/sys/net/ipv4/ip_forward
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -A FORWARD -o %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# accept the wireguard connection
PostUp = iptables -t nat -A PREROUTING -i eth0 -p udp --dport 51820 -j ACCEPT
# redirect ssh to port 23
PostUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 23 -j REDIRECT --to-port 22
# redirect *all* traffic to the wg tunnel
PostUp = iptables -t nat -A PREROUTING -i eth0 -p all -j DNAT --to-destination 192.168.4.2
# Tear down the proxy
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -o %i -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D PREROUTING -i eth0 -p udp --dport 51820 -j ACCEPT
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 23 -j REDIRECT -to-port 22
PostDown = iptables -t nat -D PREROUTING -i eth0 -p all -j DNAT --to-destination 192.168.4.2
[Peer]
PublicKey = ${SERVER_PUBKEY}
AllowedIPs = 192.168.4.2/32

@ -0,0 +1,28 @@
# wg0-server.conf
#
# This is the configuration for the server hidden behind the wireguard proxy.
# It routes all internet traffic via the proxy, with the exception of traffic
# to the proxy itself. It is still accessible on the local network.
#
# When moving this to a new machine:
# * Update the PostUp route so that the proxy address has an explicit route via the local gateway
# * Update the PownDown to delete the explicit route and restore the default gw
# * Update the Peer PublicKey and Endpoint with the proxy key and address
#
[Interface]
PostUp = wg set %i private-key /etc/wireguard/%i.key
Address = 192.168.4.2/24
# Delete the default gateway and add an explicit route for the wireguard tunnel
PostUp = route add ${PROXY_IP} gw ${SERVER_GW} || echo "wrong route"
PostUp = route del default || echo "no default"
PostUp = route add default gw 192.168.4.1
PostDown = route del ${PROXY_IP}
PostDown = route add default gw ${SERVER_GW}
[Peer]
PublicKey = ${PROXY_PUBKEY}
Endpoint = ${PROXY_IP}:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Loading…
Cancel
Save