327 lines
9.3 KiB
Bash
Executable File
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"
|