maubot-installer/install.sh

327 lines
9.3 KiB
Bash
Executable File

#!/bin/bash
panic(){ echo -e "$@"; echo "Exiting."; exit 2; }
spacer(){ echo -e "\n - - - - - - - - - "; }
info(){ echo -e "\e[0;32m$@\e[0m"; }
[[ "root" == $(whoami) ]] || panic "Must run as root."
## PACKAGES MANAGEMENT
packageList=()
packageList+=("certbot")
packageList+=("nginx")
packageList+=("pwgen")
packageList+=("python-pip")
packageList+=("python3-minimal")
packageList+=("python3-distutils")
packageList+=("sqlite3")
packageList+=("virtualenv")
info "Updating packages informations"
apt-get update >/dev/null
info "Installing packages ${packageList[@]}"
apt-get install --no-install-recommends -y ${packageList[@]} >/dev/null
## CONFIG MANAGEMENT
info "OK, time for some questions."
default_pass=$(pwgen -s 16 1)
[[ -f ./config ]] && source ./config
spacer
[[ -z "$domain" ]] && read -p "Which domain will be used to connect to your bot (ex: maubot.example.com)? " domain
[[ -z "$domain" ]] && panic "You must provide a domain"
spacer
[[ -z "$home_server" ]] && read -e -i "matrix.com" -p "Which domain is the matrix 'Home Server' you register your bots on? " home_server
[[ -z "$home_server" ]] && panic "You must provide a matrix server"
spacer
[[ -z "$maubot_user" ]] && read -e -i "maubot" -p "What will be your user name in the maubot interface? " maubot_user
[[ -z "$maubot_user" ]] && panic "You must give a valid username"
spacer
[[ -z "$maubot_pass" ]] && read -e -i $default_pass -p "What will be the pass for user '$maubot_user' in the maubot interface? " maubot_pass
[[ -z "$maubot_pass" ]] && panic "You must give a valid password"
spacer
[[ -z "$ssl" ]] && read -e -i "y" -n 1 -p "Do you want to enable SSL via letsencrypt [Y/n]? " ssl
ssl=${ssl:-y}
spacer
[[ -z "$synapse_shared_registration_secret" ]] && read -p "If the 'Home Server' is yours, what is the registration secret (ignore if you don't know what this is)? " synapse_shared_registration_secret
synapse_shared_registration_secret=${synapse_shared_registration_secret:-synapse_shared_registration_secret}
spacer
[[ -z "$install_dir" ]] && read -e -i "/opt/maubot" -p "Which install dir to use (Default: /opt/maubot)? " install_dir
install_dir=${install_dir:-/opt/maubot}
spacer
[[ -z "$unix_user" ]] && read -e -i "www-data" -p "Which unix user will own and execute the maubot code? " unix_user
unix_user=${unix_user:-www-data}
spacer
## NGINX DEPLOYEMENT
info "Deploying nginx"
cat << HEREDOC > /etc/nginx/sites-available/maubot.conf
server {
listen 80;
server_name $domain;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
}
location /_matrix/maubot/v1/logs {
proxy_pass http://localhost:29316;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For \$remote_addr;
}
location /_matrix/maubot {
proxy_pass http://localhost:29316;
proxy_set_header X-Forwarded-For \$remote_addr;
}
location / {
rewrite ^(.*) http://\$server_name/_matrix/maubot/ permanent;
}
}
HEREDOC
ln -s /etc/nginx/sites-available/maubot.conf /etc/nginx/sites-enabled/
service nginx reload
if [[ "Y" == ${ssl^^} ]]; then
info "Retrieving letsencrypt certificate"
mkdir -p /var/www/letsencrypt/.well-known/acme-challenge/
[[ -f /etc/letsencrypt/live/$domain/fullchain.pem ]] || /usr/bin/letsencrypt certonly --webroot --agree-tos -w /var/www/letsencrypt/ --email "domains@$domain" --expand -d $domain >/dev/null
[[ -f /etc/letsencrypt/live/$domain/fullchain.pem ]] || panic "Failed to get a certificate for domain $domain."
cat << HEREDOC > /etc/nginx/sites-available/maubot.conf
server {
listen 80;
server_name $domain;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
}
location / {
rewrite ^(.*) https://\$server_name\$1 permanent;
}
}
server {
listen 443 ssl;
server_name $domain;
access_log /var/log/nginx/maubot.access.log;
error_log /var/log/nginx/maubot.error.log;
ssl on;
ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_prefer_server_ciphers on;
location /_matrix/maubot/v1/logs {
proxy_pass http://localhost:29316;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For \$remote_addr;
}
location /_matrix/maubot {
proxy_pass http://localhost:29316;
proxy_set_header X-Forwarded-For \$remote_addr;
}
location / {
rewrite ^(.*) https://\$server_name/_matrix/maubot/ permanent;
}
}
HEREDOC
service nginx reload
fi
# MAUBOT DEPLOYMENT
info "Installing maubot"
mkdir -p "$install_dir"
cd "$install_dir"
virtualenv -p /usr/bin/python3 . >/dev/null
source $install_dir/bin/activate
info "Installing maubot dependencies"
pip install --upgrade maubot >/dev/null
mkdir -p $install_dir/{plugins,trash,logs}
cat << HEREDOC > "$install_dir/config.yaml"
# The full URI to the database. SQLite and Postgres are fully supported.
# Other DBMSes supported by SQLAlchemy may or may not work.
# Format examples:
# SQLite: sqlite:///filename.db
# Postgres: postgres://username:password@hostname/dbname
database: sqlite:///maubot.db
plugin_directories:
# The directory where uploaded new plugins should be stored.
upload: ./plugins
# The directories from which plugins should be loaded.
# Duplicate plugin IDs will be moved to the trash.
load:
- ./plugins
# The directory where old plugin versions and conflicting plugins should be moved.
# Set to "delete" to delete files immediately.
trash: ./trash
# The directory where plugin databases should be stored.
db: ./plugins
server:
# The IP and port to listen to.
hostname: 0.0.0.0
port: 29316
# Public base URL where the server is visible.
public_url: https://$domain
# The base management API path.
base_path: /_matrix/maubot/v1
# The base path for the UI.
ui_base_path: /_matrix/maubot
# The base path for plugin endpoints. The instance ID will be appended directly.
plugin_base_path: /_matrix/maubot/plugin/
# Override path from where to load UI resources.
# Set to false to using pkg_resources to find the path.
override_resource_path: false
# The base appservice API path. Use / for legacy appservice API and /_matrix/app/v1 for v1.
appservice_base_path: /_matrix/app/v1
# The shared secret to sign API access tokens.
# Set to "generate" to generate and save a new token at startup.
unshared_secret: generate
# Shared registration secrets to allow registering new users from the management UI
registration_secrets:
example.com:
# Client-server API URL
url: https://$home_server
# registration_shared_secret from synapse config
secret: $synapse_shared_registration_secret
# List of administrator users. Plaintext passwords will be bcrypted on startup. Set empty password
# to prevent normal login. Root is a special user that can't have a password and will always exist.
admins:
root: ""
$maubot_user: "$maubot_pass"
# API feature switches.
api_features:
login: true
plugin: true
plugin_upload: true
instance: true
instance_database: true
client: true
client_proxy: true
client_auth: true
dev_open: true
log: true
# 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:
(): maubot.lib.color_log.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: ./maubot.log
maxBytes: 10485760
backupCount: 10
console:
class: logging.StreamHandler
formatter: colored
loggers:
maubot:
level: DEBUG
mautrix:
level: DEBUG
aiohttp:
level: INFO
root:
level: DEBUG
handlers: [file, console]
HEREDOC
info "Configure database"
alembic -x config=$install_dir/config.yaml upgrade head >/dev/null
# SYSTEMD MANAGEMENT
info "Installing systemd maubot service"
cat << HEREDOC > /etc/systemd/system/maubot.service
[Unit]
Description=Maubot web interface
Documentation=https://github.com/maubot/maubot
Requires=network.target
After=network.target
[Service]
WorkingDirectory=$install_dir
Type=simple
User=www-data
ExecStart=$install_dir/bin/python3 -m maubot
[Install]
WantedBy=multi-user.target
HEREDOC
touch "$install_dir/maubot.log"
chown -R "$unix_user" "$install_dir"
systemctl daemon-reload
systemctl enable maubot
systemctl start maubot
info "Check your service state with 'systemctl status maubot'"
echo -e "\n\nCongratulations, you can now head to http://$domain and use your $maubot_user:$maubot_pass authentication, which of course you should save for future use ;) \n\n"