#!/bin/bash #================================================= # GENERIC START #================================================= # IMPORT GENERIC HELPERS #================================================= source _common.sh source experimental_helper.sh source /usr/share/yunohost/helpers # Exit if an error occurs during the execution of the script ynh_abort_if_errors #================================================= # LOAD SETTINGS #================================================= ynh_script_progression --message="Loading installation settings..." --weight=3 app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) server_name=$(ynh_app_setting_get --app=$app --key=server_name) jitsi_server=$(ynh_app_setting_get --app=$app --key=jitsi_server) path_url=$(ynh_app_setting_get --app=$app --key=path) final_path=$(ynh_app_setting_get --app=$app --key=final_path) synapse_old_version=$(ynh_app_setting_get --app=$app --key=synapse_version) is_free_registration=$(ynh_app_setting_get --app=$app --key=is_free_registration) port=$(ynh_app_setting_get --app=$app --key=synapse_port) synapse_tls_port=$(ynh_app_setting_get --app=$app --key=synapse_tls_port) turnserver_tls_port=$(ynh_app_setting_get --app=$app --key=turnserver_tls_port) turnserver_alt_tls_port=$(ynh_app_setting_get --app=$app --key=turnserver_alt_tls_port) cli_port=$(ynh_app_setting_get --app=$app --key=cli_port) report_stats=$(ynh_app_setting_get --app=$app --key=report_stats) allow_public_rooms=$(ynh_app_setting_get --app=$app --key=allow_public_rooms) e2e_enabled_by_default=$(ynh_app_setting_get --app=$app --key=e2e_enabled_by_default) synapse_db_pwd=$(ynh_app_setting_get --app=$app --key=synapse_db_pwd) turnserver_pwd=$(ynh_app_setting_get --app=$app --key=turnserver_pwd) registration_shared_secret=$(ynh_app_setting_get --app=$app --key=registration_shared_secret) form_secret=$(ynh_app_setting_get --app=$app --key=form_secret) macaroon_secret_key=$(ynh_app_setting_get --app=$app --key=macaroon_secret_key) synapse_user_app_pwd=$(ynh_app_setting_get --app=$app --key=synapse_user_app_pwd) domain_whitelist_client=$(get_domain_list) main_domain=$(yunohost domain list --output-as json | jq -r .main) #================================================= # SET ALL CONSTANT #================================================= synapse_user="matrix-$app" synapse_user_app="$app" synapse_db_name="matrix_$app" synapse_db_user="matrix_$app" synapse_db_name="matrix_$app" upstream_version=$(ynh_app_upstream_version) upgrade_type=$(ynh_check_app_version_changed) final_www_path="/var/www/$app" data_path="/home/yunohost.app/matrix-$app" #================================================= # ENSURE DOWNWARD COMPATIBILITY #================================================= ynh_script_progression --message="Ensuring downward compatibility..." --weight=1 # Following the discussion here https://github.com/YunoHost-Apps/synapse_ynh/pull/51 we decided to remove definitely the support of the old package migration. if [ -z "$synapse_old_version" ] then ynh_die --message="Update from this synapse version is not available. You need to remove this package and reinstall the new package version." fi #================================================= # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP #================================================= ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=30 # We stop the service before to set ynh_clean_setup ynh_systemd_action --service_name=matrix-$app.service --action=stop # Backup the current version of the app if [ "0$(ynh_app_setting_get --app=$app --key=disable_backup_before_upgrade)" -ne 1 ] then ynh_backup_before_upgrade ynh_clean_setup () { # Clean installation remainings that are not handled by the remove script. ynh_clean_check_starting ynh_restore_upgradebackup } fi #================================================= # STANDARD UPGRADE STEPS #================================================= # MIGRATION 5 : Manage old settings #================================================= # Migrate from settings 'special_domain' to 'domain' and 'special_path' to 'path' if [ -z $domain ]; then domain=$(ynh_app_setting_get --app=$app --key=special_domain) path_url=$(ynh_app_setting_get --app=$app --key=special_path) ynh_app_setting_set --app=$app --key=domain --value=$domain ynh_app_setting_set --app=$app --key=path --value=$path_url ynh_app_setting_delete --app=$app --key=special_domain ynh_app_setting_delete --app=$app --key=special_path ynh_app_setting_set --app=$app --key=no_sso --value true fi # Define $server_name if not already defined if [ -z $server_name ]; then server_name=$domain ynh_app_setting_set --app=$app --key=server_name --value=$domain fi # Define $jitsi_server if not already defined if [ -z $jitsi_server ]; then jitsi_server='jitsi.riot.im' ynh_app_setting_set --app=$app --key=jitsi_server --value=$jitsi_server fi # Define $e2e_enabled_by_default if not already defined if [ -z $e2e_enabled_by_default ]; then e2e_enabled_by_default='true' ynh_app_setting_set --app=$app --key=e2e_enabled_by_default --value=$e2e_enabled_by_default fi if [ -z $report_stats ]; then report_stats="false" ynh_app_setting_set --app=$app --key=report_stats --value=$report_stats fi if [ -z $allow_public_rooms ]; then allow_public_rooms="false" ynh_app_setting_set --app=$app --key=allow_public_rooms --value=$allow_public_rooms fi if [ -z $is_free_registration ]; then is_free_registration=$(ynh_app_setting_get --app=$app --key=is_""public) ynh_app_setting_set --app=$app --key=is_free_registration --value=$is_free_registration fi if [ -z $synapse_user_app_pwd ]; then synapse_user_app_pwd="$(ynh_string_random --length=30)" ynh_app_setting_set --app=$app --key=synapse_user_app_pwd --value=$synapse_user_app_pwd yunohost user create $synapse_user_app -f Synapse -l Application -d $domain -p "$synapse_user_app_pwd" fi #================================================= # MIGRATION 6 : Migrate data directory #================================================= if [ -e "/var/lib/matrix-$app" ]; then ynh_script_progression --message="Moving data directory to $data_path..." --weight=1 if [ -e "$data_path" ]; then old_data_dir_path="$data_path$(date '+%Y%m%d.%H%M%S')" ynh_print_warn "A data directory already exist. Data was renamed to $old_data_dir_path" mv "$data_path" "$old_data_dir_path" fi mv "/var/lib/matrix-$app" "$data_path" fi if ! grep -q "$final_path" /etc/passwd; then # matrix-synapse:x:994:994::/var/lib/matrix-synapse:/usr/sbin/nologin sed --in-place -r "s@matrix-$app\:x\:([[:digit:]]+\:[[:digit:]]+)\:\:/.*/matrix-$app\:/usr/sbin/nologin@matrix-$app\:x\:\1\:\:$final_path\:/usr/sbin/nologin@g" /etc/passwd fi #================================================= # INSTALL DEPENDENCIES #================================================= ynh_script_progression --message="Upgrading dependencies..." --weight=6 # WARNING : theses command are used in INSTALL, UPGRADE, RESTORE # For any update do it in all files ynh_install_app_dependencies $dependances #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= if [ "$upgrade_type" == "UPGRADE_APP" ] || [ ! -e $final_path/bin/python3 ] || [ ! -e $final_path/lib/python$python_version ] then ynh_script_progression --message="Upgrading source files..." --weight=6 install_sources fi #================================================= # CREATE SMALL CAS SERVER #================================================= # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files mkdir -p $final_www_path cp ../sources/cas_server.php $final_www_path/ chmod u=rwX,g=rX,o= -R $final_www_path chown $synapse_user:root -R $final_www_path #================================================= # MIGRATION 1 : GENERATE SYNAPSE SECRET #================================================= if [ -z "$registration_shared_secret" ] || [ "$form_secret" == "form_secret: " ] then ynh_script_progression --message="Generating synapse secret..." --weight=1 # Go in virtualenvironnement set +u source $final_path/bin/activate set -u # Generate config and keys python -m synapse.app.homeserver --keys-directory /etc/matrix-$app/ --generate-config --generate-keys --server-name $server_name --report-stats=no -c homeserver.yml # This function was defined when we called "source $final_path/bin/activate". With this function we undo what "$final_path/bin/activate" does set +u; deactivate set -u; # Get random values from config registration_shared_secret=$(egrep "^registration_shared_secret:" homeserver.yml | cut -d'"' -f2) form_secret=$(egrep "^form_secret:" homeserver.yml | cut -d'"' -f2) # store in yunohost settings ynh_app_setting_set --app=$app --key=registration_shared_secret --value="$registration_shared_secret" ynh_app_setting_set --app=$app --key=form_secret --value="$form_secret" fi #================================================= # UPDATE SYNAPSE CONFIG #================================================= ynh_script_progression --message="Updating synapse config..." --weight=2 # WARNING : theses command are used in INSTALL, UPGRADE, CONFIG, CHANGE-URL (4 times) # For any update do it in all files if [ -z $macaroon_secret_key ]; then # Well, in this package this value was not managed because it was not needed, synapse is able to generate this with some other secret in the config file but after some vulnerability was found with this practice. # For more detail about this issue you can see : https://matrix.org/blog/2019/01/15/further-details-on-critical-security-update-in-synapse-affecting-all-versions-prior-to-0-34-1-cve-2019-5885/ # The problem is that we can't just say generate a new value if the package has not already defined a value. The reason is that changing this value logout all user. And in case of a user has enabled the encryption, the user might lost all conversation !! # So for the old install we just leave this as it is. And for the new install we use a real macaroon. macaroon_secret_key_param='# macaroon_secret_key: ""' else macaroon_secret_key_param='macaroon_secret_key: "'$macaroon_secret_key'"' fi if [ $is_free_registration -eq 0 ] then allowed_access=False sso_enabled=True else allowed_access=True sso_enabled=False fi ynh_add_config --template="homeserver.yaml" --destination="/etc/matrix-$app/homeserver.yaml" ynh_add_config --template="log.yaml" --destination="/etc/matrix-$app/log.yaml" #================================================= # MIGRATION 2 : MULTINSTANCE SUPPORT #================================================= if [ ! -e /etc/matrix-$app/coturn.conf ] then ynh_script_progression --message="Creating an independant service for coturn..." --weight=1 #================================================= # CREATE AN INDEPENDANT SERVICE FOR COTURN #================================================= # Disable default config for turnserver and create a new service systemctl stop coturn.service # Set a port for each service in turnserver turnserver_alt_tls_port=$(ynh_find_port --port=$((turnserver_tls_port+1))) cli_port=$(ynh_find_port --port=5766) ynh_app_setting_set --app=$app --key=turnserver_alt_tls_port --value=$turnserver_alt_tls_port ynh_app_setting_set --app=$app --key=cli_port --value=$cli_port yunohost firewall allow Both $turnserver_alt_tls_port > /dev/null 2>&1 #================================================= # MAKE A CLEAN LOGROTATE CONFIG #================================================= ynh_use_logrotate --logfile /var/log/matrix-$app --nonappend fi #================================================= # MIGRATION 3 : USE STANDARD ACCESS FOR CERTIFCATE #================================================= # Fix issue about certificates access if [ ! $(grep "ssl-cert:x:[0-9]*:.*matrix-$app" /etc/group) ] then ynh_script_progression --message="Use standard access for certificate..." --weight=1 adduser $synapse_user ssl-cert adduser turnserver ssl-cert fi #================================================= # MIGRATION 4 : CREATE A DH FILE #================================================= # WARNING : theses command are used in INSTALL, UPGRADE, RESTORE # For any update do it in all files # Make dh cert for synapse if it doesn't exist if [ ! -e /etc/ssl/private/dh2048.pem ] then ynh_script_progression --message="Creating a dh file..." --weight=1 openssl dhparam -out /etc/ssl/private/dh2048.pem -outform PEM -2 2048 -dsaparam 2> /dev/null chown root:ssl-cert /etc/ssl/private/dh2048.pem chmod 640 /etc/ssl/private/dh2048.pem fi #================================================= # STANDARD UPGRADE STEPS #================================================= # NGINX CONFIGURATION #================================================= ynh_script_progression --message="Upgrading nginx web server configuration..." --weight=2 # Create a dedicated php-fpm config ynh_script_progression --message="Configuring application..." ynh_add_fpm_config # Create .well-known redirection for access by federation if yunohost --output-as plain domain list | grep -q "^$server_name$" then ynh_add_config --template="server_name.conf" --destination="/etc/nginx/conf.d/${server_name}.d/${app}_server_name.conf" fi # Create a dedicated nginx config ynh_add_nginx_config app #================================================= # SPECIFIC UPGRADE #================================================= # UPDATE COTURN CONFIG #================================================= ynh_script_progression --message="Updating coturn config..." --weight=1 # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files # Get public IP and set as external IP for coturn # note : '|| true' is used to ignore the errors if we can't get the public ipv4 or ipv6 public_ip4="$(curl -s ip.yunohost.org)" || true public_ip6="$(curl -s ipv6.yunohost.org)" || true turn_external_ip="" if [ -n "$public_ip4" ] && ynh_validate_ip4 --ip_address="$public_ip4" then turn_external_ip+="\nexternal-ip=$public_ip4" fi if [ -n "$public_ip6" ] && ynh_validate_ip6 --ip_address="$public_ip6" then turn_external_ip+="\nexternal-ip=$public_ip6" fi ynh_add_config --template="turnserver.conf" --destination="/etc/matrix-$app/coturn.conf" #================================================= # ADD SCRIPT FOR COTURN CRON AND APP SERVICE #================================================= # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files ynh_add_config --template="../sources/Coturn_config_rotate.sh" --destination="$final_path/Coturn_config_rotate.sh" ynh_add_config --template="../sources/update_synapse_for_appservice.sh" --destination="$final_path/update_synapse_for_appservice.sh" # Ensure app-service folder has exists and the config file exit (Migration) mkdir -p /etc/matrix-$app/app-service test -e /etc/matrix-$app/conf.d/app_service.yaml || echo "app_service_config_files:" > /etc/matrix-$app/conf.d/app_service.yaml #================================================= # ADVERTISE SERVICE IN ADMIN PANEL #================================================= yunohost service add matrix-$app --log "/var/log/matrix-$app/homeserver.log" --needs_exposed_ports $synapse_tls_port yunohost service add coturn-$app --needs_exposed_ports $turnserver_tls_port #================================================= # UPDATE SYSTEMD #================================================= ynh_script_progression --message="Upgrading systemd configuration..." --weight=3 # Create systemd service for synapse and turnserver cp ../conf/default_matrix-synapse /etc/default/matrix-$app ynh_add_systemd_config --service=matrix-$app --template=matrix-synapse.service cp ../conf/default_coturn /etc/default/coturn-$app ynh_add_systemd_config --service=coturn-$app --template=coturn-synapse.service #================================================= # UPGRADE FAIL2BAN #================================================= ynh_script_progression --message="Reconfiguring fail2ban..." --weight=8 # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files ynh_add_fail2ban_config --use_template #================================================= # GENERIC FINALIZATION #================================================= # SETUP PERMISSIONS #================================================= ynh_script_progression --message="Configuring permissions..." --weight=1 ynh_legacy_permissions_delete_all ynh_permission_url --permission=main --url=$domain/_matrix/cas_server.php/login --auth_header=true ynh_permission_update --permission=main --show_tile=false --protected=true if ! ynh_permission_exists --permission=server_api; then ynh_permission_create --permission=server_api --url=$domain/_matrix \ --label="Server access for client apps." --show_tile=false --allowed=visitors \ --auth_header=false --protected=true python3 remove_sso_conf_persistent.py $domain $server_name \ || ynh_print_warn --message="Your file /etc/ssowat/""conf.json.persistent doesn't respect the json syntax. The config file wasn't cleaned. Please clean it manually." else ynh_permission_url --permission=server_api --url=$domain/_matrix --remove_url=$server_name/.well-known/matrix \ --auth_header=false ynh_permission_update --permission=server_api --label="Server access for client apps." --show_tile=false \ --protected=true fi if yunohost --output-as plain domain list | grep -q "^$server_name"'$' && ! ynh_permission_exists --permission=server_client_infos; then ynh_permission_create --permission=server_client_infos --url=$server_name/.well-known/matrix \ --label="Server info for clients. (well-known)" --show_tile=false --allowed=visitors \ --auth_header=false --protected=true elif yunohost --output-as plain domain list | grep -q "^$server_name"'$'; then ynh_permission_url --permission=server_client_infos --url=$server_name/.well-known/matrix \ --auth_header=false ynh_permission_update --permission=server_client_infos --label="Server info for clients. (well-known)" --show_tile=false \ --protected=true fi if ! ynh_permission_exists --permission=admin_api; then ynh_permission_create --permission=admin_api --url=$domain/_synapse \ --label="Server administration API." --show_tile=false \ --auth_header=false fi #================================================= # SECURE FILES AND DIRECTORIES #================================================= # WARNING : theses command are used in INSTALL, UPGRADE, RESTORE # For any update do it in all files chown $synapse_user:root -R $final_path chmod 770 $final_path/Coturn_config_rotate.sh chmod 700 $final_path/update_synapse_for_appservice.sh chown $synapse_user:root -R $data_path chown $synapse_user:root -R /var/log/matrix-$app chown $synapse_user:root -R /etc/matrix-$app chmod u=rwX,g=rX,o= -R /etc/matrix-$app chmod 600 /etc/matrix-$app/$server_name.signing.key setfacl -R -m user:turnserver:rX /etc/matrix-$app setfacl -R -m user:turnserver:rwX /var/log/matrix-$app #================================================= # UPDATE HOOKS #================================================= # WARNING : theses command are used in INSTALL, UPGRADE # For any update do it in all files ynh_replace_string __APP__ $app ../hooks/post_cert_update ynh_replace_string __DOMAIN__ $domain ../hooks/post_cert_update #================================================= # UPDATE VERSION SETTINGS #================================================= ynh_app_setting_set --app=$app --key=synapse_version --value=$upstream_version #================================================= # RELOAD SERVICES #================================================= ynh_script_progression --message="Restarting synapse services..." --weight=5 ynh_systemd_action --service_name=coturn-$app.service --action=restart ynh_systemd_action --service_name=matrix-$app --action=restart --line_match="Synapse now listening on TCP port $synapse_tls_port" --log_path="/var/log/matrix-$app/homeserver.log" --timeout=300 #================================================= # END OF SCRIPT #================================================= ynh_script_progression --message="Upgrade of $app completed" --last