diff --git a/README.md b/README.md index 8d691e1..de7d2d5 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,3 @@ # Home server configuration Available at [comfycamp.space](https://comfycamp.space). - -## Ports - -| Number | Protocol | Service | Public URL | -| --- | --- | --- | --- | -| 3000 | | Mastodon | [m.comfycamp.space](https://m.comfycamp.space) | -| 3001 | | Mastodon streaming | | -| 3002 | | Vaultwarden | | -| 3003 | | Minio console | | -| 3004 | | Forgejo | [git.comfycamp.space](https://git.comfycamp.space) | -| 3005 | | Synapse | | -| 3006 | | Comfycamp | [comfycamp.space](https://comfycamp.space) | -| 3478 | tcp/udp | Coturn | | -| 8022 | | Forgejo SSH | | -| 8448 | | Synapse/Haproxy | | -| 9000 | | Minio | | -| 49152 - 65535 | udp | Coturn | | diff --git a/roles/comfycamp/tasks/main.yml b/roles/comfycamp/tasks/main.yml index 758cf07..a5f08c6 100644 --- a/roles/comfycamp/tasks/main.yml +++ b/roles/comfycamp/tasks/main.yml @@ -22,6 +22,7 @@ env_file: /etc/comfycamp/.env networks: - name: postgresql + - name: haproxy ports: - 127.0.0.1:3006:4000 restart_policy: unless-stopped diff --git a/roles/forgejo/tasks/forgejo.yml b/roles/forgejo/tasks/forgejo.yml index de9a160..1e19cb1 100644 --- a/roles/forgejo/tasks/forgejo.yml +++ b/roles/forgejo/tasks/forgejo.yml @@ -26,6 +26,7 @@ - name: postgresql - name: redis-forgejo - name: minio + - name: haproxy volumes: - forgejo:/data - /etc/timezone:/etc/timezone:ro diff --git a/roles/haproxy/files/errors/400.http b/roles/haproxy/files/errors/400.http new file mode 100644 index 0000000..3751ac4 --- /dev/null +++ b/roles/haproxy/files/errors/400.http @@ -0,0 +1,8 @@ +HTTP/1.0 400 Bad request +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +

400 Bad request

+Your browser sent an invalid request. + diff --git a/roles/haproxy/files/errors/403.http b/roles/haproxy/files/errors/403.http new file mode 100644 index 0000000..55a1319 --- /dev/null +++ b/roles/haproxy/files/errors/403.http @@ -0,0 +1,8 @@ +HTTP/1.0 403 Forbidden +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +

403 Forbidden

+Request forbidden by administrative rules. + diff --git a/roles/haproxy/files/errors/408.http b/roles/haproxy/files/errors/408.http new file mode 100644 index 0000000..50aa9d4 --- /dev/null +++ b/roles/haproxy/files/errors/408.http @@ -0,0 +1,8 @@ +HTTP/1.0 408 Request Time-out +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +

408 Request Time-out

+Your browser didn't send a complete request in time. + diff --git a/roles/haproxy/files/errors/500.http b/roles/haproxy/files/errors/500.http new file mode 100644 index 0000000..bff85fa --- /dev/null +++ b/roles/haproxy/files/errors/500.http @@ -0,0 +1,8 @@ +HTTP/1.0 500 Internal Server Error +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +

500 Internal Server Error

+An internal server error occurred. + diff --git a/roles/haproxy/files/errors/502.http b/roles/haproxy/files/errors/502.http new file mode 100644 index 0000000..d493d63 --- /dev/null +++ b/roles/haproxy/files/errors/502.http @@ -0,0 +1,8 @@ +HTTP/1.0 502 Bad Gateway +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +

502 Bad Gateway

+The server returned an invalid or incomplete response. + diff --git a/roles/haproxy/files/errors/503.http b/roles/haproxy/files/errors/503.http new file mode 100644 index 0000000..d1be36e --- /dev/null +++ b/roles/haproxy/files/errors/503.http @@ -0,0 +1,8 @@ +HTTP/1.0 503 Service Unavailable +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +

503 Service Unavailable

+No server is available to handle this request. + diff --git a/roles/haproxy/files/errors/504.http b/roles/haproxy/files/errors/504.http new file mode 100644 index 0000000..555066b --- /dev/null +++ b/roles/haproxy/files/errors/504.http @@ -0,0 +1,8 @@ +HTTP/1.0 504 Gateway Time-out +Cache-Control: no-cache +Connection: close +Content-Type: text/html + +

504 Gateway Time-out

+The server didn't respond in time. + diff --git a/roles/haproxy/files/haproxy.cfg b/roles/haproxy/files/haproxy.cfg index 5a1248a..2a09d7a 100644 --- a/roles/haproxy/files/haproxy.cfg +++ b/roles/haproxy/files/haproxy.cfg @@ -1,16 +1,8 @@ global - log /dev/log local0 - log /dev/log local1 notice - chroot /var/lib/haproxy - stats socket /run/haproxy/admin.sock mode 660 level admin - stats timeout 30s + log /dev/stderr local0 + log /dev/stderr local1 notice user haproxy group haproxy - daemon - - # Default SSL material locations - ca-base /etc/ssl/certs - crt-base /etc/ssl/private # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 @@ -25,18 +17,18 @@ defaults timeout connect 5000 timeout client 50000 timeout server 50000 - errorfile 400 /etc/haproxy/errors/400.http - errorfile 403 /etc/haproxy/errors/403.http - errorfile 408 /etc/haproxy/errors/408.http - errorfile 500 /etc/haproxy/errors/500.http - errorfile 502 /etc/haproxy/errors/502.http - errorfile 503 /etc/haproxy/errors/503.http - errorfile 504 /etc/haproxy/errors/504.http + errorfile 400 /usr/local/etc/haproxy/errors/400.http + errorfile 403 /usr/local/etc/haproxy/errors/403.http + errorfile 408 /usr/local/etc/haproxy/errors/408.http + errorfile 500 /usr/local/etc/haproxy/errors/500.http + errorfile 502 /usr/local/etc/haproxy/errors/502.http + errorfile 503 /usr/local/etc/haproxy/errors/503.http + errorfile 504 /usr/local/etc/haproxy/errors/504.http frontend www mode http bind :80 - bind :443 ssl crt /etc/haproxy/certs + bind :443 ssl crt /usr/local/etc/haproxy/certs http-request redirect scheme https unless { ssl_fc } http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Proto http if !{ ssl_fc } @@ -62,7 +54,7 @@ frontend www use_backend forgejo if acl_git frontend matrix-federation - bind *:8448 ssl crt /etc/haproxy/certs + bind *:8448 ssl crt /usr/local/etc/haproxy/certs http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Proto http if !{ ssl_fc } @@ -70,42 +62,42 @@ frontend matrix-federation backend comfycamp mode http - server green 127.0.0.1:3006 check + server green comfycamp:4000 check backend mastodon mode http option forwardfor - server green 127.0.0.1:3000 check + server green mastodon-web:3000 check backend mastodon_streaming mode http option forwardfor option http-server-close timeout tunnel 1h - server green 127.0.0.1:3001 check + server green mastodon-streaming:4000 check backend vaultwarden mode http option forwardfor - server green 127.0.0.1:3002 check + server green vaultwarden:80 check backend minio_console mode http option forwardfor - server green 127.0.0.1:3003 check + server green minio:9001 check backend minio mode http http-response set-header Access-Control-Allow-Origin https://m.comfycamp.space option forwardfor - server green 127.0.0.1:9000 check + server green minio:9000 check backend forgejo mode http option forwardfor - server green 127.0.0.1:3004 check + server green forgejo:3000 check backend matrix mode http option forwardfor - server matrix 127.0.0.1:3005 + server matrix synapse:8008 diff --git a/roles/haproxy/tasks/main.yml b/roles/haproxy/tasks/main.yml index 19812b2..5c40ca4 100644 --- a/roles/haproxy/tasks/main.yml +++ b/roles/haproxy/tasks/main.yml @@ -1,18 +1,69 @@ --- -- name: Install haproxy +- name: Create haproxy docker network become: true - ansible.builtin.apt: + community.docker.docker_network: name: haproxy +- name: Create haproxy dirs + become: true + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: "1755" + owner: root + group: root + loop: + - /etc/haproxy + - /etc/haproxy/errors +- name: Copy haproxy config to a temporary location + become: true + ansible.builtin.copy: + src: haproxy.cfg + dest: /tmp/haproxy.cfg +- name: Validate haproxy config + become: true + community.docker.docker_container: + name: haproxy-config-test + image: "{{ haproxy_image }}" + command: haproxy -c -f /tmp/haproxy.cfg + networks: + - name: haproxy + volumes: + - /tmp/haproxy.cfg:/tmp/haproxy.cfg + - /etc/haproxy/certs:/usr/local/etc/haproxy/certs:ro + detach: no +- name: Remove temporary container + become: true + community.docker.docker_container: + name: haproxy-config-test + state: absent - name: Copy haproxy config become: true ansible.builtin.copy: src: haproxy.cfg dest: /etc/haproxy/haproxy.cfg - validate: /usr/sbin/haproxy -f %s -c register: haproxy +- name: Copy errors + become: true + ansible.builtin.copy: + src: errors/{{ item }}.http + dest: /etc/haproxy/errors/{{ item }}.http + loop: [400, 403, 408, 500, 502, 503, 504] +- name: Create haproxy container + become: true + community.docker.docker_container: + name: haproxy + image: "{{ haproxy_image }}" + networks: + - name: haproxy + volumes: + - /etc/haproxy:/usr/local/etc/haproxy:ro + sysctls: + net.ipv4.ip_unprivileged_port_start: 0 + ports: + - 80:80 + - 443:443 + restart_policy: unless-stopped - name: Reload haproxy become: true when: haproxy.changed - ansible.builtin.systemd_service: - name: haproxy - state: reloaded + ansible.builtin.shell: docker kill -s HUP haproxy diff --git a/roles/haproxy/vars/main.yml b/roles/haproxy/vars/main.yml new file mode 100644 index 0000000..8f7b033 --- /dev/null +++ b/roles/haproxy/vars/main.yml @@ -0,0 +1 @@ +haproxy_image: haproxy:3.0-bookworm diff --git a/roles/mastodon/tasks/mastodon.yml b/roles/mastodon/tasks/mastodon.yml index 516fbad..415c8de 100644 --- a/roles/mastodon/tasks/mastodon.yml +++ b/roles/mastodon/tasks/mastodon.yml @@ -30,6 +30,7 @@ - name: redis-mastodon - name: postgresql - name: minio + - name: haproxy ports: - 127.0.0.1:3000:3000 volumes: @@ -45,6 +46,7 @@ networks: - name: redis-mastodon - name: postgresql + - name: haproxy ports: - 127.0.0.1:3001:4000 restart_policy: unless-stopped diff --git a/roles/minio/tasks/main.yml b/roles/minio/tasks/main.yml index bc16b14..aedc85c 100644 --- a/roles/minio/tasks/main.yml +++ b/roles/minio/tasks/main.yml @@ -15,6 +15,7 @@ command: ["minio", "server", "--console-address", ":9001"] networks: - name: minio + - name: haproxy volumes: - minio:/data ports: diff --git a/roles/synapse/tasks/synapse.yml b/roles/synapse/tasks/synapse.yml index e832032..f27fc24 100644 --- a/roles/synapse/tasks/synapse.yml +++ b/roles/synapse/tasks/synapse.yml @@ -41,6 +41,7 @@ SYNAPSE_CONFIG_PATH: /etc/synapse/homeserver.yaml networks: - name: postgresql + - name: haproxy ports: - 127.0.0.1:3005:8008/tcp restart_policy: unless-stopped diff --git a/roles/tls/tasks/main.yml b/roles/tls/tasks/main.yml index fe5d333..6394cfb 100644 --- a/roles/tls/tasks/main.yml +++ b/roles/tls/tasks/main.yml @@ -32,7 +32,9 @@ ansible.builtin.file: path: /etc/haproxy/certs state: directory - mode: '1750' + mode: '1700' + owner: "99" + group: "99" - name: Combine certificate and private key become: true ansible.builtin.shell: diff --git a/roles/vaultwarden/tasks/main.yml b/roles/vaultwarden/tasks/main.yml index a289b05..2d3a1c2 100644 --- a/roles/vaultwarden/tasks/main.yml +++ b/roles/vaultwarden/tasks/main.yml @@ -14,6 +14,7 @@ DATABASE_URL: "{{ db_url }}" networks: - name: postgresql + - name: haproxy ports: - 127.0.0.1:3002:80 volumes: