From 192a67c362bbbb855a620050049c1ead0af76a31 Mon Sep 17 00:00:00 2001 From: jjacobson Date: Wed, 21 Apr 2021 16:18:09 +1000 Subject: [PATCH] Added some changes/helpers to dev locally using hydrogen-web client --- .vscode/launch.json | 33 ++ ReverseProxy/README | 5 + ReverseProxy/default.conf | 20 + ReverseProxy/docker-compose.yml | 15 + .../dendrite-config-monolith-sqlite.yaml | 392 ++++++++++++++++++ cmd/dendrite-monolith-server/README | 2 + cmd/dendrite-monolith-server/matrix_key.pem | 5 + cmd/dendrite-monolith-server/server.crt | 28 ++ cmd/dendrite-monolith-server/server.key | 51 +++ 9 files changed, 551 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 ReverseProxy/README create mode 100644 ReverseProxy/default.conf create mode 100644 ReverseProxy/docker-compose.yml create mode 100644 build/docker/config/dendrite-config-monolith-sqlite.yaml create mode 100644 cmd/dendrite-monolith-server/README create mode 100644 cmd/dendrite-monolith-server/matrix_key.pem create mode 100644 cmd/dendrite-monolith-server/server.crt create mode 100644 cmd/dendrite-monolith-server/server.key diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..09db3f073 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package Monolith", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceFolder}\\cmd\\dendrite-monolith-server", + "args": [ + "-config", + "${workspaceFolder}\\build\\docker\\config\\dendrite-config-monolith-sqlite.yaml", + //Uncomment below to expose internal api's + // "--api", + // "true" + ]}, + { + "name": "Launch Package Polylith", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceFolder}/cmd/dendrite-polylith-multi", + "args": [ + "--config", + "${workspaceFolder}\\bin\\dendrite.yaml", + "clientapi", + ] + } + ] +} \ No newline at end of file diff --git a/ReverseProxy/README b/ReverseProxy/README new file mode 100644 index 000000000..16f2210eb --- /dev/null +++ b/ReverseProxy/README @@ -0,0 +1,5 @@ +This Proxy helps when deving against a local dendrite version and using a local instance of the client. CORS will give you a headache. +Simply run docker-compose -f docker-compose.yml up -d and then: + +Client available: localhost/client/ +Server available: localhost/server/ \ No newline at end of file diff --git a/ReverseProxy/default.conf b/ReverseProxy/default.conf new file mode 100644 index 000000000..4a2666c66 --- /dev/null +++ b/ReverseProxy/default.conf @@ -0,0 +1,20 @@ +server { + listen 80 ; # IPv4 + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_read_timeout 600; + + location /server/ { + proxy_pass http://host.docker.internal:8008/; + } + + location /client/ { + proxy_pass http://host.docker.internal:3000/; + } + + location /test/ { + return 200 'Hello World!'; + } + +} diff --git a/ReverseProxy/docker-compose.yml b/ReverseProxy/docker-compose.yml new file mode 100644 index 000000000..5ab353ddb --- /dev/null +++ b/ReverseProxy/docker-compose.yml @@ -0,0 +1,15 @@ +version: "3.4" +services: + nginx: + image: nginx:latest + hostname: load_balancer + networks: + - internal + volumes: + - ./default.conf:/etc/nginx/conf.d/default.conf + ports: + - 80:80 + +networks: + internal: + attachable: true diff --git a/build/docker/config/dendrite-config-monolith-sqlite.yaml b/build/docker/config/dendrite-config-monolith-sqlite.yaml new file mode 100644 index 000000000..2bd588771 --- /dev/null +++ b/build/docker/config/dendrite-config-monolith-sqlite.yaml @@ -0,0 +1,392 @@ +# This is the Dendrite configuration file. +# +# The configuration is split up into sections - each Dendrite component has a +# configuration section, in addition to the "global" section which applies to +# all components. +# +# At a minimum, to get started, you will need to update the settings in the +# "global" section for your deployment, and you will need to check that the +# database "connection_string" line in each component section is correct. +# +# Each component with a "database" section can accept the following formats +# for "connection_string": +# SQLite: file:filename.db +# file:///path/to/filename.db +# PostgreSQL: postgresql://user:pass@hostname/database?params=... +# +# SQLite is embedded into Dendrite and therefore no further prerequisites are +# needed for the database when using SQLite mode. However, performance with +# PostgreSQL is significantly better and recommended for multi-user deployments. +# SQLite is typically around 20-30% slower than PostgreSQL when tested with a +# small number of users and likely will perform worse still with a higher volume +# of users. +# +# The "max_open_conns" and "max_idle_conns" settings configure the maximum +# number of open/idle database connections. The value 0 will use the database +# engine default, and a negative value will use unlimited connections. The +# "conn_max_lifetime" option controls the maximum length of time a database +# connection can be idle in seconds - a negative value is unlimited. + +# The version of the configuration file. +version: 1 + +# Global Matrix configuration. This configuration applies to all components. +global: + # The domain name of this homeserver. + server_name: example.com + + # The path to the signing private key file, used to sign requests and events. + # Note that this is NOT the same private key as used for TLS! To generate a + # signing key, use "./bin/generate-keys --private-key matrix_key.pem". + private_key: matrix_key.pem + + # The paths and expiry timestamps (as a UNIX timestamp in millisecond precision) + # to old signing private keys that were formerly in use on this domain. These + # keys will not be used for federation request or event signing, but will be + # provided to any other homeserver that asks when trying to verify old events. + # old_private_keys: + # - private_key: old_matrix_key.pem + # expired_at: 1601024554498 + + # How long a remote server can cache our server signing key before requesting it + # again. Increasing this number will reduce the number of requests made by other + # servers for our key but increases the period that a compromised key will be + # considered valid by other homeservers. + key_validity_period: 168h0m0s + + # Lists of domains that the server will trust as identity servers to verify third + # party identifiers such as phone numbers and email addresses. + trusted_third_party_id_servers: + - matrix.org + - vector.im + + # Disables federation. Dendrite will not be able to make any outbound HTTP requests + # to other servers and the federation API will not be exposed. + disable_federation: true + + # Configuration for Kafka/Naffka. + kafka: + # List of Kafka broker addresses to connect to. This is not needed if using + # Naffka in monolith mode. + addresses: + - localhost:2181 + + # The prefix to use for Kafka topic names for this homeserver. Change this only if + # you are running more than one Dendrite homeserver on the same Kafka deployment. + topic_prefix: Dendrite + + # Whether to use Naffka instead of Kafka. This is only available in monolith + # mode, but means that you can run a single-process server without requiring + # Kafka. + use_naffka: true + + # The max size a Kafka message is allowed to use. + # You only need to change this value, if you encounter issues with too large messages. + # Must be less than/equal to "max.message.bytes" configured in Kafka. + # Defaults to 8388608 bytes. + # max_message_bytes: 8388608 + + # Naffka database options. Not required when using Kafka. + naffka_database: + connection_string: file:naffka.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + + # Configuration for Prometheus metric collection. + metrics: + # Whether or not Prometheus metrics are enabled. + enabled: false + + # HTTP basic authentication to protect access to monitoring. + basic_auth: + username: metrics + password: metrics + + # DNS cache options. The DNS cache may reduce the load on DNS servers + # if there is no local caching resolver available for use. + dns_cache: + # Whether or not the DNS cache is enabled. + enabled: false + + # Maximum number of entries to hold in the DNS cache, and + # for how long those items should be considered valid in seconds. + cache_size: 256 + cache_lifetime: 300 + +# Configuration for the Appservice API. +app_service_api: + internal_api: + listen: http://localhost:7777 + connect: http://localhost:7777 + database: + connection_string: file:appserviceapi.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + + # Disable the validation of TLS certificates of appservices. This is + # not recommended in production since it may allow appservice traffic + # to be sent to an unverified endpoint. + disable_tls_validation: false + + # Appservice configuration files to load into this homeserver. + config_files: [] + +# Configuration for the Client API. +client_api: + internal_api: + listen: http://localhost:7771 + connect: http://localhost:7771 + external_api: + listen: http://[::]:8071 + + # Prevents new users from being able to register on this homeserver, except when + # using the registration shared secret below. + registration_disabled: false + + # If set, allows registration by anyone who knows the shared secret, regardless of + # whether registration is otherwise disabled. + registration_shared_secret: "" + + # Whether to require reCAPTCHA for registration. + enable_registration_captcha: false + + # Settings for ReCAPTCHA. + recaptcha_public_key: "" + recaptcha_private_key: "" + recaptcha_bypass_secret: "" + recaptcha_siteverify_api: "" + + # TURN server information that this homeserver should send to clients. + turn: + turn_user_lifetime: "" + turn_uris: [] + turn_shared_secret: "" + turn_username: "" + turn_password: "" + + # Settings for rate-limited endpoints. Rate limiting will kick in after the + # threshold number of "slots" have been taken by requests from a specific + # host. Each "slot" will be released after the cooloff time in milliseconds. + rate_limiting: + enabled: true + threshold: 5 + cooloff_ms: 500 + +# Configuration for the EDU server. +edu_server: + internal_api: + listen: http://localhost:7778 + connect: http://localhost:7778 + +# Configuration for the Federation API. +federation_api: + internal_api: + listen: http://localhost:7772 + connect: http://localhost:7772 + external_api: + listen: http://[::]:8072 + + # List of paths to X.509 certificates to be used by the external federation listeners. + # These certificates will be used to calculate the TLS fingerprints and other servers + # will expect the certificate to match these fingerprints. Certificates must be in PEM + # format. + federation_certificates: [] + +# Configuration for the Federation Sender. +federation_sender: + internal_api: + listen: http://localhost:7775 + connect: http://localhost:7775 + database: + connection_string: file:federationsender.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + + # How many times we will try to resend a failed transaction to a specific server. The + # backoff is 2**x seconds, so 1 = 2 seconds, 2 = 4 seconds, 3 = 8 seconds etc. + send_max_retries: 16 + + # Disable the validation of TLS certificates of remote federated homeservers. Do not + # enable this option in production as it presents a security risk! + disable_tls_validation: false + + # Use the following proxy server for outbound federation traffic. + proxy_outbound: + enabled: false + protocol: http + host: localhost + port: 8080 + +# Configuration for the Key Server (for end-to-end encryption). +key_server: + internal_api: + listen: http://localhost:7779 + connect: http://localhost:7779 + database: + connection_string: file:keyserver.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + +# Configuration for the Media API. +media_api: + internal_api: + listen: http://localhost:7774 + connect: http://localhost:7774 + external_api: + listen: http://[::]:8074 + database: + connection_string: file:mediaapi.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + + # Storage path for uploaded media. May be relative or absolute. + base_path: ./media_store + + # The maximum allowed file size (in bytes) for media uploads to this homeserver + # (0 = unlimited). If using a reverse proxy, ensure it allows requests at + # least this large (e.g. client_max_body_size in nginx.) + max_file_size_bytes: 10485760 + + # Whether to dynamically generate thumbnails if needed. + dynamic_thumbnails: false + + # The maximum number of simultaneous thumbnail generators to run. + max_thumbnail_generators: 10 + + # A list of thumbnail sizes to be generated for media content. + thumbnail_sizes: + - width: 32 + height: 32 + method: crop + - width: 96 + height: 96 + method: crop + - width: 640 + height: 480 + method: scale + +# Configuration for experimental MSC's +mscs: + # A list of enabled MSC's + # Currently valid values are: + # - msc2836 (Threading, see https://github.com/matrix-org/matrix-doc/pull/2836) + # - msc2946 (Spaces Summary, see https://github.com/matrix-org/matrix-doc/pull/2946) + mscs: [] + database: + connection_string: file:mscs.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + +# Configuration for the Room Server. +room_server: + internal_api: + listen: http://localhost:7770 + connect: http://localhost:7770 + database: + connection_string: file:roomserver.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + +# Configuration for the Signing Key Server (for server signing keys). +signing_key_server: + internal_api: + listen: http://localhost:7780 + connect: http://localhost:7780 + database: + connection_string: file:signingkey.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + + # Perspective keyservers to use as a backup when direct key fetches fail. This may + # be required to satisfy key requests for servers that are no longer online when + # joining some rooms. + key_perspectives: + - server_name: matrix.org + keys: + - key_id: ed25519:auto + public_key: Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw + - key_id: ed25519:a_RXGa + public_key: l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ + + # This option will control whether Dendrite will prefer to look up keys directly + # or whether it should try perspective servers first, using direct fetches as a + # last resort. + prefer_direct_fetch: false + +# Configuration for the Sync API. +sync_api: + internal_api: + listen: http://localhost:7773 + connect: http://localhost:7773 + external_api: + listen: http://[::]:8073 + database: + connection_string: file:syncapi.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + + # This option controls which HTTP header to inspect to find the real remote IP + # address of the client. This is likely required if Dendrite is running behind + # a reverse proxy server. + # real_ip_header: X-Real-IP + +# Configuration for the User API. +user_api: + # The cost when hashing passwords on registration/login. Default: 10. Min: 4, Max: 31 + # See https://pkg.go.dev/golang.org/x/crypto/bcrypt for more information. + # Setting this lower makes registration/login consume less CPU resources at the cost of security + # should the database be compromised. Setting this higher makes registration/login consume more + # CPU resources but makes it harder to brute force password hashes. + # This value can be low if performing tests or on embedded Dendrite instances (e.g WASM builds) + # bcrypt_cost: 10 + internal_api: + listen: http://localhost:7781 + connect: http://localhost:7781 + account_database: + connection_string: file:account_database.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + device_database: + connection_string: file:devicedatabase.db + max_open_conns: 3 + max_idle_conns: 1 + conn_max_lifetime: 60 + # The length of time that a token issued for a relying party from + # /_matrix/client/r0/user/{userId}/openid/request_token endpoint + # is considered to be valid in milliseconds. + # The default lifetime is 3600000ms (60 minutes). + # openid_token_lifetime_ms: 3600000 + +# Configuration for Opentracing. +# See https://github.com/matrix-org/dendrite/tree/master/docs/tracing for information on +# how this works and how to set it up. +tracing: + enabled: false + jaeger: + serviceName: "" + disabled: false + rpc_metrics: false + tags: [] + sampler: null + reporter: null + headers: null + baggage_restrictions: null + throttler: null + +# Logging configuration, in addition to the standard logging that is sent to +# stdout by Dendrite. +# logging: +# - type: file +# level: info +# params: +# path: ./logs \ No newline at end of file diff --git a/cmd/dendrite-monolith-server/README b/cmd/dendrite-monolith-server/README new file mode 100644 index 000000000..8e8bfef1b --- /dev/null +++ b/cmd/dendrite-monolith-server/README @@ -0,0 +1,2 @@ +#To create a new user in this directory execute: +../../bin/create-account --config ../../build/docker/config/dendrite-config-monolith-sqlite.yaml --username alice3 --password foobarbaz \ No newline at end of file diff --git a/cmd/dendrite-monolith-server/matrix_key.pem b/cmd/dendrite-monolith-server/matrix_key.pem new file mode 100644 index 000000000..2cd465178 --- /dev/null +++ b/cmd/dendrite-monolith-server/matrix_key.pem @@ -0,0 +1,5 @@ +-----BEGIN MATRIX PRIVATE KEY----- +Key-ID: ed25519:4LGNlF + +lFHUDCW3KPXO0m9IdGn2rN+hr5G/kq9/mrOXIsjVpyQ= +-----END MATRIX PRIVATE KEY----- diff --git a/cmd/dendrite-monolith-server/server.crt b/cmd/dendrite-monolith-server/server.crt new file mode 100644 index 000000000..a19d7515f --- /dev/null +++ b/cmd/dendrite-monolith-server/server.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEwDCCAqigAwIBAgIRAOs9foA0BNG98hxrxHZSlekwDQYJKoZIhvcNAQELBQAw +ADAeFw0yMTA0MjEwMjI1NDJaFw0zMTA0MTkwMjI1NDJaMAAwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQC0WCQlEgwywdISSLpvKISmSnMT4hPZrSFLblqu +G/U839VP1lS8+rm458gLwM0bNY7R/uvJhUoWQKn7dRv4FIJexPjlqOs8XEp4ePxv +Ag5UE55avvmm0sLYuEzmzLcu+9a2TZ/fjqmS97dJTb4taVc4nn057ovJD2L1hthE +gB0IZNbzEfrPVQVx3uA82qYAKOVbva9AI991GO5irgYIYi8yv3jPLNKha/fISOzR +nTpHXSvyuqHktp5PNq9tcBn+B+FOujtZkKtlZTkFWYglNMtd1cm+HtxCL4d1yqM6 +9/ljIX499qkjG0ywSjxgIwFfMAZgrvEbnaoIOfTRiAbrX0Tc9ZrxK3mOmv5ygkaC +gwej29PED6K13pX5KuUSKIf6Goa7sOSh7RwsrrT1eVx5wpN0dB3VnCYR5Xs9kt+C +dROirNr9OzPNOmVFwhQuuqao3hPodPE2elDibUNJs6B4RaPOOdIKr1MFtwVW3jBv +Wfp5p+XoX8X3/DwX9Te/KHDvBP6OCNvXujqMoMVjWcSdO/N2gjoPGX91YJo9pGlX +LGndDzChCCqlhslBlT89+gO77UtNWzBVMc7f1h9BH3tyOHfHkaWYXlSX6xqj3HcR +/lTjigO7KkPiDJKmSsXsVJi2k6iPCuNcBKGoJrQJ4H9GlnaLwikROSP+XZawy9sf +fkYnowIDAQABozUwMzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAeNKrewgy3lXCE0eE +53bgVtwD1AIgiPoh8ATRaKTytGV/YXMpJRHLsXZVmYY6kFf/BzUO8LyQqHUX5/mf +coJ0mU3A3bWPfGzUoLlCzRVaqKSvD6DldutTXrP0EOFyLe3QP/KKcTjGYUBuE9mr +nxCER9RwtxGCK5rmmdOqBePCXIW/N13yyP8jOJUGCbrSejiyy1ojBUhtLFuBFa9p +k4zxNnAnIF2/7wkk20Clp7PEdkT84Q8RON94wdtFMEHxjHAdMXlxzXMjlPmzG8hH +EB7pTsDUwOi814IpbxJI9yBLIuArWQ4InCx203ytWkg1f7LPDZ/xBXxLXL88wriJ +uYMXr0VXSc3Yv41ZFa17aMIHVEBjp+H1Jwqg1IBJ5heAZWGwkmFv6GLASH5UZYTj +T41DUGI76dpZ5+24CMfsSx8I211xL6rFpUOuhIml9QX9gOTKOwN0pYVuCqJhXtG8 +z0OUd57ughuv6p9hma3ihO9wBSAb3rHwaPQpbQySxljKZNzEpXko4EhgHBjg/1qV +0tA1iJrUheMaxV8mDSJq0jAx5W3exXwt6KZal3CqgL1szNPq+0lnXu2jO6xzhTM/ +ytZM1auynXnjy4CQvdnf0WPp7Ahhh7Iaa58/PEne8FpjMugE4yyWwiFW/h6QCbwN +VO4a9s7ok5mvowq4jczxOmPDnMc= +-----END CERTIFICATE----- diff --git a/cmd/dendrite-monolith-server/server.key b/cmd/dendrite-monolith-server/server.key new file mode 100644 index 000000000..8bf04aa2f --- /dev/null +++ b/cmd/dendrite-monolith-server/server.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY-----