diff --git a/containers/conduit.nix b/containers/conduit.nix index 125652e..bca4713 100644 --- a/containers/conduit.nix +++ b/containers/conduit.nix @@ -10,59 +10,101 @@ nglib.makeSystem { type.services = { }; }; - init.services.conduit = { + init.services.synapse = { enabled = true; shutdownOnExit = true; script = let - conduitConfig = pkgs.writeText "conduit.toml" - '' - [global] - # The server_name is the pretty name of this server. It is used as a suffix for user - # and room ids. Examples: matrix.org, conduit.rs + logConfig = (pkgs.formats.yaml {}).generate "log.yaml" + { + # Log configuration for Synapse. + # + # This is a YAML file containing a standard Python logging configuration + # dictionary. See [1] for details on the valid settings. + # + # Synapse also supports structured logging for machine readable logs which can + # be ingested by ELK stacks. See [2] for details. + # + # [1]: https://docs.python.org/3.7/library/logging.config.html#configuration-dictionary-schema + # [2]: https://matrix-org.github.io/synapse/latest/structured_logging.html - # The Conduit server needs all /_matrix/ requests to be reachable at - # https://your.server.name/ on port 443 (client-server) and 8448 (federation). + version = 1; - # If that's not possible for you, you can create /.well-known files to redirect - # requests. See - # https://matrix.org/docs/spec/client_server/latest#get-well-known-matrix-client - # and - # https://matrix.org/docs/spec/server_server/r0.1.4#get-well-known-matrix-server - # for more information + formatters.precise.format = "%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s"; + handlers.console = + { + class = "logging.StreamHandler"; + formatter = "precise"; + }; + loggers."synapse.storage.SQL" = + { + level = "INFO"; + }; + root = + { + level = "INFO"; + handlers = [ "console" ]; + }; - # YOU NEED TO EDIT THIS - server_name = "matrix.redalder.org" + disable_existing_loggers = false; + }; + synapseConfig = (pkgs.formats.yaml {}).generate "conduit.yaml" + { + server_name = "matrix.redalder.org"; + report_stats = "yes"; + pid_file = "/homeserver.pid"; - # This is the only directory where Conduit will save its data - database_path = "/var/lib/matrix-conduit/" - database_backend = "rocksdb" + enable_registration = false; + enable_registration_without_verification = false; - # The port Conduit will be running on. You need to set up a reverse proxy in - # your web server (e.g. apache or nginx), so all requests to /_matrix on port - # 443 and 8448 will be forwarded to the Conduit instance running on this port - port = 6167 - - # Max size for uploads - max_request_size = 20_000_000 # in bytes - - # Enables registration. If set to false, no users can register on this server. - allow_registration = true - - allow_federation = true - - trusted_servers = ["matrix.org"] - - # How many requests Conduit sends to other servers at the same time - #max_concurrent_requests = 100 - #log = "info,state_res=warn,rocket=off,_=off,sled=off" - - address = "127.0.0.1" - ''; + listeners = + [ + { + port = 6167; + tls = false; + type = "http"; + x_forwarded = true; + bind_adrresses = [ "127.0.0.1" ]; + resources = + [ + { + names = [ "client" "federation" ]; + compress = false; + } + ]; + } + ]; + database = + { + name = "sqlite3"; + compress = false; + args.database = "/var/lib/synapse/sqlite.db"; + }; + log_config = logConfig; + trusted_key_servers = + [ + { + server_name = "matrix.org"; + } + ]; + media_store_path = "/var/lib/synapse/media_store"; + signing_key_path = "/var/lib/synapse/signing.key"; + }; in pkgs.writeShellScript "conduit" '' - CONDUIT_CONFIG=${conduitConfig} ${pkgs.matrix-conduit}/bin/conduit + [ -e /var/lib/synapse/signing.key ] || \ + ${pkgs.matrix-synapse}/bin/synapse_homeserver \ + --config-path ${synapseConfig} \ + --config-path /secrets/extra.yaml \ + --config-path /var/lib/registrations/extra.yaml \ + --keys-directory /var/lib/synapse/keys \ + --generate-keys + ${pkgs.matrix-synapse}/bin/synapse_homeserver \ + --config-path ${synapseConfig} \ + --config-path /secrets/extra.yaml \ + --config-path /var/lib/registrations/extra.yaml \ + --keys-directory /var/lib/synapse/keys ''; }; }); diff --git a/containers/ingress-toothpick.nix b/containers/ingress-toothpick.nix index 67b8450..a76de11 100644 --- a/containers/ingress-toothpick.nix +++ b/containers/ingress-toothpick.nix @@ -67,6 +67,7 @@ nglib.makeSystem { extraDomains = [ "hydra.redalder.org" "gitea.redalder.org" + "matrix.redalder.org" "nixng.org" ]; webroot = "/var/www/certbot"; diff --git a/containers/mautrix-facebook.nix b/containers/mautrix-facebook.nix new file mode 100644 index 0000000..4817f95 --- /dev/null +++ b/containers/mautrix-facebook.nix @@ -0,0 +1,36 @@ +{ nglib, nixpkgs }: +nglib.makeSystem { + system = "x86_64-linux"; + name = "nixng-gitea"; + inherit nixpkgs; + config = ({ pkgs, ... }: + { + dumb-init = { + enable = true; + type.services = { }; + }; + + init.services.mautrix-facebook = { + enabled = true; + shutdownOnExit = true; + script = + let + config = ./mautrix-facebook.yaml; + in + pkgs.writeShellScript "mautrix-facebook" + '' + DATA_DIR="/var/lib/mautrix-facebook" + CONFIG_FILE="$DATA_DIR/config.yaml" + REGISTRATION_FILE="/var/lib/registrations/mautrix-facebook.yaml" + DB_FILE="$DATA_DIR/sqlite.db" + + cp ${config} "$CONFIG_FILE" ; chmod 755 "$CONFIG_FILE" + ${pkgs.sqlite}/bin/sqlite3 $DB_FILE '.databases ; .quit' + + [ -e "$REGISTRATION_FILE" ] || \ + ${pkgs.mautrix-facebook}/bin/mautrix-facebook -c "$CONFIG_FILE" -r "$REGISTRATION_FILE" -g + ${pkgs.mautrix-facebook}/bin/mautrix-facebook -c "$CONFIG_FILE" -r "$REGISTRATION_FILE" -n + ''; + }; + }); +} diff --git a/containers/mautrix-facebook.yaml b/containers/mautrix-facebook.yaml new file mode 100644 index 0000000..91f9bc6 --- /dev/null +++ b/containers/mautrix-facebook.yaml @@ -0,0 +1,359 @@ +# Homeserver details +homeserver: + # The address that this appservice can use to connect to the homeserver. + address: https://matrix.redalder.org + # The domain of the homeserver (for MXIDs, etc). + domain: matrix.redalder.org + # Whether or not to verify the SSL certificate of the homeserver. + # Only applies if address starts with https:// + verify_ssl: true + # What software is the homeserver running? + # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. + software: standard + # Number of retries for all HTTP requests if the homeserver isn't reachable. + http_retry_count: 4 + # The URL to push real-time bridge status to. + # If set, the bridge will make POST requests to this URL whenever a user's Facebook MQTT connection state changes. + # The bridge will use the appservice as_token to authorize requests. + status_endpoint: null + # Endpoint for reporting per-message status. + message_send_checkpoint_endpoint: null + # Whether asynchronous uploads via MSC2246 should be enabled for media. + # Requires a media repo that supports MSC2246. + async_media: false + +# Application service host/registration related details +# Changing these values requires regeneration of the registration. +appservice: + # The address that the homeserver can use to connect to this appservice. + address: http://localhost:29319 + + # The hostname and port where this appservice should listen. + hostname: 0.0.0.0 + port: 29319 + # The maximum body size of appservice API requests (from the homeserver) in mebibytes + # Usually 1 is enough, but on high-traffic bridges you might need to increase this to avoid 413s + max_body_size: 1 + + # The full URI to the database. SQLite and Postgres are supported. + # Format examples: + # SQLite: sqlite:///filename.db + # Postgres: postgres://username:password@hostname/dbname + database: sqlite:////var/lib/mautrix-facebook/sqlite.db + # Additional arguments for asyncpg.create_pool() or sqlite3.connect() + # https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.pool.create_pool + # https://docs.python.org/3/library/sqlite3.html#sqlite3.connect + # For sqlite, min_size is used as the connection thread pool size and max_size is ignored. + # Additionally, SQLite supports init_commands as an array of SQL queries to run on connect (e.g. to set PRAGMAs). + database_opts: + min_size: 1 + max_size: 10 + + # Public part of web server for out-of-Matrix interaction with the bridge. + public: + # Whether or not the public-facing endpoints should be enabled. + enabled: true + # The prefix to use in the public-facing endpoints. + prefix: /mufb + # The base URL where the public-facing endpoints are available. The prefix is not added + # implicitly. + external: https://matrix.redalder.org/mufb + # Shared secret for integration managers such as mautrix-manager. + # If set to "generate", a random string will be generated on the next startup. + # If null, integration manager access to the API will not be possible. + shared_secret: generate + # Allow logging in within Matrix. If false, users can only log in using the web interface. + allow_matrix_login: true + # Segment API key to enable analytics tracking for web server endpoints. Set to null to disable. + # Currently the only events are login start, success and fail. + segment_key: null + + # The unique ID of this appservice. + id: mufacebook + # Username of the appservice bot. + bot_username: mufacebookbot + # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty + # to leave display name/avatar as-is. + bot_displayname: Mautrix Facebook bridge bot + bot_avatar: mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak + + # Whether or not to receive ephemeral events via appservice transactions. + # Requires MSC2409 support (i.e. Synapse 1.22+). + # You should disable bridge -> sync_with_custom_puppets when this is enabled. + ephemeral_events: true + + # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. + # as_token: "This value is generated when generating the registration" + # hs_token: "This value is generated when generating the registration" + +# Prometheus telemetry config. Requires prometheus-client to be installed. +metrics: + enabled: false + listen_port: 8000 + +# Manhole config. +manhole: + # Whether or not opening the manhole is allowed. + enabled: false + # The path for the unix socket. + path: /var/tmp/mautrix-facebook.manhole + # The list of UIDs who can be added to the whitelist. + # If empty, any UIDs can be specified in the open-manhole command. + whitelist: + - 0 + +# Bridge config +bridge: + # Localpart template of MXIDs for Facebook users. + # {userid} is replaced with the user ID of the Facebook user. + username_template: "facebook_{userid}" + # Displayname template for Facebook users. + # {displayname} is replaced with the display name of the Facebook user + # as defined below in displayname_preference. + # Keys available for displayname_preference are also available here. + displayname_template: "{displayname} (FB)" + # Available keys: + # "name" (full name) + # "first_name" + # "last_name" + # "nickname" + # "own_nickname" (user-specific!) + displayname_preference: + - name + - first_name + + # The prefix for commands. Only required in non-management rooms. + command_prefix: "!fb" + + # Number of chats to sync (and create portals for) on startup/login. + # Set 0 to disable automatic syncing. + initial_chat_sync: 20 + # Whether or not the Facebook users of logged in Matrix users should be + # invited to private chats when the user sends a message from another client. + invite_own_puppet_to_pm: false + # Whether or not to use /sync to get presence, read receipts and typing notifications + # when double puppeting is enabled + sync_with_custom_puppets: false + # Whether or not to update the m.direct account data event when double puppeting is enabled. + # Note that updating the m.direct event is not atomic (except with mautrix-asmux) + # and is therefore prone to race conditions. + sync_direct_chat_list: false + # Servers to always allow double puppeting from + double_puppet_server_map: + example.com: https://example.com + # Allow using double puppeting from any server with a valid client .well-known file. + double_puppet_allow_discovery: false + # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth + # + # If set, custom puppets will be enabled automatically for local users + # instead of users having to find an access token and run `login-matrix` + # manually. + # If using this for other servers than the bridge's server, + # you must also set the URL in the double_puppet_server_map. + login_shared_secret_map: + example.com: foobar + # Should presence from Facebook be bridged? This doesn't use the same API as the Android app, + # so it might be more suspicious to Facebook. + presence_from_facebook: false + # Whether or not to update avatars when syncing all contacts at startup. + update_avatar_initial_sync: true + + # Whether or not the bridge should send a read receipt from the bridge bot when a message has + # been sent to Facebook. + delivery_receipts: false + # Whether or not delivery errors should be reported as messages in the Matrix room. + delivery_error_reports: true + # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. + message_status_events: false + # Whether to allow inviting arbitrary mxids to portal rooms + allow_invites: false + # Whether or not created rooms should have federation enabled. + # If false, created portal rooms will never be federated. + federate_rooms: true + # Settings for backfilling messages from Facebook. + backfill: + # Whether or not the Facebook users of logged in Matrix users should be + # invited to private chats when backfilling history from Facebook. This is + # usually needed to prevent rate limits and to allow timestamp massaging. + invite_own_puppet: true + # Maximum number of messages to backfill initially. + # Set to 0 to disable backfilling when creating portal. + initial_limit: 0 + # Maximum number of messages to backfill if messages were missed while + # the bridge was disconnected. + # Set to 0 to disable backfilling missed messages. + missed_limit: 1000 + # If using double puppeting, should notifications be disabled + # while the initial backfill is in progress? + disable_notifications: false + periodic_reconnect: + # Interval in seconds in which to automatically reconnect all users. + # This can be used to automatically mitigate the bug where Facebook stops sending messages. + # Set to -1 to disable periodic reconnections entirely. + # Set to a list of two items to randomize the interval (min, max). + interval: -1 + # What to do in periodic reconnects. Either "refresh" or "reconnect" + mode: refresh + # Should even disconnected users be reconnected? + always: false + # Only reconnect if the user has been connected for longer than this value + min_connected_time: 0 + # The number of seconds that a disconnection can last without triggering an automatic re-sync + # and missed message backfilling when reconnecting. + # Set to 0 to always re-sync, or -1 to never re-sync automatically. + resync_max_disconnected_time: 5 + # Should the bridge do a resync on startup? + sync_on_startup: true + # Whether or not temporary disconnections should send notices to the notice room. + # If this is false, disconnections will never send messages and connections will only send + # messages if it was disconnected for more than resync_max_disconnected_time seconds. + temporary_disconnect_notices: false + # Disable bridge notices entirely + disable_bridge_notices: false + on_reconnection_fail: + # What to do if a reconnection attempt fails? Options: reconnect, refresh, null + action: reconnect + # Seconds to wait before attempting to refresh the connection, set a list of two items to + # to randomize the interval (min, max). + wait_for: 0 + # Set this to true to tell the bridge to re-send m.bridge events to all rooms on the next run. + # This field will automatically be changed back to false after it, + # except if the config file is not writable. + resend_bridge_info: false + # When using double puppeting, should muted chats be muted in Matrix? + mute_bridging: false + # Whether or not mute status and tags should only be bridged when the portal room is created. + tag_only_on_create: true + # If set to true, downloading media from the CDN will use a plain aiohttp client without the usual headers or + # other configuration. This may be useful if you don't want to use the default proxy for large files. + sandbox_media_download: false + # URL to call to retrieve a proxy URL from (defaults to the http_proxy environment variable). + get_proxy_api_url: null + + # End-to-bridge encryption support options. + # + # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. + encryption: + # Allow encryption, work in group chat rooms with e2ee enabled + allow: false + # Default to encryption, force-enable encryption in all portals the bridge creates + # This will cause the bridge bot to be in private chats for the encryption to work properly. + default: false + # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. + appservice: false + # Require encryption, drop any unencrypted messages. + require: false + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow_key_sharing: false + # What level of device verification should be required from users? + # + # Valid levels: + # unverified - Send keys to all device in the room. + # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. + # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). + # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. + # Note that creating user signatures from the bridge bot is not currently possible. + # verified - Require manual per-device verification + # (currently only possible by modifying the `trust` column in the `crypto_device` database table). + verification_levels: + # Minimum level for which the bridge should send keys to when bridging messages from Telegram to Matrix. + receive: unverified + # Minimum level that the bridge should accept for incoming Matrix messages. + send: unverified + # Minimum level that the bridge should require for accepting key requests. + share: cross-signed-tofu + # Options for Megolm room key rotation. These options allow you to + # configure the m.room.encryption event content. See: + # https://spec.matrix.org/v1.3/client-server-api/#mroomencryption for + # more information about that event. + rotation: + # Enable custom Megolm room key rotation settings. Note that these + # settings will only apply to rooms created after this option is + # set. + enable_custom: false + # The maximum number of milliseconds a session should be used + # before changing it. The Matrix spec recommends 604800000 (a week) + # as the default. + milliseconds: 604800000 + # The maximum number of messages that should be sent with a given a + # session before changing it. The Matrix spec recommends 100 as the + # default. + messages: 100 + + # Permissions for using the bridge. + # Permitted values: + # relay - Allowed to be relayed through the bridge, no access to commands. + # user - Use the bridge with puppeting. + # admin - Use and administrate the bridge. + # Permitted keys: + # * - All Matrix users + # domain - All users on that homeserver + # mxid - Specific user + permissions: + "*": "relay" + "matrix.redalder.org": "user" + "@magic_rb:matrix.redalder.org": "admin" + + relay: + # Whether relay mode should be allowed. If allowed, `!fb set-relay` can be used to turn any + # authenticated user into a relaybot for that chat. + enabled: false + # The formats to use when sending messages to Messenger via a relay user. + # + # Available variables: + # $sender_displayname - The display name of the sender (e.g. Example User) + # $sender_username - The username (Matrix ID localpart) of the sender (e.g. exampleuser) + # $sender_mxid - The Matrix ID of the sender (e.g. @exampleuser:example.com) + # $message - The message content + message_formats: + m.text: '$sender_displayname: $message' + m.notice: '$sender_displayname: $message' + m.emote: '* $sender_displayname $message' + m.file: '$sender_displayname sent a file' + m.image: '$sender_displayname sent an image' + m.audio: '$sender_displayname sent an audio file' + m.video: '$sender_displayname sent a video' + m.location: '$sender_displayname sent a location' + +facebook: + device_seed: generate + default_region_hint: ODN + connection_type: WIFI + carrier: Verizon + hni: 311390 + +# Python logging configuration. +# +# See section 16.7.2 of the Python documentation for more info: +# https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema +logging: + version: 1 + formatters: + colored: + (): mautrix_facebook.util.ColorFormatter + format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s" + normal: + format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s" + handlers: + file: + class: logging.handlers.RotatingFileHandler + formatter: normal + filename: ./mautrix-facebook.log + maxBytes: 10485760 + backupCount: 10 + console: + class: logging.StreamHandler + formatter: colored + loggers: + mau: + level: DEBUG + maufbapi: + level: DEBUG + paho: + level: INFO + aiohttp: + level: INFO + root: + level: DEBUG + handlers: [file, console] diff --git a/flake.nix b/flake.nix index 4e668c6..7b834f7 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,7 @@ reicio = import ./containers/reicio.nix base; baikal = import ./containers/baikal.nix base; conduit = import ./containers/conduit.nix base; + mautrix-facebook = import ./containers/mautrix-facebook.nix base; }; hydraJobs =