|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# Copyright (c) 2021-2026 tteck |
| 4 | +# Author: Dan Erickson (derickson2402) |
| 5 | +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE |
| 6 | +# Source: https://matrix-construct.github.io/tuwunel/ |
| 7 | + |
| 8 | +# Required by Community-Scripts framework |
| 9 | +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" |
| 10 | +color |
| 11 | +verb_ip6 |
| 12 | +catch_errors |
| 13 | +setting_up_container |
| 14 | +network_check |
| 15 | +update_os |
| 16 | + |
| 17 | +# Collect server configuration from user |
| 18 | +whiptail --title "Attention!" --msgbox "These options cannot be easily changed! Please read the docs before proceeding." 8 60 3>&1 1>&2 2>&3 |
| 19 | +TUWUNEL_CONF_SERVER_NAME=$(whiptail --title "Server name" --inputbox "Matrix server name, where 'myuser@server-name' will be your public username. Ex: 'example.com'" 8 60 3>&1 1>&2 2>&3) |
| 20 | +TUWUNEL_CONF_TUWUNEL_HOST=$(whiptail --title "Tuwunel hostname" --inputbox "Tuwunel's FQDN, where Tuwunel will be accessed. Ex: 'matrix.example.com'" 8 60 3>&1 1>&2 2>&3) |
| 21 | + |
| 22 | +# Tuwunel distributes seperate binaries depending on the encryption hardware |
| 23 | +# available in the CPU. As of January 2026, binaries are provided for v1,v2, and |
| 24 | +# v3. Use the highest version supported by your CPU. If CPU supports higher (ex. |
| 25 | +# v4), use v3. Their docs provide a helpful script to automate this. See: |
| 26 | +# https://matrix-construct.github.io/tuwunel/deploying/generic.html#static-prebuilt-binary |
| 27 | +msg_info "Identifying CPU architecture and capabilities" |
| 28 | +tuwunel_sys_arch=$(dpkg --print-architecture) |
| 29 | +case "$tuwunel_sys_arch" in |
| 30 | + amd64) tuwunel_arch_tag="x86_64" |
| 31 | + tuwunel_cpu_caps=$(cat /proc/cpuinfo | \ |
| 32 | + grep -Po '(avx|sse)[235]' | sort -u | \ |
| 33 | + sed 's/avx5/v4/;s/avx2/v3/;s/sse3/v2/;s/sse2/v1/' | \ |
| 34 | + sort -V | tail -n1) |
| 35 | + if [[ "$tuwunel_cpu_caps" =~ ^v[0-9]+$ ]] && (( ${tuwunel_cpu_caps#v} > 3 )); then |
| 36 | + # Binaries only go up to v3. More capable CPU's still use this verison |
| 37 | + tuwunel_cpu_caps="v3" |
| 38 | + fi |
| 39 | + if [[ ! "$tuwunel_cpu_caps" =~ ^v[1-3]$ ]]; then |
| 40 | + msg_error "Could not detect valid CPU feature level. Expected [v1, v3], got $tuwunel_cpu_caps" |
| 41 | + exit 1 |
| 42 | + fi |
| 43 | + ;; |
| 44 | + arm64) tuwunel_arch_tag="aarch64" |
| 45 | + # For some reason, ARM CPU's only use v8. Likely because the oldest ARM |
| 46 | + # chips are much newer than older x86 chips |
| 47 | + tuwunel_cpu_caps="v8" |
| 48 | + ;; |
| 49 | + *) msg_error "Unsupported architecture: $tuwunel_sys_arch"; exit 1 ;; |
| 50 | +esac |
| 51 | +msg_ok "Identified ${tuwunel_arch_tag} CPU with ${tuwunel_cpu_caps} capabilities" |
| 52 | + |
| 53 | +# Download and install Tuwunel debian package for this system. Nice and simple, |
| 54 | +# thanks Tuwunel! |
| 55 | +msg_info "Updating system packages" |
| 56 | +$STD apt update -y |
| 57 | +$STD apt upgrade -y |
| 58 | +msg_info "Checking GitHub for latest version" |
| 59 | +tuwunel_version=$(curl -fsSL https://api.github.com/repos/matrix-construct/tuwunel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') |
| 60 | +msg_info "Downloading and installing Tuwunel v${tuwunel_version}" |
| 61 | +tuwunel_deb_url="https://github.com/matrix-construct/tuwunel/releases/download/v${tuwunel_version}/v${tuwunel_version}-release-all-${tuwunel_arch_tag}-${tuwunel_cpu_caps}-linux-gnu-tuwunel.deb" |
| 62 | +tuwunel_deb_path="/tmp/tuwunel.deb" |
| 63 | +curl -fsSL -o "${tuwunel_deb_path}" "${tuwunel_deb_url}" |
| 64 | +$STD dpkg -i "${tuwunel_deb_path}" |
| 65 | +rm -f "${tuwunel_deb_path}" |
| 66 | +echo "${tuwunel_version}" > "/opt/Tuwunel_version.txt" |
| 67 | +echo "${tuwunel_arch_tag}" > "/opt/Tuwunel_arch.txt" |
| 68 | +echo "${tuwunel_cpu_caps}" > "/opt/Tuwunel_cpu_cap.txt" |
| 69 | +msg_ok "Installed Tuwunel v${tuwunel_version}" |
| 70 | + |
| 71 | +# Configure Tuwunel now that it is installed. Debian package creates some of |
| 72 | +# this by default, but we explicitly create it here to ensure it is correct and |
| 73 | +# permissions are set properly |
| 74 | +msg_info "Configuring Tuwunel" |
| 75 | +if ! id tuwunel &>/dev/null; then |
| 76 | + # If the deb package already made the user, this safely skips recreating it |
| 77 | + sudo adduser --system tuwunel --group --disabled-login --no-create-home |
| 78 | +fi |
| 79 | +tuwunel_config_path="/etc/tuwunel/tuwunel.toml" |
| 80 | +tuwunel_reg_token_path="/etc/tuwunel/.reg_token" |
| 81 | +cp "${tuwunel_config_path}" /etc/tuwunel/tuwunel-example.toml |
| 82 | + cat <<EOF >"${tuwunel_config_path}" |
| 83 | +[global] |
| 84 | +# Stop! This cannot be changed without a DB wipe! See the docs for details: |
| 85 | +# https://matrix-construct.github.io/tuwunel/configuration/examples.html?highlight=wipe#example-configuration |
| 86 | +server_name = "${TUWUNEL_CONF_SERVER_NAME}" |
| 87 | +
|
| 88 | +# You can safely leave everything below this line as defaults unless you have |
| 89 | +# specific needs to change them. |
| 90 | +address = "0.0.0.0" |
| 91 | +allow_registration = true |
| 92 | +registration_token_file = "${tuwunel_reg_token_path}" |
| 93 | +
|
| 94 | +[global.well_known] |
| 95 | +client = "https://${TUWUNEL_CONF_TUWUNEL_HOST}" |
| 96 | +server = "${TUWUNEL_CONF_TUWUNEL_HOST}:443" |
| 97 | +EOF |
| 98 | +reg_token=$(openssl rand -base64 200 | tr -dc 'a-zA-Z0-9' | head -c32) |
| 99 | +echo "$reg_token" > "${tuwunel_reg_token_path}" |
| 100 | +chown -R tuwunel:tuwunel /etc/tuwunel |
| 101 | +chmod 755 /etc/tuwunel |
| 102 | +chmod 700 "${tuwunel_reg_token_path}" |
| 103 | +msg_ok "Configured Tuwunel" |
| 104 | + |
| 105 | +# This is the last prompt the user will see after installation is done, so we |
| 106 | +# need to alert them about post-installation setup tasks. |
| 107 | +msg_info "Finishing up and starting server" |
| 108 | +systemctl enable -q --now tuwunel |
| 109 | +msg_warn "" |
| 110 | +msg_warn "Tuwunel is serving well-known json for federation at:" |
| 111 | +msg_warn " http://localhost:8008/.well-known/matrix" |
| 112 | +msg_warn "Tuwunel is serving matrix federation port at:" |
| 113 | +msg_warn " http://localhost:8448" |
| 114 | +msg_warn "" |
| 115 | +msg_warn "Tuwunel expects to be proxied to:" |
| 116 | +msg_warn " https://${TUWUNEL_CONF_TUWUNEL_HOST}" |
| 117 | +msg_warn "Other users look for you (federation) at either address (pick one):" |
| 118 | +msg_warn " https://$TUWUNEL_CONF_SERVER_NAME/.well-known/matrix" |
| 119 | +msg_warn " $TUWUNEL_CONF_SERVER_NAME:8448" |
| 120 | +msg_warn "" |
| 121 | +msg_warn "First registered user gets admin rights. Use the token to register:" |
| 122 | +msg_warn " $reg_token" |
| 123 | +msg_warn "" |
| 124 | +msg_ok "Installation successful!" |
| 125 | + |
| 126 | +# Required by Community-Scripts framework |
| 127 | +motd_ssh |
| 128 | +customize |
| 129 | +cleanup_lxc |
0 commit comments