diff --git a/README.md b/README.md index 7cced0ed..58996b71 100644 --- a/README.md +++ b/README.md @@ -37,4 +37,4 @@ sudo yunohost app upgrade synapse -u https://github.com/YunoHost-Apps/synapse_yn ### 📚 App packaging documentation -Please see for more information. +Please see for more information. \ No newline at end of file diff --git a/auto_update/auto_update.sh b/auto_update/auto_update.sh index 457491e5..8d3ddd44 100644 --- a/auto_update/auto_update.sh +++ b/auto_update/auto_update.sh @@ -20,11 +20,14 @@ json_str = json.dumps(loaded_toml) print(json_str) EOL ) - echo $result | jq -r "$1" + echo "$result" | jq -r "$1" } check_app_version() { - local app_remote_version=$(curl 'https://api.github.com/repos/element-hq/synapse/releases/latest' -H 'Host: api.github.com' --compressed | jq -r ".tag_name" | cut -dv -f2) + local app_remote_version + app_remote_version=$(curl 'https://api.github.com/repos/element-hq/synapse/releases/latest' -H 'Host: api.github.com' --compressed | jq -r ".tag_name" | cut -dv -f2) + lk_jwt_version=$(curl 'https://api.github.com/repos/element-hq/lk-jwt-service/releases/latest' -H 'Host: api.github.com' --compressed | jq -r ".tag_name" | cut -dv -f2) + livekit_version=$(curl 'https://api.github.com/repos/livekit/livekit/releases/latest' -H 'Host: api.github.com' --compressed | jq -r ".tag_name" | cut -dv -f2) ## Check if new build is needed if [[ "$app_version" != "$app_remote_version" ]] @@ -39,6 +42,8 @@ check_app_version() { upgrade_app() { ( set -eu + local new_checksum + local prev_checksum # Define output file name # arm build: ${result_prefix_name_deb_1}-bin1_armv7l.tar.gz @@ -48,8 +53,8 @@ upgrade_app() { readonly result_prefix_name_deb_2="matrix-synapse_${app_version}-$debian_version_name_2" # Build armv7 build - build_cmd_deb_1 $app_version $result_prefix_name_deb_1 - build_cmd_deb_2 $app_version $result_prefix_name_deb_2 + build_cmd_deb_1 "$app_version" "$result_prefix_name_deb_1" + build_cmd_deb_2 "$app_version" "$result_prefix_name_deb_2" push_armv7_build # Update python requirement @@ -57,20 +62,39 @@ upgrade_app() { cp "$build_result_path_deb_2/${result_prefix_name_deb_2}"-build1_requirement.txt ../conf/requirement_"$debian_version_name_2".txt # Update manifest - sed -r -i 's|version = "[[:alnum:].]{4,8}~ynh[[:alnum:].]{1,2}"|version = "'${app_version}'~ynh1"|' ../manifest.toml + sed -r -i 's|version = "[[:alnum:].]{4,8}~ynh[[:alnum:].]{1,2}"|version = "'"${app_version}"'~ynh1"|' ../manifest.toml - # Update this link + # Update synapse link sed -r -i "s|armhf.url\s*=(.*)/releases/download/v[[:alnum:].]{4,10}/matrix-synapse_[[:alnum:].]{4,10}-$debian_version_name_1-bin[[:digit:]]_armv7l.tar.gz|armhf.url =\1/releases/download/v${app_version}/matrix-synapse_${app_version}-$debian_version_name_1-bin1_armv7l.tar.gz|" ../manifest.toml - sed -r -i "s|armhf.url\s*=(.*)/releases/download/v[[:alnum:].]{4,10}/matrix-synapse_[[:alnum:].]{4,10}-$debian_version_name_2-bin[[:digit:]]_armv7l.tar.gz|armhf.url =\1/releases/download/v${app_version}/matrix-synapse_${app_version}-$debian_version_name_2-bin1_armv7l.tar.gz|" ../manifest.toml + sed -r -i "s|armhf.url\s*=(.*)/releases/download/v[[:alnum:].]{4,10}/matrix-synapse_[[:alnum:].]{4,10}-$debian_version_name_2-bin[[:digit:]]_armv7l\.tar\.gz|armhf.url =\1/releases/download/v${app_version}/matrix-synapse_${app_version}-$debian_version_name_2-bin1_armv7l.tar.gz|" ../manifest.toml - # Update checksum - sha256sum_arm_archive_deb_1=$(cat $build_result_path_deb_1/${result_prefix_name_deb_1}-bin1_armv7l-sha256.txt) - sha256sum_arm_archive_deb_2=$(cat $build_result_path_deb_2/${result_prefix_name_deb_2}-bin1_armv7l-sha256.txt) + # Update synapse link checksum + sha256sum_arm_archive_deb_1=$(cat "$build_result_path_deb_1/${result_prefix_name_deb_1}-bin1_armv7l-sha256.txt") + sha256sum_arm_archive_deb_2=$(cat "$build_result_path_deb_2/${result_prefix_name_deb_2}-bin1_armv7l-sha256.txt") prev_sha256sum_arm_archive_deb_1=$(get_from_manifest ".resources.sources.${app_name}_prebuilt_armv7_$debian_version_name_1.armhf.sha256") prev_sha256sum_arm_archive_deb_2=$(get_from_manifest ".resources.sources.${app_name}_prebuilt_armv7_$debian_version_name_2.armhf.sha256") sed -r -i "s|$prev_sha256sum_arm_archive_deb_1|$sha256sum_arm_archive_deb_1|" ../manifest.toml sed -r -i "s|$prev_sha256sum_arm_archive_deb_2|$sha256sum_arm_archive_deb_2|" ../manifest.toml + # Update lk-jwt + wget -O archive.tar.gz "https://github.com/element-hq/lk-jwt-service/archive/refs/tags/v${lk_jwt_version}.tar.gz" + new_checksum=$(sha256sum archive.tar.gz | cut -d' ' -f1) + rm archive.tar.gz + + sed -r -i "s|url\s*=(.*)/element-hq/lk-jwt-service/archive/refs/tags/v[[:alnum:].]{4,10}\.tar\.gz|url =\1/element-hq/lk-jwt-service/archive/refs/tags/v${lk_jwt_version}.tar.gz|" ../manifest.toml + prev_checksum=$(get_from_manifest ".resources.sources.lk_jwt.sha256") + sed -r -i "s|$prev_checksum|$new_checksum|" ../manifest.toml + + # Update livekit + wget -O checksums.txt "https://github.com/livekit/livekit/releases/download/v${livekit_version}/checksums.txt" + for arch in amd64 arm64 armhf; do + sed -r -i "s|${arch}\.url\s*=(.*)/livekit/livekit/releases/download/v[[:alnum:].]{4,10}/livekit_[[:alnum:].]{4,10}_linux_${arch}.tar.gz|${arch}.url =\1/livekit/livekit/releases/download/v${livekit_version}/livekit_${livekit_version}_linux_${arch}.tar.gz|" ../manifest.toml + prev_checksum="$(get_from_manifest ".resources.sources.livekit.${arch}.sha256")" + new_checksum="$(grep -F "livekit_${livekit_version}_linux_${arch}.tar.gz" checksums.txt | cut -d' ' -f1)" + sed -r -i "s|$prev_checksum|$new_checksum|" ../manifest.toml + done + rm checksums.txt + git commit -a -m "Upgrade $app_name to $app_version" git push gitea auto_update:auto_update ) 2>&1 | tee "${app_name}_build_temp.log" diff --git a/conf/homeserver.yaml b/conf/homeserver.yaml index af62bf9a..a97147f9 100644 --- a/conf/homeserver.yaml +++ b/conf/homeserver.yaml @@ -84,7 +84,6 @@ allow_public_rooms_over_federation: {{ allow_public_rooms_over_federation }} # Note: The value is ignored when an HTTP proxy is in use # ip_range_blacklist: - - '127.0.0.0/8' - '10.0.0.0/8' - '172.16.0.0/12' - '192.168.0.0/16' @@ -97,12 +96,15 @@ ip_range_blacklist: - '198.51.100.0/24' - '203.0.113.0/24' - '224.0.0.0/4' - - '::1/128' - 'fe80::/10' - 'fc00::/7' - '2001:db8::/32' - 'ff00::/8' - 'fec0::/10' +{%- if allow_to_send_request_to_localhost != 'true' %} + - '127.0.0.0/8' + - '::1/128' +{% endif %} # List of ports that Synapse should listen on, their purpose and their # configuration. @@ -717,7 +719,7 @@ sso: # By default, this list contains only the login fallback page. # client_whitelist: -{%- for domain in domain_whitelist_client.splitlines() %} +{%- for domain in domains_list.splitlines() %} - {{ domain }} {%- endfor %} @@ -1004,3 +1006,30 @@ encryption_enabled_by_default_for_room_type: {{ e2e_enabled_by_default }} # Uncomment to allow non-server-admin users to create groups on this server # enable_group_creation: {{ enable_group_creation }} + +# +# Used for element call +# +experimental_features: + # MSC3266: Room summary API. Used for knocking over federation + msc3266_enabled: true + # MSC4222: needed for syncv2 state_after. This allows clients to + # correctly track the state of the room. + msc4222_enabled: true + # MSC4140: Delayed events are required for proper call participation signalling. If disabled it is very likely that you end up with stuck calls in Matrix rooms + msc4140_enabled: true + +# The maximum allowed duration by which sent events can be delayed, as +# per MSC4140. +max_event_delay_duration: 24h + +rc_message: + # This needs to match at least e2ee key sharing frequency plus a bit of headroom + # Note key sharing events are bursty + per_second: 0.5 + burst_count: 30 + # 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 +rc_delayed_event_mgmt: + per_second: 1 + burst_count: 20 diff --git a/conf/livekit.yml b/conf/livekit.yml new file mode 100644 index 00000000..ab73700c --- /dev/null +++ b/conf/livekit.yml @@ -0,0 +1,315 @@ +# WARNING: Don't edit this file. All change will be removed after each app upgrade +# +# Copyright 2024 LiveKit, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# main TCP port for RoomService and RTC endpoint +# for production setups, this port should be placed behind a load balancer with TLS +port: __PORT_LIVEKIT__ + +# when redis is set, LiveKit will automatically operate in a fully distributed fashion +# clients could connect to any node and be routed to the same room +# redis: + # address: redis.host:6379 + # db: 0 + # username: myuser + # password: mypassword + # To use sentinel remove the address key above and add the following + # sentinel_master_name: livekit + # sentinel_addresses: + # - livekit-redis-node-0.livekit-redis-headless:26379 + # - livekit-redis-node-1.livekit-redis-headless:26379 + # If you use a different set of credentials for sentinel add + # sentinel_username: user + # sentinel_password: pass + # + # To use TLS with redis + # tls: + # enabled: true + # # when set to true, LiveKit will not verify the server's certificate, defaults to true + # insecure: false + # server_name: myserver.com + # # file containing trusted root certificates for verification + # ca_cert_file: /path/to/ca.crt + # client_cert_file: /path/to/client.crt + # client_key_file: /path/to/client.key + # + # To use cluster remove the address key above and add the following + # cluster_addresses: + # - livekit-redis-node-0.livekit-redis-headless:6379 + # - livekit-redis-node-1.livekit-redis-headless:6380 + # And it will use the password key above as cluster password + # And the db key will not be used due to cluster mode not support it. + +# WebRTC configuration +rtc: + # UDP ports to use for client traffic. + # this port range should be open for inbound traffic on the firewall + port_range_start: 49153 + port_range_end: 49193 + # when set, LiveKit enable WebRTC ICE over TCP when UDP isn't available + # this port *cannot* be behind load balancer or TLS, and must be exposed on the node + # WebRTC transports are encrypted and do not require additional encryption + # only 80/443 on public IP are allowed if less than 1024 + tcp_port: __PORT_LIVEKIT_RTC__ + # when set to true, attempts to discover the host's public IP via STUN + # this is useful for cloud environments such as AWS & Google where hosts have an internal IP + # that maps to an external one + use_external_ip: false + # # when set, LiveKit will attempt to use a UDP mux so all UDP traffic goes through + # # listed port(s). To maximize system performance, we recommend using a range of ports + # # greater or equal to the number of vCPUs on the machine. + # # port_range_start & end must not be set for this config to take effect + # udp_port: 7882-7892 + # # when set to true, server will use a lite ice agent, that will speed up ice connection, but + # # might cause connect issue if server running behind NAT. + # use_ice_lite: true + # # optional STUN servers for LiveKit clients to use. Clients will be configured to use these STUN servers automatically. + # # by default LiveKit clients use Google's public STUN servers + # stun_servers: + # - server1 + # # optional TURN servers for clients. This isn't necessary if using embedded TURN server (see below). + # turn_servers: + # - host: myhost.com + # port: 443 + # # tls, tcp, or udp + # protocol: tls + # username: "" + # credential: "" + # # allows LiveKit to monitor congestion when sending streams and automatically + # # manage bandwidth utilization to avoid congestion/loss. Enabled by default + # congestion_control: + # enabled: true + # # in the unlikely event of highly congested networks, SFU may choose to pause some tracks + # # in order to allow others to stream smoothly. You can disable this behavior here + # allow_pause: true + # # allows automatic connection fallback to TCP and TURN/TLS (if configured) when UDP has been unstable, default true + # allow_tcp_fallback: true + # # number of packets to buffer in the SFU for video, defaults to 500 + # packet_buffer_size_video: 500 + # # number of packets to buffer in the SFU for audio, defaults to 200 + # packet_buffer_size_audio: 200 + # # minimum amount of time between pli/fir rtcp packets being sent to an individual + # # producer. Increasing these times can lead to longer black screens when new participants join, + # # while reducing them can lead to higher stream bitrate. + # pli_throttle: + # low_quality: 500ms + # mid_quality: 1s + # high_quality: 1s + # # when set, Livekit will collect loopback candidates, it is useful for some VM have public address mapped to its loopback interface. + # enable_loopback_candidate: true + # # network interface filter. If the machine has more than one network interface and you'd like it to use or skip specific interfaces + # # both inclusion and exclusion filters can be used together. If neither is defined (default), all interfaces on the machine will be used. + # # If both of them are set, then only include takes effect. + # interfaces: + # includes: + # - en0 + # excludes: + # - docker0 + # # ip address filter. If the machine has more than one ip address and you'd like it to use or skip specific ips, + # # both inclusion and exclusion CIDR filters can be used together. If neither is defined (default), all ip on the machine will be used. + # # If both of them are set, then only include takes effect. + ips: + # includes: + # - 10.0.0.0/16 + excludes: + - 0.0.0.0/8 + - 127.0.0.0/8 + # # Set to true to enable mDNS name candidate. This should be left disabled for most users. + # # when enabled, it will impact performance since each PeerConnection will process the same mDNS message independently + # use_mdns: true + # # Set to false to disable strict ACKs for peer connections where LiveKit is the dialing side, + # # ie. subscriber peer connections. Disabling strict ACKs will prevent clients that do not ACK + # # peer connections from getting kicked out of rooms by the monitor. Note that if strict ACKs + # # are disabled and clients don't ACK opened peer connections, only reliable, ordered delivery + # # will be available. + # strict_acks: true + # # enable batch write to merge network write system calls to reduce cpu usage. Outgoing packets + # # will be queued until length of queue equal to `batch_size` or time elapsed since last write exceeds `max_flush_interval`. + # batch_io: + # batch_size: 128 + # max_flush_interval: 2ms + # # max number of bytes to buffer for data channel. 0 means unlimited. + # # when this limit is breached, data messages will be dropped till the buffered amount drops below this limit. + # data_channel_max_buffered_amount: 0 + +# when enabled, LiveKit will expose prometheus metrics on :6789/metrics +# prometheus_port: 6789 + +# API key / secret pairs. +# Keys are used for JWT authentication, server APIs would require a keypair in order to generate access tokens +# and make calls to the server +keys: + element_call: __LIVEKIT_SECRET__ +# Logging config +logging: + # log level, valid values: debug, info, warn, error + level: warn + # log level for pion, default error + pion_level: error + # when set to true, emit json fields + json: false + # for production setups, enables sampling algorithm + # https://github.com/uber-go/zap/blob/master/FAQ.md#why-sample-application-logs + sample: true + +# Default room config +# Each room created will inherit these settings. If rooms are created explicitly with CreateRoom, they will take +# precedence over defaults +# room: +# # allow rooms to be automatically created when participants join, defaults to true +# # auto_create: false +# # number of seconds to keep the room open if no one joins +# empty_timeout: 300 +# # number of seconds to keep the room open after everyone leaves +# departure_timeout: 20 +# # limit number of participants that can be in a room, 0 for no limit +# max_participants: 0 +# # only accept specific codecs for clients publishing to this room +# # this is useful to standardize codecs across clients +# # other supported codecs are video/h264, video/vp9, video/av1, audio/red +# enabled_codecs: +# - mime: audio/opus +# - mime: video/vp8 +# # allow tracks to be unmuted remotely, defaults to false +# # tracks can always be muted from the Room Service APIs +# enable_remote_unmute: true +# # limit size of room and participant's metadata, 0 for no limit +# max_metadata_size: 0 +# # control playout delay in ms of video track (and associated audio track) +# playout_delay: +# enabled: true +# min: 100 +# max: 2000 +# # improves A/V sync when playout_delay set to a value larger than 200ms. It will disables transceiver re-use +# # so not recommended for rooms with frequent subscription changes +# sync_streams: true + +# Webhooks +# when configured, LiveKit notifies your URL handler with room events +# webhook: +# # the API key to use in order to sign the message +# # this must match one of the keys LiveKit is configured with +# api_key: +# # list of URLs to be notified of room events +# urls: +# - https://your-host.com/handler + +# Signal Relay +# since v1.4.0, a more reliable, psrpc based signal relay is available +# this gives us the ability to reliably proxy messages between a signal server and RTC node +# signal_relay: +# # amount of time a message delivery is tried before giving up +# retry_timeout: 30s +# # minimum amount of time to wait for RTC node to ack, +# # retries use exponentially increasing wait on every subsequent try +# # with an upper bound of max_retry_interval +# min_retry_interval: 500ms +# # maximum amount of time to wait for RTC node to ack +# max_retry_interval: 5s +# # number of messages to buffer before dropping +# stream_buffer_size: 1000 + +# PSRPC +# since v1.5.1, a more reliable, psrpc based internal rpc +# psrpc: +# # maximum number of rpc attempts +# max_attempts: 3 +# # initial time to wait for calls to complete +# timeout: 500ms +# # amount of time added to the timeout after each failure +# backoff: 500ms +# # number of messages to buffer before dropping +# buffer_size: 1000 + +# customize audio level sensitivity +# audio: +# # minimum level to be considered active, 0-127, where 0 is loudest +# # defaults to 30 +# active_level: 30 +# # percentile to measure, a participant is considered active if it has exceeded the +# # ActiveLevel more than MinPercentile% of the time +# # defaults to 40 +# min_percentile: 40 +# # frequency in ms to notify changes to clients, defaults to 500 +# update_interval: 500 +# # to prevent speaker updates from too jumpy, smooth out values over N samples +# smooth_intervals: 4 +# # enable red encoding downtrack for opus only audio up track +# active_red_encoding: true + +# turn server +turn: + # Uses TLS. Requires cert and key pem files by either: + # - using turn.secretName if deploying with our helm chart, or + # - setting LIVEKIT_TURN_CERT and LIVEKIT_TURN_KEY env vars with file locations, or + # - using cert_file and key_file below + # defaults to false + enabled: false +# # defaults to 3478 - recommended to 443 if not running HTTP3/QUIC server +# # only 53/80/443 are allowed if less than 1024 +# udp_port: 3478 +# # defaults to 5349 - if not using a load balancer, this must be set to 443 +# tls_port: 5349 +# # set UDP port range for TURN relay to connect to LiveKit SFU, by default it uses a any available port +# relay_range_start: 1024 +# relay_range_end: 30000 +# # set external_tls to true if using a L4 load balancer to terminate TLS. when enabled, +# # LiveKit expects unencrypted traffic on tls_port, and still advertise tls_port as a TURN/TLS candidate. +# external_tls: true +# # needs to match tls cert domain +# domain: turn.myhost.com +# # optional (set only if not using external TLS termination) +# # cert_file: /path/to/cert.pem +# # key_file: /path/to/key.pem + +# ingress server +# ingress: +# # Prefix used to generate RTMP URLs for RTMP ingress. +# rtmp_base_url: "rtmp://my.domain.com/live" +# # Prefix used to generate WHIP URLs for WHIP ingress. +# whip_base_url: "http://my.domain.com/whip" + +# Region of the current node. Required if using regionaware node selector +# region: us-west-2 + +# # node selector +# node_selector: +# # default: any. valid values: any, sysload, cpuload, regionaware +# kind: sysload +# # priority used for selection of node when multiple are available +# # default: random. valid values: random, sysload, cpuload, rooms, clients, tracks, bytespersec +# sort_by: sysload +# # used in sysload and regionaware +# # do not assign room to node if load per CPU exceeds sysload_limit +# sysload_limit: 0.7 +# # used in regionaware +# # list of regions and their lat/lon coordinates +# regions: +# - name: us-west-2 +# lat: 44.19434095976287 +# lon: -123.0674908379146 + +# # node limits +# # set to -1 to disable a limit +# limit: +# # defaults to 400 tracks in & out per CPU, up to 8000 +# num_tracks: -1 +# # defaults to 1 GB/s, or just under 10 Gbps +# bytes_per_sec: 1_000_000_000 +# # how many tracks (audio / video) that a single participant can subscribe at same time. +# # if the limit is exceeded, subscriptions will be pending until any subscribed track has been unsubscribed. +# # value less or equal than 0 means no limit. +# subscription_limit_video: 0 +# subscription_limit_audio: 0 diff --git a/conf/lk-jwt.conf b/conf/lk-jwt.conf new file mode 100644 index 00000000..2cc860c5 --- /dev/null +++ b/conf/lk-jwt.conf @@ -0,0 +1,4 @@ +LIVEKIT_URL=wss://__SFU_DOMAIN__/livekit/sfu +LIVEKIT_KEY=element_call +LIVEKIT_SECRET=__LIVEKIT_SECRET__ +LIVEKIT_JWT_PORT=__PORT_LIVEKIT_JWT__ diff --git a/conf/nginx.conf b/conf/nginx.conf index f78532d9..7650681e 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,10 +1,10 @@ rewrite ^$ /; location ~ ^/$ { - default_type text/plain; - return 200 "This is where Synapse is installed."; + default_type text/plain; + return 200 "This is where Synapse is installed."; } -location /_matrix/ { +location ~ ^(/_matrix|/client) { proxy_pass http://localhost:__PORT_SYNAPSE__; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; @@ -14,8 +14,8 @@ location /_matrix/ { } # Use the specific path for the php file. It's more secure than global php path -location /_matrix/cas_server.php/ { - alias /var/www/__APP__/; +location ^~ /_matrix/cas_server.php/ { + alias /var/www/__APP__/cas/; fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_pass unix:/run/php/php__PHP_VERSION__-fpm-__APP__.sock; include fastcgi_params; @@ -32,3 +32,22 @@ location /_synapse/ { client_max_body_size 10M; } + +location /livekit/jwt/ { + proxy_pass http://127.0.0.1:__PORT_LIVEKIT_JWT__/; + more_set_headers "Access-Control-Allow-Origin: *"; +} + +location /livekit/sfu/ { + proxy_pass http://127.0.0.1:__PORT_LIVEKIT__/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Server $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; +} +include /etc/nginx/conf.d/__DOMAIN__.d/__APP__.conf.inc; diff --git a/conf/nginx.conf.inc b/conf/nginx.conf.inc new file mode 100644 index 00000000..5006c006 --- /dev/null +++ b/conf/nginx.conf.inc @@ -0,0 +1,25 @@ +location = /.well-known/matrix/server { + return 200 '{"m.server": "__DOMAIN__:__PORT_SYNAPSE_TLS__"}'; + default_type application/json; + more_set_headers "Access-Control-Allow-Origin: *"; +} + +location = /.well-known/matrix/client { + return 200 '{ + "m.homeserver": { "base_url": "https://__DOMAIN__" }, + "im.vector.riot.jitsi": {"preferredDomain": "__JITSI_SERVER__"}, + "im.vector.riot.e2ee": {"default": __E2E_ENABLED_BY_DEFAULT_CLIENT_CONFIG__ }, + "org.matrix.msc4143.rtc_foci": [ + { + "type": "livekit", + "livekit_service_url": "https://__DOMAIN__/livekit/jwt" + }, + { + "type": "nextgen_new_foci_type", + "props_for_nextgen_foci": "val" + } + ] + }'; + default_type application/json; + more_set_headers "Access-Control-Allow-Origin: *"; +} diff --git a/conf/server_name.conf b/conf/server_name.conf index 9a8664f3..8f40a0ba 100644 --- a/conf/server_name.conf +++ b/conf/server_name.conf @@ -1,15 +1 @@ -location = /.well-known/matrix/server { - return 200 '{"m.server": "__DOMAIN__:__PORT_SYNAPSE_TLS__"}'; - add_header Content-Type application/json; - add_header Access-Control-Allow-Origin '*'; -} - -location = /.well-known/matrix/client { - return 200 '{ - "m.homeserver": { "base_url": "https://__DOMAIN__" }, - "im.vector.riot.jitsi": {"preferredDomain": "__JITSI_SERVER__"}, - "im.vector.riot.e2ee": {"default": __E2E_ENABLED_BY_DEFAULT_CLIENT_CONFIG__ } - }'; - add_header Content-Type application/json; - add_header Access-Control-Allow-Origin '*'; -} +include /etc/nginx/conf.d/__DOMAIN__.d/__APP__.conf.inc; diff --git a/conf/synapse-livekit.service b/conf/synapse-livekit.service new file mode 100644 index 00000000..ed523d12 --- /dev/null +++ b/conf/synapse-livekit.service @@ -0,0 +1,47 @@ +[Unit] +Description=Synapse livekit RTC backend +After=network.target + +[Service] +Type=simple +User=__APP__ +Group=__APP__ +WorkingDirectory=__INSTALL_DIR__/livekit +ExecStart=__INSTALL_DIR__/livekit/livekit-server --config /etc/matrix-__APP__/livekit.yml __LK_NODE_IP__ + +### Depending on specificities of your service/app, you may need to tweak these +### .. but this should be a good baseline +# Sandboxing options to harden security +# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html +NoNewPrivileges=yes +PrivateTmp=yes +PrivateDevices=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +RestrictNamespaces=yes +RestrictRealtime=yes +DevicePolicy=closed +ProtectClock=yes +ProtectHostname=yes +ProtectProc=invisible +ProtectSystem=full +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +LockPersonality=yes +SystemCallArchitectures=native +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation @privileged + +# Denying access to capabilities that should not be relevant for webapps +# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html +CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD +CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE +CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT +CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK +CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM +CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG +CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE +CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW +CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG + +[Install] +WantedBy=multi-user.target diff --git a/conf/synapse-lk-jwt.service b/conf/synapse-lk-jwt.service new file mode 100644 index 00000000..93c56fd6 --- /dev/null +++ b/conf/synapse-lk-jwt.service @@ -0,0 +1,48 @@ +[Unit] +Description=Synapse RTC JWT livekit backend +After=network.target + +[Service] +Type=simple +User=__APP__ +Group=__APP__ +WorkingDirectory=__INSTALL_DIR__/lk_jwt +EnvironmentFile=/etc/matrix-__APP__/lk-jwt.conf +ExecStart=__INSTALL_DIR__/lk_jwt/lk-jwt-service + +### Depending on specificities of your service/app, you may need to tweak these +### .. but this should be a good baseline +# Sandboxing options to harden security +# Details for these options: https://www.freedesktop.org/software/systemd/man/systemd.exec.html +NoNewPrivileges=yes +PrivateTmp=yes +PrivateDevices=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK +RestrictNamespaces=yes +RestrictRealtime=yes +DevicePolicy=closed +ProtectClock=yes +ProtectHostname=yes +ProtectProc=invisible +ProtectSystem=full +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +LockPersonality=yes +SystemCallArchitectures=native +SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap @cpu-emulation @privileged + +# Denying access to capabilities that should not be relevant for webapps +# Doc: https://man7.org/linux/man-pages/man7/capabilities.7.html +CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD +CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE +CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT +CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK +CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM +CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG +CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE +CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW +CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG + +[Install] +WantedBy=multi-user.target diff --git a/conf/synapse.service b/conf/synapse.service index ab8a2fcf..31d18d74 100644 --- a/conf/synapse.service +++ b/conf/synapse.service @@ -1,14 +1,14 @@ [Unit] Description=Synapse Matrix homeserver -After=network.target +After=network.target postgresql.service [Service] Type=simple User=__APP__ -WorkingDirectory=/opt/yunohost/matrix-__APP__ +WorkingDirectory=__INSTALL_DIR__ BindPaths=/etc/matrix-__APP__ -ExecStartPre=/opt/yunohost/matrix-__APP__/bin/python -m synapse.app.homeserver --config-path=/etc/matrix-__APP__/homeserver.yaml --config-path=/etc/matrix-__APP__/conf.d/ --generate-keys -ExecStart=/opt/yunohost/matrix-__APP__/bin/python -m synapse.app.homeserver --config-path=/etc/matrix-__APP__/homeserver.yaml --config-path=/etc/matrix-__APP__/conf.d/ +ExecStartPre=__INSTALL_DIR__/venv/bin/python -m synapse.app.homeserver --config-path=/etc/matrix-__APP__/homeserver.yaml --config-path=/etc/matrix-__APP__/conf.d/ --generate-keys +ExecStart=__INSTALL_DIR__/venv/bin/python -m synapse.app.homeserver --config-path=/etc/matrix-__APP__/homeserver.yaml --config-path=/etc/matrix-__APP__/conf.d/ Restart=always RestartSec=3 diff --git a/config_panel.toml b/config_panel.toml index f40486a5..72e84016 100644 --- a/config_panel.toml +++ b/config_panel.toml @@ -14,13 +14,14 @@ services = ["__APP__"] no = "false" help = "Defaults to 'false'. If 'true', it is highly recommended to use either captcha, email, or token-based verification to avoid SPAM." - [main.welcome.password_enabled] - ask = "Enable Password Login" - type = "boolean" - yes = "true" - no = "false" - help = "If disabled, Login with Non-YunoHost Users impossible. But it simplies Login process if your Matrix server only has YunoHost SSO Users." - visible = "! enable_registration" + # Disabled for matrix V2 because some client like Element X don't support cas and so require to have password authentication enabled + # [main.welcome.password_enabled] + # ask = "Enable Password Login" + # type = "boolean" + # yes = "true" + # no = "false" + # help = "If disabled, Login with Non-YunoHost Users impossible. But it simplies Login process if your Matrix server only has YunoHost SSO Users." + # visible = "! enable_registration" [main.welcome.registrations_require_3pid] ask = "Registration requires all following 3PID personal identifier" @@ -233,3 +234,10 @@ services = ["__APP__"] yes = "true" no = "false" help = "Enabling TLS/DTLS is really recommanded but it could bring some issues depending of the server certificate. There are some known issues with let's encrypt (https://github.com/element-hq/element-android/issues/1533), so if you have issues it could be better to disable this feature." + + [advanced.security.allow_to_send_request_to_localhost] + ask = "Allow synapse to send request to localhost" + type = "boolean" + yes = "true" + no = "false" + help = "This could be needed by example if you self host on the same Yunohost instance a ntfy server for notifications. In this case to allow synapse to contact the ntfy server you will need to enable this settings." diff --git a/doc/ADMIN.md b/doc/ADMIN.md index 309e69a0..cabc609e 100644 --- a/doc/ADMIN.md +++ b/doc/ADMIN.md @@ -23,7 +23,7 @@ So you can follow this process to set the user as admin: - On the Yunohost Webadmin, go on: Applications > Synapse > Main Settings > On the "Add admin user" section you can select the user to set as admin. - You can run this following script: ```bash -/opt/yunohost/matrix-__APP__/set_admin_user.sh '@:' +__INSTALL_DIR__/set_admin_user.sh '@:' ``` ## Access by federation @@ -71,7 +71,7 @@ To prevent the situation when the server is behind a NAT, the public IP is writt If you have a dynamic IP address, you also might need to update this config automatically. To do that just edit a file named `/etc/cron.d/coturn_config_rotate` and add the following content (just adapt the `` which could be `synapse` or maybe `synapse__2`). ``` -*/15 * * * * root bash /opt/yunohost/matrix-/Coturn_config_rotate.sh; +*/15 * * * * root bash /var/www//Coturn_config_rotate.sh; ``` ## OpenVPN diff --git a/manifest.toml b/manifest.toml index 90ea6ad2..54cfee56 100644 --- a/manifest.toml +++ b/manifest.toml @@ -10,7 +10,7 @@ version = "1.129.0~ynh1" maintainers = ["Josué Tille"] [upstream] -license = "Apache-2.0" +license = "AGPL-3.0,Apache-2.0" website = "https://matrix.org/" code = "https://github.com/element-hq/synapse" admindoc = "https://matrix-org.github.io/synapse/latest/welcome_and_overview.html" @@ -20,7 +20,11 @@ fund = "https://matrix.org/support/#" [integration] yunohost = ">= 11.2.30" helpers_version = "2.1" -architectures = "all" +architectures = [ + "amd64", + "armhf", + "arm64" +] multi_instance = true ldap = true sso = "not_relevant" @@ -34,11 +38,14 @@ ram.runtime = "1G" type = "domain" [install.server_name] - ask.en = "If your Synapse domain is a subdomain, you can choose a name for your Synapse server to have your Matrix user-ids looking like @user:domain.org instead of @user:synapse.domain.org" - ask.fr = "Si votre domaine pour Synapse est un sous-domaine, vous pouvez choisir un nom pour votre serveur Synapse afin que vos identifiants Matrix soient @utilisateur:domain.org plutôt que @utilisateur:synapse.domain.org" + ask.en = "Chose a server name if (optional)" + ask.fr = "Choissez un nom de serveur (optionnel)" + help.en = "If your Synapse domain is a subdomain, you can choose a name for your Synapse server to have your Matrix user-ids looking like @user:domain.org instead of @user:synapse.domain.org. Leave the value empty to use the same value than the domain." + help.fr = "Si votre domaine pour Synapse est un sous-domaine, vous pouvez choisir un nom pour votre serveur Synapse afin que vos identifiants Matrix soient @utilisateur:domain.org plutôt que @utilisateur:synapse.domain.org. Laissez la valeur vide afin d'utiliser le même nom que le domaine." type = "string" example = "domain.org" - default = "Same than the domain" + default = "" + optional = true [install.is_free_registration] ask.en = "Is it a server with free registration?" @@ -48,13 +55,6 @@ ram.runtime = "1G" type = "boolean" default = false - [install.jitsi_server] - ask.en = "Jitsi server address for conferencing?" - ask.fr = "Adresse du serveur Jitsi pour les conférences ?" - type = "string" - example = "domain.org" - default = "jitsi.riot.im" - [install.init_main_permission] help.en = "Define the users allowed to access to synapse. Setting this to 'visitors' don't make sens in this case." type = "group" @@ -72,9 +72,28 @@ ram.runtime = "1G" armhf.url = "https://github.com/YunoHost-Apps/synapse_python_build/releases/download/v1.129.0/matrix-synapse_1.129.0-bullseye-bin1_armv7l.tar.gz" armhf.sha256 = "ca44cb9c004f8515b83cf9bda7e66d77a46514bfafdd16486adcfb5e588657f8" + [resources.sources.lk_jwt] + prefetch = true + extract = true + + url = "https://github.com/element-hq/lk-jwt-service/archive/refs/tags/v0.2.3.tar.gz" + sha256 = "68d33629d4aebc12a3bc1bdfc667d052a20f7cc74b44d650abe8f4d8f6a24119" + + [resources.sources.livekit] + prefetch = true + extract = true + in_subdir = false + + amd64.url = "https://github.com/livekit/livekit/releases/download/v1.8.4/livekit_1.8.4_linux_amd64.tar.gz" + amd64.sha256 = "b660f4a72fe493e7c2a27861c403fba3d8c8fec4ce5e223515b26850c24d2dae" + arm64.url = "https://github.com/livekit/livekit/releases/download/v1.8.4/livekit_1.8.4_linux_arm64.tar.gz" + arm64.sha256 = "02f7a7b252d9bd1298e5bc3e301a138cc7d1bc00dc6855fd4c566ff61fb06324" + armhf.url = "https://github.com/livekit/livekit/releases/download/v1.8.4/livekit_1.8.4_linux_armv7.tar.gz" + armhf.sha256 = "0157cbb419bc82943c44e4a0548939c04c0f06a4789563f0339de7c359d09814" + [resources.system_user] allow_email = true - home = "/opt/yunohost/matrix-__APP__" + home = "/var/www/__APP__" [resources.install_dir] dir = "/var/www/__APP__" @@ -93,6 +112,7 @@ ram.runtime = "1G" main.protected = true server_api.url = "/_matrix" + server_api.additional_urls = ["/client"] server_api.label = "Server access for client apps" server_api.allowed = "visitors" server_api.auth_header = false @@ -106,6 +126,19 @@ ram.runtime = "1G" admin_api.show_tile = false admin_api.protected = true + server_client_infos.url = "/.well-known/matrix" + server_client_infos.allowed = "visitors" + server_client_infos.auth_header = false + server_client_infos.show_tile = false + server_client_infos.protected = true + + livekit.url = "/livekit" + livekit.label = "Element call backend" + livekit.allowed = "visitors" + livekit.auth_header = false + livekit.show_tile = false + livekit.protected = true + [resources.ports] synapse_tls.default = 8448 synapse_tls.exposed = "TCP" @@ -115,6 +148,10 @@ ram.runtime = "1G" turnserver_alt_tls.default = 5350 turnserver_alt_tls.exposed = "Both" cli.default = 5766 + livekit.default = 7880 + livekit_rtc.default = 7881 + livekit_rtc.exposed = "TCP" + livekit_jwt.default = 8080 [resources.apt] packages = ["coturn", "acl", "postgresql", "php8.3-fpm", diff --git a/scripts/_common.sh b/scripts/_common.sh index 73423474..9090a668 100755 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -1,46 +1,50 @@ readonly python_version="$(python3 -V | cut -d' ' -f2 | cut -d. -f1-2)" -readonly code_dir="/opt/yunohost/matrix-$app" -readonly domain_whitelist_client="$(yunohost --output-as json domain list | jq -r '.domains | .[]')" +go_version=1.24.2 +readonly domains_list="$(yunohost --output-as json domain list | jq -r '.domains | .[]')" +# +# TODO Ideally we must have a dedicated domain for this but for now it's not supported +# so we just use the main app domain +# Since Yunohost support multiple domain for the same app we should move it to sfu.$domain +# +readonly sfu_domain="$domain" install_sources() { # Install/upgrade synapse in virtualenv # Clean venv is it was on python2.7 or python3 with old version in case major upgrade of debian - if [ ! -e "$code_dir"/bin/python3 ] || [ ! -e "$code_dir/lib/python$python_version" ]; then - ynh_safe_rm "$code_dir"/bin - ynh_safe_rm "$code_dir"/lib - ynh_safe_rm "$code_dir"/lib64 - ynh_safe_rm "$code_dir"/include - ynh_safe_rm "$code_dir"/share - ynh_safe_rm "$code_dir"/pyvenv.cfg + if [ ! -e "$install_dir/venv"/bin/python3 ] || [ ! -e "$install_dir/venv/lib/python$python_version" ]; then + ynh_safe_rm "$install_dir/venv"/bin + ynh_safe_rm "$install_dir/venv"/lib + ynh_safe_rm "$install_dir/venv"/lib64 + ynh_safe_rm "$install_dir/venv"/include + ynh_safe_rm "$install_dir/venv"/share + ynh_safe_rm "$install_dir/venv"/pyvenv.cfg fi - mkdir -p "$code_dir" - chown "$app":root -R "$code_dir" + mkdir -p "$install_dir/venv" + chown "$app":root -R "$install_dir/venv" if [ -n "$(uname -m | grep arm)" ] then # Clean old file, sometimes it could make some big issues if we don't do this!! - ynh_safe_rm "$code_dir"/bin - ynh_safe_rm "$code_dir"/lib - ynh_safe_rm "$code_dir"/include - ynh_safe_rm "$code_dir"/share + ynh_safe_rm "$install_dir/venv"/bin + ynh_safe_rm "$install_dir/venv"/lib + ynh_safe_rm "$install_dir/venv"/include + ynh_safe_rm "$install_dir/venv"/share - ynh_setup_source --dest_dir="$code_dir"/ --source_id="synapse_prebuilt_armv7_$(lsb_release --codename --short)" + ynh_setup_source --dest_dir="$install_dir/venv"/ --source_id="synapse_prebuilt_armv7_$(lsb_release --codename --short)" # Fix multi-instance support - for f in "$code_dir"/bin/*; do - if ! [[ $f =~ "__" ]]; then - ynh_replace_regex --match='#!/opt/yunohost/matrix-synapse' --replace='#!'"$code_dir" --file="$f" - fi + for f in "$install_dir/venv"/bin/*; do + ynh_replace_regex --match='#!/opt/yunohost/matrix-synapse' --replace='#!'"$install_dir/venv" --file="$f" done else # Install virtualenv if it don't exist - test -e "$code_dir"/bin/python3 || python3 -m venv "$code_dir" + test -e "$install_dir/venv"/bin/python3 || python3 -m venv "$install_dir/venv" # Install synapse in virtualenv - local pip3="$code_dir"/bin/pip3 + local pip3="$install_dir/venv"/bin/pip3 $pip3 install --upgrade setuptools wheel pip cffi $pip3 install --upgrade -r "$YNH_APP_BASEDIR/conf/requirement_$(lsb_release --codename --short).txt" @@ -48,11 +52,35 @@ install_sources() { # Apply patch for LDAP auth if needed # Note that we put patch into scripts dir because /source are not stored and can't be used on restore - if ! grep -F -q '# LDAP Filter anonymous user Applied' "$code_dir/lib/python$python_version/site-packages/ldap_auth_provider.py"; then - pushd "$code_dir/lib/python$python_version/site-packages" + if ! grep -F -q '# LDAP Filter anonymous user Applied' "$install_dir/venv/lib/python$python_version/site-packages/ldap_auth_provider.py"; then + pushd "$install_dir/venv/lib/python$python_version/site-packages" patch < "$YNH_APP_BASEDIR"/scripts/patch/ldap_auth_filter_anonymous_user.patch popd fi + + # Install livekit jwt + ynh_setup_source --source_id=lk_jwt --dest_dir="$install_dir/lk_jwt" + + ynh_hide_warnings ynh_go_install + chown "$app" -R "$install_dir" + + pushd "$install_dir/lk_jwt" + ynh_hide_warnings ynh_exec_as_app go build -o lk-jwt-service . + popd + + # Install livekit server for element-call + ynh_setup_source --source_id=livekit --dest_dir="$install_dir/livekit" +} + +get_lk_node_ip() { + local public_ip4 + public_ip4="$(curl -s https://ip.yunohost.org)" || true + + lk_node_ip="" + if [ -n "$public_ip4" ] && ynh_validate_ip --family=4 --ip_address="$public_ip4" + then + lk_node_ip="--node-ip $public_ip4" + fi } configure_coturn() { @@ -77,23 +105,33 @@ configure_coturn() { configure_nginx() { local e2e_enabled_by_default_client_config + if [ "$e2e_enabled_by_default" == "off" ]; then + e2e_enabled_by_default_client_config=false + else + e2e_enabled_by_default_client_config=true + fi # Create .well-known redirection for access by federation - if yunohost --output-as plain domain list | grep -q "^$server_name$" + if yunohost --output-as plain domain list | grep -q "^$server_name$" && [ "$server_name" != "$domain" ] then - local e2e_enabled_by_default_client_config - if [ "$e2e_enabled_by_default" == "off" ]; then - e2e_enabled_by_default_client_config=false - else - e2e_enabled_by_default_client_config=true - fi ynh_config_add --template="server_name.conf" --destination="/etc/nginx/conf.d/${server_name}.d/${app}_server_name.conf" fi + ynh_config_add --template='nginx.conf.inc' --destination="/etc/nginx/conf.d/${domain}.d/${app}.conf.inc" + # Create a dedicated NGINX config ynh_config_add_nginx } +configure_php() { + ynh_config_add_phpfpm + ynh_replace --match="chdir = $install_dir" \ + --replace="chdir = $install_dir/cas" \ + --file="/etc/php/$php_version/fpm/pool.d/$app.conf" + ynh_store_file_checksum "/etc/php/$php_version/fpm/pool.d/$app.conf" + ynh_systemctl --service="php$php_version-fpm" --action=reload +} + ensure_vars_set() { ynh_app_setting_set_default --app="$app" --key=report_stats --value=false ynh_app_setting_set_default --app="$app" --key=e2e_enabled_by_default --value=invite @@ -113,6 +151,8 @@ ensure_vars_set() { ynh_app_setting_set --key=web_client_location --value="$web_client_location" fi + ynh_app_setting_set_default --app="$app" --key=jitsi_server --value=jitsi.riot.im + ynh_app_setting_set_default --app="$app" --key=client_base_url --value="$web_client_location" ynh_app_setting_set_default --app="$app" --key=invite_client_location --value="$web_client_location" @@ -136,18 +176,21 @@ ensure_vars_set() { ynh_app_setting_set_default --app="$app" --key=enable_3pid_lookup --value=false ynh_app_setting_set_default --app="$app" --key=push_include_content --value=true ynh_app_setting_set_default --app="$app" --key=enable_dtls_for_audio_video_turn_call --value=true + ynh_app_setting_set_default --app="$app" --key=allow_to_send_request_to_localhost --value=false + + ynh_app_setting_set_default --app="$app" --key=livekit_secret --value="$(ynh_string_random --length=40)" } set_permissions() { chown -R "$app:$app" "$install_dir" chmod -R u+rwX,g+rX-w,o= "$install_dir" - chown -R "$app":"$app" "$code_dir" - chmod -R u+rwX,g+rX-w,o= "$code_dir" + chmod 750 "$install_dir"/Coturn_config_rotate.sh + chmod 700 "$install_dir"/update_synapse_for_appservice.sh + chmod 700 "$install_dir"/set_admin_user.sh - chmod 750 "$code_dir"/Coturn_config_rotate.sh - chmod 700 "$code_dir"/update_synapse_for_appservice.sh - chmod 700 "$code_dir"/set_admin_user.sh + chmod 640 "$install_dir"/cas/cas_server.php + chown "$app":www-data "$install_dir" "$install_dir"/cas "$install_dir"/cas/cas_server.php if [ "${1:-}" == data ]; then chmod 750 "$data_dir" diff --git a/scripts/backup b/scripts/backup index dbe1629b..cdb84a32 100644 --- a/scripts/backup +++ b/scripts/backup @@ -20,7 +20,6 @@ ynh_print_info "Declaring files to be backed up..." # BACKUP THE APP MAIN DIR #================================================= -ynh_backup "$code_dir" ynh_backup "$install_dir" #================================================= @@ -31,6 +30,8 @@ ynh_backup "$install_dir" ynh_backup "/etc/php/$php_version/fpm/pool.d/$app.conf" ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" +ynh_backup "/etc/nginx/conf.d/${domain}.d/${app}.conf.inc" + # Backup only server name config if it exist if [ -e "/etc/nginx/conf.d/${server_name}.d/${app}_server_name.conf" ]; then ynh_backup "/etc/nginx/conf.d/${server_name}.d/${app}_server_name.conf" @@ -63,6 +64,8 @@ ynh_backup "/etc/matrix-$app" ynh_backup "/etc/systemd/system/$app.service" ynh_backup "/etc/systemd/system/$app-coturn.service" +ynh_backup /etc/systemd/system/"$app"-livekit.service +ynh_backup /etc/systemd/system/"$app"-lk-jwt.service #================================================= # BACKUP SYNAPSE DATA diff --git a/scripts/change_url b/scripts/change_url index f4fc360c..c4582863 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -19,6 +19,9 @@ ynh_systemctl --service="$app".service --action=stop ynh_script_progression "Updating NGINX configuration..." ynh_config_change_url_nginx +if [ "$domain" != "$old_domain" ]; then + mv "/etc/nginx/conf.d/${old_domain}.d/${app}.conf.inc" "/etc/nginx/conf.d/${domain}.d/${app}.conf.inc" +fi configure_nginx #================================================= @@ -26,6 +29,10 @@ configure_nginx #================================================= ynh_script_progression "Updating Synapse config..." + +# Force enable it because some client like Element X don't support CAS and so require to have password authentication enabled +password_enabled=true + ynh_config_add --jinja --template="homeserver.yaml" --destination="/etc/matrix-$app/homeserver.yaml" ynh_config_add --template="log.yaml" --destination="/etc/matrix-$app/log.yaml" diff --git a/scripts/config b/scripts/config index e2b2345f..26d3635b 100644 --- a/scripts/config +++ b/scripts/config @@ -22,6 +22,10 @@ ynh_app_config_validate() { ynh_app_config_apply() { _ynh_app_config_apply configure_nginx + + # Force enable it because some client like Element X don't support CAS and so require to have password authentication enabled + password_enabled=true + ynh_config_add --jinja --template="homeserver.yaml" --destination="/etc/matrix-$app/homeserver.yaml" ynh_config_add --template="log.yaml" --destination="/etc/matrix-$app/log.yaml" set_permissions diff --git a/scripts/install b/scripts/install index 9a9f133f..fa0b7636 100644 --- a/scripts/install +++ b/scripts/install @@ -14,7 +14,7 @@ ynh_app_setting_set --key=php_upload_max_filesize --value=100M # RETRIEVE ARGUMENTS FROM THE MANIFEST #================================================= -if [ "$server_name" == "Same than the domain" ]; then +if [ -z "$server_name" ]; then server_name="$domain" ynh_app_setting_set --key=server_name --value="$server_name" fi @@ -27,6 +27,8 @@ ynh_script_progression "Storing installation settings..." ensure_vars_set +mkdir -p "$install_dir"/{cas,venv} + if [ "$is_free_registration" -eq 0 ] then enable_registration=false @@ -105,7 +107,7 @@ install_sources # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files -cp ../sources/cas_server.php "$install_dir"/ +cp ../sources/cas_server.php "$install_dir"/cas/ #================================================= # CREATE SYNAPSE CONFIG @@ -114,7 +116,7 @@ cp ../sources/cas_server.php "$install_dir"/ ynh_script_progression "Creating Synapse config..." # Generate config -"$code_dir"/bin/python -m synapse.app.homeserver --keys-directory /etc/matrix-"$app"/ --generate-config --server-name "$server_name" --report-stats=no -c homeserver.yml +"$install_dir/venv"/bin/python -m synapse.app.homeserver --keys-directory /etc/matrix-"$app"/ --generate-config --server-name "$server_name" --report-stats=no -c homeserver.yml # Get random values from config registration_shared_secret="$(grep -E "^registration_shared_secret:" homeserver.yml | cut -d'"' -f2)" @@ -136,6 +138,9 @@ ynh_config_add_systemd --template=synapse.service cp ../conf/default_coturn /etc/matrix-"$app"/coturn_env ynh_config_add_systemd --service="$app"-coturn --template=synapse-coturn.service +get_lk_node_ip +ynh_config_add_systemd --service="$app"-livekit --template=synapse-livekit.service +ynh_config_add_systemd --service="$app"-lk-jwt --template=synapse-lk-jwt.service #================================================= # NGINX CONFIGURATION @@ -145,7 +150,7 @@ ynh_script_progression "Configuring NGINX web server..." # Create a dedicated php-fpm config ynh_script_progression "Configuring application..." -ynh_config_add_phpfpm +configure_php configure_nginx @@ -154,6 +159,9 @@ configure_nginx #================================================= ynh_script_progression "Configuring Synapse..." +# Force enable it because some client like Element X don't support CAS and so require to have password authentication enabled +password_enabled=true + ynh_config_add --jinja --template="homeserver.yaml" --destination="/etc/matrix-$app/homeserver.yaml" ynh_config_add --template="log.yaml" --destination="/etc/matrix-$app/log.yaml" @@ -164,6 +172,14 @@ ynh_script_progression "Configuring Coturn..." configure_coturn +#================================================= +# SET Element call CONFIG +#================================================= +ynh_script_progression "Configuring Element call backend..." --weight=1 + +ynh_config_add --template=livekit.yml --destination=/etc/matrix-"$app"/livekit.yml +ynh_config_add --template=lk-jwt.conf --destination=/etc/matrix-"$app"/lk-jwt.conf + #================================================= # SETUP LOGROTATE #================================================= @@ -178,9 +194,9 @@ ynh_config_add_logrotate "/var/log/matrix-$app" # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files -ynh_config_add --template="../sources/Coturn_config_rotate.sh" --destination="$code_dir/Coturn_config_rotate.sh" -ynh_config_add --template="../sources/update_synapse_for_appservice.sh" --destination="$code_dir/update_synapse_for_appservice.sh" -ynh_config_add --template=../sources/set_admin_user.sh --destination="$code_dir"/set_admin_user.sh +ynh_config_add --template="../sources/Coturn_config_rotate.sh" --destination="$install_dir/Coturn_config_rotate.sh" +ynh_config_add --template="../sources/update_synapse_for_appservice.sh" --destination="$install_dir/update_synapse_for_appservice.sh" +ynh_config_add --template=../sources/set_admin_user.sh --destination="$install_dir"/set_admin_user.sh #================================================= # SETUP PERMISSIONS @@ -189,9 +205,7 @@ ynh_config_add --template=../sources/set_admin_user.sh --destination="$code_dir" ynh_script_progression "Configuring permissions..." if yunohost --output-as plain domain list | grep -q "^$server_name$"; then - ynh_""permission_create --permission=server_client_infos --url="$server_name"/.well-known/matrix \ - --show_tile=false --allowed=visitors \ - --auth_header=false --protected=true + ynh_""permission_url --permission=server_client_infos --add_url="$server_name"/.well-known/matrix else ynh_print_warn "Note yunohost won't be able to manage the required config for $server_name. So please add the needed DNS config as described on the documentation" fi @@ -218,6 +232,8 @@ set_permissions data yunohost service add "$app" --log "/var/log/matrix-$app/homeserver.log" --needs_exposed_ports "$port_synapse_tls" --description 'Main matrix server service.' yunohost service add "$app"-coturn --needs_exposed_ports "$port_turnserver_tls" --description 'Turn server for matrix server. Used for audio and video call.' +yunohost service add "$app"-livekit --description 'Livekit server for element call.' +yunohost service add "$app"-lk-jwt --description 'RTC Livekit JWT service for element call.' #================================================= # RELOAD SERVICES @@ -226,6 +242,8 @@ ynh_script_progression "Restarting Synapse services..." ynh_systemctl --service="$app"-coturn.service --action=restart ynh_systemctl --service="$app".service --action=restart --wait_until="Synapse now listening on TCP port $port_synapse_tls" --log_path="/var/log/matrix-$app/homeserver.log" --timeout=300 +ynh_systemctl --service="$app"-livekit.service --action=restart +ynh_systemctl --service="$app"-lk-jwt.service --action=restart #================================================= # SETUP FAIL2BAN diff --git a/scripts/remove b/scripts/remove index c9d19535..7317764e 100755 --- a/scripts/remove +++ b/scripts/remove @@ -13,6 +13,8 @@ source /usr/share/yunohost/helpers # Remove a service from the admin panel, added by `yunohost service add` yunohost service remove "$app" yunohost service remove "$app"-coturn +yunohost service remove "$app"-livekit +yunohost service remove "$app"-lk-jwt #================================================= # STOP AND REMOVE SERVICE @@ -20,17 +22,18 @@ yunohost service remove "$app"-coturn ynh_script_progression "Stopping and removing the systemd service" ynh_config_remove_systemd - ynh_config_remove_systemd "$app"-coturn +ynh_config_remove_systemd "$app"-livekit +ynh_config_remove_systemd "$app"-lk-jwt #================================================= # REMOVE APP MAIN DIR #================================================= ynh_script_progression "Removing app main directory" -ynh_safe_rm "$code_dir" ynh_safe_rm /etc/matrix-"$app" ynh_safe_rm "/etc/nginx/conf.d/${server_name}.d/${app}_server_name.conf" +ynh_safe_rm "/etc/nginx/conf.d/${domain}.d/${app}.conf.inc" #================================================= # REMOVE NGINX CONFIGURATION diff --git a/scripts/restore b/scripts/restore index cf207647..c1550ab5 100644 --- a/scripts/restore +++ b/scripts/restore @@ -62,6 +62,8 @@ ynh_script_progression "Enable systemd services" # systemctl daemon-reload systemctl enable "$app".service --quiet systemctl enable "$app"-coturn.service --quiet +systemctl enable "$app"-livekit.service --quiet +systemctl enable "$app"-lk-jwt.service --quiet #================================================= # ADVERTISE SERVICE IN ADMIN PANEL @@ -69,6 +71,8 @@ systemctl enable "$app"-coturn.service --quiet yunohost service add "$app" --log "/var/log/matrix-$app/homeserver.log" --needs_exposed_ports $port_synapse_tls --description 'Main matrix server service.' yunohost service add "$app-coturn" --needs_exposed_ports "$port_turnserver_tls" --description 'Turn server for matrix server. Used for audio and video call.' +yunohost service add "$app"-livekit --description 'Livekit server for element call.' +yunohost service add "$app"-lk-jwt --description 'RTC Livekit JWT service for element call.' #================================================= # CREATE A DH FILE @@ -114,6 +118,8 @@ ynh_script_progression "Restarting Synapse services..." ynh_systemctl --service="$app"-coturn.service --action=restart ynh_systemctl --service="$app".service --action=restart --wait_until="Synapse now listening on TCP port $port_synapse_tls" --log_path="/var/log/matrix-$app/homeserver.log" --timeout=300 +ynh_systemctl --service="$app"-livekit.service --action=restart +ynh_systemctl --service="$app"-lk-jwt.service --action=restart #================================================= # RELOAD NGINX diff --git a/scripts/upgrade b/scripts/upgrade index 383c368b..9293c414 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -26,6 +26,7 @@ if [ -z "${domain:-}" ]; then fi ensure_vars_set +mkdir -p "$install_dir"/{cas,venv} # Define $server_name if not already defined ynh_app_setting_set_default --app="$app" --key=server_name --value="$domain" @@ -78,13 +79,13 @@ then fi # remove legacy env file into /etc/default -ynh_safe_rm /etc/default/coturn-$app +ynh_safe_rm /etc/default/coturn-"$app" #================================================= # MIGRATION 7 : STANDARDIZE SYSTEMD UNIT #================================================= -if [ -e /etc/systemd/system/matrix-$app.service ] +if [ -e /etc/systemd/system/matrix-"$app".service ] then ynh_script_progression 'Migrating systemd unit to standard name...' @@ -106,7 +107,10 @@ fi #================================================= # We stop the service -ynh_systemctl --service=$app.service --action=stop +ynh_systemctl --service="$app".service --action=stop +ynh_systemctl --service="$app"-coturn.service --action=stop +ynh_systemctl --service="$app"-livekit.service --action=stop +ynh_systemctl --service="$app"-lk-jwt.service --action=stop ynh_script_progression 'Managing migrations...' @@ -194,9 +198,9 @@ fi # MIGRATION 9 : migrate data path (from matrix-$app to $app) #================================================= -if [ -e /home/yunohost.app/matrix-$app ]; then - mv -t $data_dir /home/yunohost.app/matrix-$app/* - ynh_safe_rm /home/yunohost.app/matrix-$app +if [ -e /home/yunohost.app/matrix-"$app" ]; then + mv -t "$data_dir" /home/yunohost.app/matrix-"$app"/* + ynh_safe_rm /home/yunohost.app/matrix-"$app" fi #================================================= @@ -224,15 +228,24 @@ if grep -q "^matrix-$app" /etc/passwd; then systemctl stop php8.3-fpm.service || true ynh_''system_user_delete --username=matrix-"$app" || true - yunohost user delete $app || true - ynh_''system_user_create --username=$app --home_dir=$code_dir - adduser $app ssl-cert + yunohost user delete "$app" || true + ynh_''system_user_create --username="$app" --home_dir="$install_dir"/venv + adduser "$app" ssl-cert systemctl start php7.4-fpm.service || true systemctl start php8.2-fpm.service || true systemctl start php8.3-fpm.service || true fi +#================================================= +# MIGRATION : some cleanup ... +#================================================= + +ynh_safe_rm /opt/yunohost/matrix-"$app" + +# Clean old server_name config if $server_name == $domain because now it's provided by the main nginx config +ynh_safe_rm "/etc/nginx/conf.d/${domain}.d/${app}_server_name.conf" + #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= @@ -249,7 +262,7 @@ then ynh_script_progression "Generating synapse secret..." # Generate config and keys - "$code_dir"/bin/python -m synapse.app.homeserver --keys-directory /etc/matrix-"$app"/ --generate-config --generate-keys --server-name "$server_name" --report-stats=no -c homeserver.yml + "$install_dir/venv"/bin/python -m synapse.app.homeserver --keys-directory /etc/matrix-"$app"/ --generate-config --generate-keys --server-name "$server_name" --report-stats=no -c homeserver.yml # Get random values from config registration_shared_secret=$(egrep "^registration_shared_secret:" homeserver.yml | cut -d'"' -f2) @@ -260,12 +273,32 @@ then ynh_app_setting_set --key=form_secret --value="$form_secret" fi +#================================================= +# MIGRATION 13 : REMOVE SLIDING SYNC PROXY COMPONENTS +#================================================= +ynh_script_progression "Cleaning sliding sync proxy components..." + +if ynh_''psql_database_exists "${db_name}"_slidingproxy; then + ynh_''psql_drop_db "${db_name}"_slidingproxy +fi + +ynh_safe_rm /etc/matrix-"$app"/sliding_proxy.conf + +test -e /etc/systemd/system/"$app"-sliding-proxy.service && (yunohost service remove "$app"-sliding-proxy || true) +ynh_config_remove_systemd "$app"-sliding-proxy + +#================================================= +# STANDARD UPGRADE STEPS #================================================= #================================================= # UPDATE SYNAPSE CONFIG #================================================= ynh_script_progression "Updating synapse config..." + +# Force enable it because some client like Element X don't support CAS and so require to have password authentication enabled +password_enabled=true + ynh_config_add --jinja --template="homeserver.yaml" --destination="/etc/matrix-$app/homeserver.yaml" ynh_config_add --template="log.yaml" --destination="/etc/matrix-$app/log.yaml" @@ -275,10 +308,7 @@ ynh_config_add --template="log.yaml" --destination="/etc/matrix-$app/log.yaml" # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files -mkdir -p "$install_dir" -cp ../sources/cas_server.php "$install_dir"/ -chmod u=rwX,g=rX,o= -R "$install_dir" -chown "$app":root -R "$install_dir" +cp ../sources/cas_server.php "$install_dir"/cas/ #================================================= # NGINX CONFIGURATION @@ -288,7 +318,7 @@ ynh_script_progression "Upgrading NGINX web server configuration..." # Create a dedicated php-fpm config ynh_script_progression "Configuring application..." -ynh_config_add_phpfpm +configure_php configure_nginx @@ -299,6 +329,14 @@ ynh_script_progression "Updating Coturn config..." configure_coturn +#================================================= +# SET Element call CONFIG +#================================================= +ynh_script_progression "Configuring Element call..." --weight=1 + +ynh_config_add --template=livekit.yml --destination=/etc/matrix-"$app"/livekit.yml +ynh_config_add --template=lk-jwt.conf --destination=/etc/matrix-"$app"/lk-jwt.conf + #================================================= # ADD SCRIPT FOR COTURN CRON AND APP SERVICE #================================================= @@ -306,9 +344,9 @@ configure_coturn # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files -ynh_config_add --template="../sources/Coturn_config_rotate.sh" --destination="$code_dir/Coturn_config_rotate.sh" -ynh_config_add --template="../sources/update_synapse_for_appservice.sh" --destination="$code_dir/update_synapse_for_appservice.sh" -ynh_config_add --template=../sources/set_admin_user.sh --destination=$code_dir/set_admin_user.sh +ynh_config_add --template="../sources/Coturn_config_rotate.sh" --destination="$install_dir/Coturn_config_rotate.sh" +ynh_config_add --template="../sources/update_synapse_for_appservice.sh" --destination="$install_dir/update_synapse_for_appservice.sh" +ynh_config_add --template=../sources/set_admin_user.sh --destination="$install_dir"/set_admin_user.sh # Ensure app-service folder has exists and the config file exit (Migration) mkdir -p /etc/matrix-$app/app-service @@ -327,6 +365,8 @@ fi yunohost service add "$app" --log "/var/log/matrix-$app/homeserver.log" --needs_exposed_ports "$port_synapse_tls" --description 'Main matrix server service.' yunohost service add "$app"-coturn --needs_exposed_ports "$port_turnserver_tls" --description 'Turn server for matrix server. Used for audio and video call.' +yunohost service add "$app"-livekit --description 'Livekit server for element call.' +yunohost service add "$app"-lk-jwt --description 'RTC Livekit JWT service for element call.' #================================================= # UPDATE SYSTEMD @@ -338,6 +378,9 @@ ynh_config_add_systemd --template=synapse.service cp ../conf/default_coturn /etc/matrix-"$app"/coturn_env ynh_config_add_systemd --service="$app"-coturn --template=synapse-coturn.service +get_lk_node_ip +ynh_config_add_systemd --service="$app"-livekit --template=synapse-livekit.service +ynh_config_add_systemd --service="$app"-lk-jwt --template=synapse-lk-jwt.service #================================================= # UPGRADE FAIL2BAN @@ -353,16 +396,7 @@ ynh_config_add_fail2ban --logpath=/var/log/matrix-"$app"/homeserver.log ynh_script_progression "Configuring permissions..." if yunohost --output-as plain domain list | grep -q "^$server_name"'$'; then - if ! ynh_""permission_exists --permission=server_client_infos; then - ynh_""permission_create --permission=server_client_infos --url="$server_name"/.well-known/matrix \ - --show_tile=false --allowed=visitors \ - --auth_header=false --protected=true - else yunohost --output-as plain domain list | grep -q "^$server_name"'$' - ynh_""permission_url --permission=server_client_infos --url="$server_name"/.well-known/matrix \ - --auth_header=false - ynh_""permission_update --permission=server_client_infos --show_tile=false \ - --protected=true - fi + ynh_""permission_url --permission=server_client_infos --add_url="$server_name"/.well-known/matrix fi #================================================= @@ -388,6 +422,8 @@ ynh_script_progression "Restarting Synapse services..." ynh_systemctl --service="$app"-coturn.service --action=restart ynh_systemctl --service="$app".service --action=restart --wait_until="Synapse now listening on TCP port $port_synapse_tls" --log_path="/var/log/matrix-$app/homeserver.log" --timeout=300 +ynh_systemctl --service="$app"-livekit.service --action=restart +ynh_systemctl --service="$app"-lk-jwt.service --action=restart #================================================= # END OF SCRIPT diff --git a/tests.toml b/tests.toml index 5aa50cc4..a2b72642 100644 --- a/tests.toml +++ b/tests.toml @@ -5,4 +5,11 @@ test_format = 1.0 [default] test_upgrade_from.3b5a58e5d8b83f292c6160e8908ac662360aa03e.name = "Before packaging v2 (branch old_version_for_CI_6)" + + test_upgrade_from.9431fd9bb466f02b883ef7cce9c0a62c919dd2fb.name = "Before Matrix v2 implementation (branch old_version_for_CI_8)" + + test_upgrade_from.70b585b595bfe63ebf4ef82f11acc7e243740764.name = "Before sliding sync proxy removal" + test_upgrade_from.8ab6186bede11c5856886a8978428a0f09b6d08d.name = "Before helper 2.1" + + test_upgrade_from.92e630366e39aca49dbeb66c9d1b3c3bc2e03b31.name = "Before element call backend"