117 lines
4.7 KiB
Bash
117 lines
4.7 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
if [[ ${EUID} -ne 0 ]]; then
|
|
echo "This installer must run as root" >&2
|
|
exit 1
|
|
fi
|
|
|
|
SOURCE_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
|
MYSQL_ENV=/opt/cangku/shared/mysql.env
|
|
SERVICE_ENV=/etc/cangku-bootstrap/service.env
|
|
|
|
test -f "${MYSQL_ENV}"
|
|
test -f "${SOURCE_DIR}/bootstrap_service.py"
|
|
|
|
apt-get update -qq
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq python3-venv openssl certbot python3-certbot-dns-cloudflare >/dev/null
|
|
|
|
if ! getent passwd cangku-bootstrap >/dev/null; then
|
|
useradd --system --home-dir /var/lib/cangku-bootstrap --create-home --shell /usr/sbin/nologin cangku-bootstrap
|
|
fi
|
|
if ! getent passwd cangku-tunnel >/dev/null; then
|
|
useradd --system --home-dir /var/lib/cangku-tunnel --create-home --shell /bin/bash cangku-tunnel
|
|
fi
|
|
passwd -d cangku-tunnel >/dev/null 2>&1
|
|
|
|
install -d -m 0755 /opt/cangku-bootstrap/app
|
|
install -d -m 0700 -o cangku-bootstrap -g cangku-bootstrap /var/lib/cangku-bootstrap
|
|
install -d -m 0750 -o root -g cangku-bootstrap /etc/cangku-bootstrap
|
|
install -m 0755 "${SOURCE_DIR}/bootstrap_service.py" /opt/cangku-bootstrap/app/bootstrap_service.py
|
|
install -m 0750 "${SOURCE_DIR}/cangku-bootstrapctl" /usr/local/sbin/cangku-bootstrapctl
|
|
|
|
if [[ ! -x /opt/cangku-bootstrap/venv/bin/python ]]; then
|
|
python3 -m venv /opt/cangku-bootstrap/venv
|
|
fi
|
|
/opt/cangku-bootstrap/venv/bin/pip install --disable-pip-version-check -q -r "${SOURCE_DIR}/requirements.txt"
|
|
|
|
if [[ ! -f /var/lib/cangku-bootstrap/ssh_user_ca ]]; then
|
|
sudo -u cangku-bootstrap ssh-keygen -q -t ed25519 -N '' -C cangku-bootstrap-user-ca -f /var/lib/cangku-bootstrap/ssh_user_ca
|
|
fi
|
|
chmod 0600 /var/lib/cangku-bootstrap/ssh_user_ca
|
|
chmod 0644 /var/lib/cangku-bootstrap/ssh_user_ca.pub
|
|
|
|
install -d -m 0700 -o cangku-tunnel -g cangku-tunnel /var/lib/cangku-tunnel/.ssh
|
|
{
|
|
printf 'cert-authority,principals="cangku-tunnel" '
|
|
cat /var/lib/cangku-bootstrap/ssh_user_ca.pub
|
|
} > /var/lib/cangku-tunnel/.ssh/authorized_keys
|
|
chown cangku-tunnel:cangku-tunnel /var/lib/cangku-tunnel/.ssh/authorized_keys
|
|
chmod 0600 /var/lib/cangku-tunnel/.ssh/authorized_keys
|
|
|
|
install -m 0644 "${SOURCE_DIR}/sshd-cangku-tunnel.conf" /etc/ssh/sshd_config.d/60-cangku-tunnel.conf
|
|
sshd -t
|
|
systemctl reload ssh
|
|
|
|
if [[ ! -f "${SERVICE_ENV}" ]]; then
|
|
provisioner_password=$(openssl rand -hex 32)
|
|
token_pepper=$(openssl rand -hex 32)
|
|
umask 0077
|
|
{
|
|
printf 'BOOTSTRAP_BIND_HOST=127.0.0.1\n'
|
|
printf 'BOOTSTRAP_PORT=4092\n'
|
|
printf 'BOOTSTRAP_STATE_DB=/var/lib/cangku-bootstrap/state.sqlite3\n'
|
|
printf 'BOOTSTRAP_TOKEN_PEPPER=%s\n' "${token_pepper}"
|
|
printf 'BOOTSTRAP_MYSQL_HOST=127.0.0.1\n'
|
|
printf 'BOOTSTRAP_MYSQL_PORT=3307\n'
|
|
printf 'BOOTSTRAP_MYSQL_DATABASE=cangku_system\n'
|
|
printf 'BOOTSTRAP_MYSQL_USER=cangku_bootstrap\n'
|
|
printf 'BOOTSTRAP_MYSQL_PASSWORD=%s\n' "${provisioner_password}"
|
|
printf 'BOOTSTRAP_SSH_CA_KEY=/var/lib/cangku-bootstrap/ssh_user_ca\n'
|
|
printf 'BOOTSTRAP_SSH_HOST_KEY=/etc/ssh/ssh_host_ed25519_key.pub\n'
|
|
printf 'BOOTSTRAP_SSH_HOST=103.236.66.132\n'
|
|
printf 'BOOTSTRAP_SSH_PORT=22\n'
|
|
printf 'BOOTSTRAP_SSH_USER=cangku-tunnel\n'
|
|
printf 'BOOTSTRAP_REMOTE_DB_HOST=127.0.0.1\n'
|
|
printf 'BOOTSTRAP_REMOTE_DB_PORT=3307\n'
|
|
printf 'BOOTSTRAP_CERT_DAYS=30\n'
|
|
} > "${SERVICE_ENV}"
|
|
chown root:cangku-bootstrap "${SERVICE_ENV}"
|
|
chmod 0640 "${SERVICE_ENV}"
|
|
else
|
|
provisioner_password=$(sed -n 's/^BOOTSTRAP_MYSQL_PASSWORD=//p' "${SERVICE_ENV}")
|
|
fi
|
|
|
|
set -a
|
|
source "${MYSQL_ENV}"
|
|
set +a
|
|
docker exec -i -e MYSQL_PWD="${MYSQL_ROOT_PASSWORD}" cangku-mysql mysql -uroot <<EOF
|
|
CREATE USER IF NOT EXISTS 'cangku_bootstrap'@'%' IDENTIFIED BY '${provisioner_password}';
|
|
ALTER USER 'cangku_bootstrap'@'%' IDENTIFIED BY '${provisioner_password}';
|
|
GRANT CREATE USER ON *.* TO 'cangku_bootstrap'@'%';
|
|
GRANT ALL PRIVILEGES ON cangku_system.* TO 'cangku_bootstrap'@'%' WITH GRANT OPTION;
|
|
EOF
|
|
unset MYSQL_ROOT_PASSWORD MYSQL_PASSWORD provisioner_password token_pepper
|
|
|
|
install -m 0644 "${SOURCE_DIR}/cangku-bootstrap.service" /etc/systemd/system/cangku-bootstrap.service
|
|
test -f /etc/letsencrypt/live/ck.yydd.ai/fullchain.pem
|
|
install -m 0644 "${SOURCE_DIR}/nginx-bootstrap.conf" /etc/nginx/sites-available/cangku-bootstrap
|
|
ln -sfn /etc/nginx/sites-available/cangku-bootstrap /etc/nginx/sites-enabled/cangku-bootstrap
|
|
nginx -t
|
|
systemctl daemon-reload
|
|
systemctl enable --now cangku-bootstrap
|
|
systemctl enable --now certbot.timer
|
|
ufw allow 80/tcp comment 'HTTP and ACME' >/dev/null
|
|
ufw allow 8443/tcp comment 'Cangku bootstrap HTTPS' >/dev/null
|
|
systemctl reload nginx
|
|
|
|
for _ in {1..20}; do
|
|
if curl --silent --show-error --fail https://ck.yydd.ai:8443/health >/dev/null; then
|
|
exit 0
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
|
|
journalctl -u cangku-bootstrap -n 50 --no-pager >&2
|
|
exit 1
|