diff --git a/backend/dev_homeserver-othersite.yaml b/backend/dev_homeserver-othersite.yaml new file mode 100644 index 00000000..12c9d1ad --- /dev/null +++ b/backend/dev_homeserver-othersite.yaml @@ -0,0 +1,65 @@ +server_name: "synapse.othersite.m.localhost" +public_baseurl: https://synapse.othersite.m.localhost/ + +pid_file: /data/homeserver.pid + +listeners: + - port: 18008 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation, openid] + compress: false + +database: + name: sqlite3 + args: + database: /data/homeserver.db + +media_store_path: /data/media_store +signing_key_path: "/data/SERVERNAME.signing.key" + +# Due to custom TLS certificate with domains +# - m.localhost, localhost +# - *.m.localhost +# - *.othersite.m.localhost +# we disable certificate verification to allow for federation +# WARNING: DO NOT USE IN PRODUCTION!!! +federation_verify_certificates: false +ip_range_blacklist: [] +trusted_key_servers: + - server_name: "synapse.m.localhost" + accept_keys_insecurely: true + +experimental_features: + # MSC3266: Room summary API. Used for knocking over federation + msc3266_enabled: true + # MSC4222 needed for syncv2 state_after. This allow clients to + # correctly track the state of the room. + msc4222_enabled: true + +# The maximum allowed duration by which sent events can be delayed, as +# per MSC4140. Must be a positive value if set. Defaults to no +# duration (null), which disallows sending delayed events. +max_event_delay_duration: 24h + +# Required for Element Call in Single Page Mode due to on-the-fly user registration +enable_registration: true +enable_registration_without_verification: true + +report_stats: false +serve_server_wellknown: true + +# Ratelimiting settings for client actions (registration, login, messaging). +# +# Each ratelimiting configuration is made of two parameters: +# - per_second: number of requests a client can send per second. +# - burst_count: number of requests a client can send before being throttled. + +rc_message: + # This needs to match at least the heart-beat frequency plus a bit of headroom + # Currently the heart-beat is every 5 seconds which translates into a rate of 0.2s + per_second: 0.5 + burst_count: 30 + diff --git a/backend/dev_livekit-othersite.yaml b/backend/dev_livekit-othersite.yaml new file mode 100644 index 00000000..0ae98c24 --- /dev/null +++ b/backend/dev_livekit-othersite.yaml @@ -0,0 +1,20 @@ +port: 17880 +bind_addresses: + - "0.0.0.0" +rtc: + tcp_port: 17881 + port_range_start: 50300 + port_range_end: 50400 + use_external_ip: false +turn: + enabled: false + domain: localhost + cert_file: "" + key_file: "" + tls_port: 5349 + udp_port: 443 + external_tls: true +keys: + devkey: secret +room: + auto_create: false diff --git a/backend/dev_nginx.conf b/backend/dev_nginx.conf index aadb612c..be015060 100644 --- a/backend/dev_nginx.conf +++ b/backend/dev_nginx.conf @@ -1,4 +1,5 @@ # Synapse reverse proxy including .well-known/matrix/client +# domain synapse.m.localhost server { listen 80; listen [::]:80; @@ -26,14 +27,53 @@ server { # This is also required for development environment. # Reason: the lk-jwt-service uses the federation API for the openid token # verification, which requires TLS - location / { - proxy_pass "http://homeserver:8008"; + location ~ ^(/_matrix|/_synapse/client) { + proxy_pass "http://homeserver:8008"; proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + } + + error_page 500 502 503 504 /50x.html; + +} + +# Synapse reverse proxy including .well-known/matrix/client +# domain synapse.othersite.m.localhost +server { + listen 80; + listen [::]:80; + listen 443 ssl; + listen 8448 ssl; + listen [::]:443 ssl; + listen [::]:8448 ssl; + server_name synapse.othersite.m.localhost; + ssl_certificate /root/ssl/cert.pem; + ssl_certificate_key /root/ssl/key.pem; + + # well-known config adding rtc_foci backend + # Note well-known is currently not effective due to: + # https://spec.matrix.org/v1.12/client-server-api/#well-known-uri the spec + # says it must be at https://$server_name/... (implied port 443) Hence, we + # currently rely for local development environment on deprecated config.json + # setting for livekit_service_url + location /.well-known/matrix/client { + add_header Access-Control-Allow-Origin *; + return 200 '{"m.homeserver": {"base_url": "https://synapse.othersite.m.localhost"}, "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://matrix-rtc.othersite.m.localhost/livekit/jwt"}]}'; + default_type application/json; + } + + # Reverse proxy for Matrix Synapse Homeserver + # This is also required for development environment. + # Reason: the lk-jwt-service uses the federation API for the openid token + # verification, which requires TLS + location ~ ^(/_matrix|/_synapse/client) { + proxy_pass "http://homeserver-1:18008"; + proxy_http_version 1.1; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; } error_page 500 502 503 504 /50x.html; @@ -41,6 +81,7 @@ server { } # MatrixRTC reverse proxy +# domain matrix-rtc.m.localhost # - MatrixRTC Authorization Service # - LiveKit SFU websocket signaling connection upstream jwt-auth-services { @@ -49,12 +90,8 @@ upstream jwt-auth-services { } server { - listen 80; - listen [::]:80; listen 443 ssl; listen [::]:443 ssl; - listen 8448 ssl; - listen [::]:8448 ssl; server_name matrix-rtc.m.localhost; ssl_certificate /root/ssl/cert.pem; ssl_certificate_key /root/ssl/key.pem; @@ -96,6 +133,54 @@ server { } +# MatrixRTC reverse proxy +# domain matrix-rtc.othersite.m.localhost +# - MatrixRTC Authorization Service +# - LiveKit SFU websocket signaling connection +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name matrix-rtc.othersite.m.localhost; + ssl_certificate /root/ssl/cert.pem; + ssl_certificate_key /root/ssl/key.pem; + + http2 on; + + + location ^~ /livekit/jwt/ { + + 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; + + # JWT Service running at port 16080 + proxy_pass http://auth-service-1:16080/; + + } + + location ^~ /livekit/sfu/ { + 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; + + proxy_send_timeout 120; + proxy_read_timeout 120; + proxy_buffering off; + + proxy_set_header Accept-Encoding gzip; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # LiveKit SFU websocket connection running at port 17880 + proxy_pass http://livekit-sfu-1:17880/; + } + + error_page 500 502 503 504 /50x.html; + +} + # Convenience reverse proxy for the call.m.localhost domain to yarn dev --host server { listen 80; @@ -161,3 +246,36 @@ server { error_page 500 502 503 504 /50x.html; } + +# Convenience reverse proxy app.othersite.m.localhost for element web +server { + listen 80; + listen [::]:80; + server_name app.othersite.m.localhost; + + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + server_name app.othersite.m.localhost; + ssl_certificate /root/ssl/cert.pem; + ssl_certificate_key /root/ssl/key.pem; + + + location ^~ / { + + 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; + + proxy_pass http://element-web-1:18081; + proxy_ssl_verify off; + + } + + error_page 500 502 503 504 /50x.html; + +} diff --git a/backend/playwright_homeserver-othersite.yaml b/backend/playwright_homeserver-othersite.yaml new file mode 100644 index 00000000..e769277e --- /dev/null +++ b/backend/playwright_homeserver-othersite.yaml @@ -0,0 +1,88 @@ +server_name: "synapse.othersite.m.localhost" +public_baseurl: https://synapse.othersite.m.localhost/ + +pid_file: /data/homeserver.pid + +listeners: + - port: 18008 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation, openid] + compress: false + +database: + name: sqlite3 + args: + database: /data/homeserver.db + +media_store_path: /data/media_store +signing_key_path: "/data/SERVERNAME.signing.key" + +# Due to custom TLS certificate with domains +# - m.localhost, localhost +# - *.m.localhost +# - *.othersite.m.localhost +# we disable certificate verification to allow for federation. +# WARNING: DO NOT USE IN PRODUCTION!!! +federation_verify_certificates: false +ip_range_blacklist: [] +trusted_key_servers: + - server_name: "synapse.m.localhost" + accept_keys_insecurely: true + +experimental_features: + # MSC3266: Room summary API. Used for knocking over federation + msc3266_enabled: true + # MSC4222 needed for syncv2 state_after. This allow clients to + # correctly track the state of the room. + msc4222_enabled: true + +# The maximum allowed duration by which sent events can be delayed, as +# per MSC4140. Must be a positive value if set. Defaults to no +# duration (null), which disallows sending delayed events. +max_event_delay_duration: 24h + +# Required for Element Call in Single Page Mode due to on-the-fly user registration +enable_registration: true +enable_registration_without_verification: true + +report_stats: false +serve_server_wellknown: true + +# Ratelimiting settings for client actions (registration, login, messaging). +# +# Each ratelimiting configuration is made of two parameters: +# - per_second: number of requests a client can send per second. +# - burst_count: number of requests a client can send before being throttled. + +rc_message: + per_second: 10000 + burst_count: 10000 + +rc_delayed_event_mgmt: + per_second: 10000 + burst_count: 10000 + +rc_login: + address: + per_second: 10000 + burst_count: 10000 + account: + per_second: 10000 + burst_count: 10000 + failed_attempts: + per_second: 10000 + burst_count: 10000 + +rc_registration: + per_second: 10000 + burst_count: 10000 + +# Required for Element Call in Single Page Mode due to on-the-fly user registration +enable_registration: true +enable_registration_without_verification: true + +report_stats: false +serve_server_wellknown: true diff --git a/dev-backend-docker-compose.yml b/dev-backend-docker-compose.yml index f4c37cf2..335534a1 100644 --- a/dev-backend-docker-compose.yml +++ b/dev-backend-docker-compose.yml @@ -24,6 +24,28 @@ services: networks: - ecbackend + auth-service-1: + image: ghcr.io/element-hq/lk-jwt-service:latest-ci + pull_policy: always + hostname: auth-server-1 + environment: + - LIVEKIT_JWT_PORT=16080 + - LIVEKIT_URL=wss://matrix-rtc.othersite.m.localhost/livekit/sfu + - LIVEKIT_KEY=devkey + - LIVEKIT_SECRET=secret + # If the configured homeserver runs on localhost, it'll probably be using + # a self-signed certificate + - LIVEKIT_INSECURE_SKIP_VERIFY_TLS=YES_I_KNOW_WHAT_I_AM_DOING + - LIVEKIT_FULL_ACCESS_HOMESERVERS=* + deploy: + restart_policy: + condition: on-failure + ports: + # HOST_PORT:CONTAINER_PORT + - 16080:16080 + networks: + - ecbackend + livekit: image: livekit/livekit-server:latest pull_policy: always @@ -44,10 +66,23 @@ services: networks: - ecbackend + livekit-1: + image: livekit/livekit-server:latest pull_policy: always + hostname: livekit-sfu-1 + command: --dev --config /etc/livekit.yaml + restart: unless-stopped + # The SFU seems to work far more reliably when we let it share the host + # network rather than opening specific ports (but why?? we're not missing + # any…) ports: # HOST_PORT:CONTAINER_PORT + - 17880:17880/tcp + - 17881:17881/tcp + - 17882:17882/tcp + - 50300-50400:50300-50400/udp volumes: + - ./backend/dev_livekit-othersite.yaml:/etc/livekit.yaml:Z networks: - ecbackend @@ -69,6 +104,24 @@ services: networks: - ecbackend + synapse-1: + hostname: homeserver-1 + image: docker.io/matrixdotorg/synapse:latest + pull_policy: always + environment: + - SYNAPSE_CONFIG_PATH=/data/cfg/homeserver.yaml + # Needed for rootless podman-compose such that the uid/gid mapping does + # fit local user uid. If the container runs as root (uid 0) it is fine as + # it actually maps to your non-root user on the host (e.g. 1000). + # Otherwise uid mapping will not match your non-root user. + - UID=0 + - GID=0 + volumes: + - ./backend/synapse_tmp_othersite:/data:Z + - ./backend/dev_homeserver-othersite.yaml:/data/cfg/homeserver.yaml:Z + networks: + - ecbackend + element-web: image: ghcr.io/element-hq/element-web:develop pull_policy: always diff --git a/playwright-backend-docker-compose.override.yml b/playwright-backend-docker-compose.override.yml index dadbccc2..8648c63c 100644 --- a/playwright-backend-docker-compose.override.yml +++ b/playwright-backend-docker-compose.override.yml @@ -2,3 +2,6 @@ services: synapse: volumes: - ./backend/playwright_homeserver.yaml:/data/cfg/homeserver.yaml:Z + synapse-1: + volumes: + - ./backend/playwright_homeserver-othersite.yaml:/data/cfg/homeserver.yaml:Z