commit 12941cd2c5d151fa92152183f60bb45cba703f30 Author: rskntroot Date: Tue Mar 11 06:03:13 2025 +0000 init commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd89bd6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +mkdocs/site +traefik/log/*.log +traefik/log/*.gz +traefik/tls/*.json +.local diff --git a/README.md b/README.md new file mode 100644 index 0000000..6a2f60f --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# Headquarters + +Services + +- traefik as front end proxy, tls, and http3 +- traefik dashboard behind mtls +- squidfunk/mkdocs-material to build static html +- nginx to host static html +- jellyfin for streaming service + +## Setup + +``` bash +docker compose up -d +``` + +## Requirements + +### Traefik Logging + +expects `/var/log/traefik` to exist + +``` bash +sudo mkdir -p /var/log/traefik +``` + +### Rskio Website + +expects `../rskio/mkdocs` to exist + +``` bash +git clone https://github.com/rskntroot/rskio.git +``` + +### Jellyfin + +expects `/mnt/jellyfin` and `/mnt/media` to exist + +#### setup creds + +``` bash +sudo mkdir -p /etc/smb/creds +sudo vi /etc/smb/creds/share +sudo chmod 600 /etc/smb/creds/share +``` + +create creds files in the format + +``` +username= +password= +``` + +#### edit fstab + +``` zsh +vi /etc/fstab +``` + +``` fstab +//192.168.1.179/Media /mnt/media cifs credentials=/etc/smb/creds/media,iocharset=utf8,vers=3.0,uid=1000,gid=1000,file_mode=0660,dir_mode=0770 0 0 +//192.168.1.179/Jellyfin /mnt/jellyfin cifs credentials=/etc/smb/creds/jellyfin,iocharset=utf8,vers=3.0,uid=1000,gid=1000,file_mode=0660,dir_mode=0770 0 0 +``` diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..d49f863 --- /dev/null +++ b/compose.yml @@ -0,0 +1,65 @@ +services: + mkdocs: + image: squidfunk/mkdocs-material + command: + - build + volumes: + - ./mkdocs:/docs + + traefik: + image: traefik:latest + command: + - --configFile=/etc/traefik/traefik.yml + ports: + - 80:80/tcp + - 443:443/tcp + - 443:443/udp + - 8080:8080/tcp + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - /var/log/traefik:/var/log/traefik + - ./traefik/etc:/etc/traefik:ro + - ./traefik/tls:/letsencrypt + + nginx: + image: nginx:latest + restart: unless-stopped + labels: + - traefik.enable=true + - traefik.http.routers.rskio.entrypoints=websecure + - traefik.http.routers.rskio.rule=Host(`docs.rskio.com`) + - traefik.http.routers.rskio.tls=true + - traefik.http.routers.rskio.tls.options=docs@file + - traefik.http.routers.rskio.tls.certresolver=rskio_certresolver + - traefik.http.routers.rskio.service=rskio@docker + - traefik.http.services.rskio.loadbalancer.server.port=80 + - traefik.http.routers.rskio.middlewares=secureHeaders@file + volumes: + - ./mkdocs/site:/opt/share/mkdocs/html:ro + - ./nginx/etc/conf.d:/etc/nginx/conf.d:ro + depends_on: + mkdocs: + condition: service_completed_successfully + + stream: + image: jellyfin/jellyfin + labels: + - traefik.enable=true + - traefik.http.routers.stream.entrypoints=websecure + - traefik.http.routers.stream.rule=Host(`stream.rskio.com`) + - traefik.http.routers.stream.tls=true + - traefik.http.routers.stream.tls.certresolver=rskio_certresolver + - traefik.http.routers.stream.service=stream@docker + - traefik.http.services.stream.loadbalancer.server.port=8096 + tty: true + restart: unless-stopped + devices: + - /dev/dri:/dev/dri + volumes: + - ./jellyfin/config:/config + - ./jellyfin/cache:/cache + - /mnt/media:/data + ports: + - 8096:8096 + environment: + - TZ=US/Mountain diff --git a/jellyfin b/jellyfin new file mode 120000 index 0000000..1f76c12 --- /dev/null +++ b/jellyfin @@ -0,0 +1 @@ +/mnt/jellyfin \ No newline at end of file diff --git a/mkdocs b/mkdocs new file mode 120000 index 0000000..07a87cc --- /dev/null +++ b/mkdocs @@ -0,0 +1 @@ +../rskio/mkdocs \ No newline at end of file diff --git a/nginx/etc/conf.d/default.conf b/nginx/etc/conf.d/default.conf new file mode 100644 index 0000000..7ad5114 --- /dev/null +++ b/nginx/etc/conf.d/default.conf @@ -0,0 +1,31 @@ +server { + listen 80; + listen [::]:80; + server_name rskio.com; + + server_tokens off; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; + add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; + add_header X-XSS-Protection "1; mode=block"; + + # rskio logging is handled via traefik + #access_log /var/log/nginx/host.access.log main; + + location / { + root /opt/share/mkdocs/html; + index index.html index.htm; + limit_except GET HEAD POST { deny all; } + } + + # rskio auth is handled via traefik + #error_page 404 /404.html; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + limit_except GET HEAD POST { deny all; } + } +} + diff --git a/rskio.service b/rskio.service new file mode 100644 index 0000000..5e5171c --- /dev/null +++ b/rskio.service @@ -0,0 +1,14 @@ +[Unit] +Description=Rskio Website +After=docker.service +Requires=docker.service + +[Service] +Type=oneshot +RemainAfterExit=yes +WorkingDirectory=/opt/docker/rskio +ExecStart=/bin/bash -c "docker compose -f ./compose.yml up -d" +ExecStop=/bin/bash -c "docker compose -f ./compose.yml down" + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/traefik/etc/com.rskio.ca.crt b/traefik/etc/com.rskio.ca.crt new file mode 100644 index 0000000..9528f52 --- /dev/null +++ b/traefik/etc/com.rskio.ca.crt @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIF/zCCA+egAwIBAgIUUiRAdfNY8+cPZkIoKgYmCaHwb6wwDQYJKoZIhvcNAQEL +BQAwgY0xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhDb2xvcmFkbzEPMA0GA1UEBwwG +RGVudmVyMRIwEAYDVQQKDAlSc2tpbyBMdGQxFDASBgNVBAsMC0RldmVsb3BtZW50 +MREwDwYDVQQDDAhyc2tpby1jYTEdMBsGCSqGSIb3DQEJARYObG9zdEByc2tpby5j +b20wIBcNMjUwMzA0MDc0NDQwWhgPMjA1MjA3MjAwNzQ0NDBaMIGNMQswCQYDVQQG +EwJVUzERMA8GA1UECAwIQ29sb3JhZG8xDzANBgNVBAcMBkRlbnZlcjESMBAGA1UE +CgwJUnNraW8gTHRkMRQwEgYDVQQLDAtEZXZlbG9wbWVudDERMA8GA1UEAwwIcnNr +aW8tY2ExHTAbBgkqhkiG9w0BCQEWDmxvc3RAcnNraW8uY29tMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEArCrI30KsrX1fywvJt3klEZXmOZaFFIl+p86c +DC80HpBQ4YRlkWrXYor5jVPNNZMSAx9Vcu8DVqRjysHtRpajgQtNdWrpmbqH/F1r +gcdHciedTJqxnE3JAA95hVJYewWsvInUzcgmsvYehEUGnYvFeN+rxfDBMiUDFcav +r+FyNk51PTUb+zRdGwwrLvBN86Kc8oyjK7T8q8c10BHD0ESDOY4SeRU0ap0VpsVN +EaGfuO5+eHqUMXj5OvoI8mzjPVZ/ELLDlFRxQVZAzcLRAXIHzIXlt2ROl5dypXyE +l++0kVZBBk0qVLk95r8w+sYzaMH5zPUp4UFQjLFSSgyCpWpzwWrbyOdvDzcVJ3As +8A/8lqSThbCIbHLXllqQO0Oi3oSZQm/Crn3aQw5kOUwYEyJvnlSXXMcvkHVQgLv/ +Uhl0OlQfSjwIEzL0Ezti/9kmAVHUvxBbEWu2zq5g8/3zzaVU6FX9EdPNsVTTk9Qw +RxslLWWtUtlkhtOjD6EoruboFDxlTC7sfTrWsUF9+5O11xbowmvHPycs2QE8fn13 +paYmMLMq4XNtjErKKlYUh12/Ysca91FwUX6+JQtygzrwf0kX1ZY5oW+QpjnRAL+q ++7JD+uP14VrsJTN781e615icI0RcMvpyfnf2za6TZR8U0bov224M+kdgaAKae2jb +h/cjLVsCAwEAAaNTMFEwHQYDVR0OBBYEFL5x8cKfmeYPZ/bcm4p6xfCWwwVHMB8G +A1UdIwQYMBaAFL5x8cKfmeYPZ/bcm4p6xfCWwwVHMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggIBAATyoT95B5MiXmbt6PW00Gkn16RBLORTFJ6CrRB8 +J03bSYUk8H4xyT9C4jvi+HDQD66zPaMmMwoy5sSx0XUdNa+wZNTztUaKiDa9XPyU +osztloZgH6heheyls4TCexHDmVjwPndYXLDg9X8gUIdw2hFYcjrtyRFeUuDIvQ8b +XVrTAZ3iaPWsPYEV+PvY3EaSbTLJWmTEIbYEbx3XGIkSSsYTEqJqWaMkxlHxTJK+ +mruk7mqGeCNgyrbX7jvyxqF+U0lWG2dgw+2z70+c4uOfA3hVAcZDQAXHT1DOdDde +WnZ1g0WH/VktF61ldd7F34ljBfVsGTvfem/gwHdjplf8eavw6L8f4bV1UbM3j7TM +rtaNN4+Gb+1gmBMzkHpQFMF1jQifrDEhytnpRd6CP0rtzYjg6IwcRdeTTQtsI1y9 +hiEP+FRsZbj2QV7wNMfmCQG8/QAsrAVaAho6MmTlPoZaIXdiVBJPALBkfJUIUII4 +OqgAWF4uAqxQx1iUOkeq/+RQtUCMQol0k20UBA4rGQbw7WjCYhJq1DdCsYsCka6N +rUfTI5tZSM9bUNbCabsn56OWERx0KRjY4hTZqrlbjOpnAuOF0qqUcxLhgwgtLbWz +5eJz/ulkMtv/1woK0EqPHiDl4DqX1PIGNQFxTFJqvOC7a4Emokij6VOiz96H7mqK +Oxh9 +-----END CERTIFICATE----- diff --git a/traefik/etc/dynamic.yml b/traefik/etc/dynamic.yml new file mode 100644 index 0000000..8db1821 --- /dev/null +++ b/traefik/etc/dynamic.yml @@ -0,0 +1,56 @@ +tls: + options: + docs: + minVersion: VersionTLS13 + cipherSuites: + - TLS_AES_256_GCM_SHA384 + - TLS_AES_128_GCM_SHA256 + - TLS_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_FALLBACK_SCSV + dashboard: + minVersion: VersionTLS13 + cipherSuites: + - TLS_AES_256_GCM_SHA384 + - TLS_AES_128_GCM_SHA256 + - TLS_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_FALLBACK_SCSV + clientAuth: + caFiles: + - /etc/traefik/com.rskio.ca.crt + clientAuthType: RequireAndVerifyClientCert + +http: + routers: + traefik-dashboard: + rule: "Host(`oxy.rskio.com`)" + service: "api@internal" + entryPoints: + - "websecure" + middlewares: + - "redirect-dashboard" + tls: + options: dashboard@file + certResolver: rskio_certresolver + middlewares: + redirect-dashboard: + redirectRegex: + regex: "^https?://([^/]+)/?$" + replacement: "https://${1}/dashboard/" + permanent: true + secureHeaders: + headers: + browserXssFilter: true + contentTypeNosniff: true + forceSTSHeader: true + frameDeny: true + referrerPolicy: "same-origin" + sslRedirect: true + stsSeconds: 31536000 diff --git a/traefik/etc/traefik.yml b/traefik/etc/traefik.yml new file mode 100644 index 0000000..373e6ac --- /dev/null +++ b/traefik/etc/traefik.yml @@ -0,0 +1,44 @@ +global: + checkNewVersion: false + sendAnonymousUsage: false + +entryPoints: + web: + address: :80 + http: + redirections: + entryPoint: + to: websecure + priority: 10 + websecure: + address: :443 + http3: + advertisedPort: 443 + +certificatesResolvers: + rskio_certresolver: + acme: + tlsChallenge: {} + email: rskntroot@gmail.com + storage: /letsencrypt/acme.json + +log: + level: INFO + format: json + filePath: /var/log/traefik/traefik.log + +accessLog: + format: json + filePath: /var/log/traefik/access.log + +api: + dashboard: true + +providers: + docker: + endpoint: unix:///var/run/docker.sock + network: hq_default + exposedByDefault: false + file: + filename: /etc/traefik/dynamic.yml + watch: true diff --git a/traefik/log b/traefik/log new file mode 120000 index 0000000..a0abb9e --- /dev/null +++ b/traefik/log @@ -0,0 +1 @@ +/var/log/traefik/ \ No newline at end of file diff --git a/traefik/tls/.required.md b/traefik/tls/.required.md new file mode 100644 index 0000000..36b124d --- /dev/null +++ b/traefik/tls/.required.md @@ -0,0 +1,3 @@ +# Required + +this dir is required to enable traefik letsencrypt