Files
homelab-docs/homelab/npm-cert-cloud.sh
2026-02-23 16:47:17 +03:00

99 lines
3.4 KiB
Bash

#!/bin/bash
# Выпуск сертификата cloud.katykhin.ru через certbot DNS-01 Beget и подключение к NPM
# Usage: BEGET_USER=логин BEGET_PASS=пароль ./npm-cert-cloud.sh
set -e
DOMAIN="cloud.katykhin.ru"
EMAIL="j3tears100@gmail.com"
# Запуск: ssh root@PROXMOX "pct exec 100 -- bash -s" < npm-cert-cloud.sh
# Или: BEGET_USER=xxx BEGET_PASS=xxx pct exec 100 -- bash -c 'eval "$(cat)"' < npm-cert-cloud.sh
NPM_URL="${NPM_URL:-http://127.0.0.1:81}"
API="$NPM_URL/api"
NPM_EMAIL="j3tears100@gmail.com"
NPM_PASSWORD="kqEUubVq02DJTS8"
if [ -z "$BEGET_USER" ] || [ -z "$BEGET_PASS" ]; then
echo "Укажите BEGET_USER и BEGET_PASS (логин и пароль Beget API)"
exit 1
fi
echo "1. Создание credentials для certbot..."
CRED_DIR="/root/.secrets/certbot"
mkdir -p "$CRED_DIR"
cat > "$CRED_DIR/beget.ini" << EOF
dns_beget_api_username = $BEGET_USER
dns_beget_api_password = $BEGET_PASS
EOF
chmod 600 "$CRED_DIR/beget.ini"
echo "2. Запрос сертификата Let's Encrypt (DNS-01)..."
certbot certonly \
--authenticator dns-beget-api \
--dns-beget-api-credentials "$CRED_DIR/beget.ini" \
--dns-beget-api-propagation-seconds 120 \
-d "$DOMAIN" \
--non-interactive \
--agree-tos \
--email "$EMAIL"
CERT_DIR="/etc/letsencrypt/live/$DOMAIN"
CERT=$(cat "$CERT_DIR/fullchain.pem")
KEY=$(cat "$CERT_DIR/privkey.pem")
echo "3. Добавление сертификата в NPM..."
TOKEN=$(curl -s -X POST "$API/tokens" \
-H "Content-Type: application/json" \
-d "{\"identity\":\"$NPM_EMAIL\",\"secret\":\"$NPM_PASSWORD\"}" \
| jq -r '.token // empty')
if [ -z "$TOKEN" ]; then
echo "Ошибка: не удалось получить токен NPM"
exit 1
fi
# Экранируем для JSON
CERT_ESC=$(echo "$CERT" | jq -Rs .)
KEY_ESC=$(echo "$KEY" | jq -Rs .)
RESP=$(curl -s -w "\n%{http_code}" -X POST "$API/nginx/certificates" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"provider\":\"other\",\"domain_names\":[\"$DOMAIN\"],\"nice_name\":\"$DOMAIN\",\"meta\":{\"certificate\":$CERT_ESC,\"certificate_key\":$KEY_ESC}}")
HTTP_CODE=$(echo "$RESP" | tail -1)
BODY=$(echo "$RESP" | sed '$d')
if [ "$HTTP_CODE" != "201" ]; then
echo "Ошибка добавления сертификата (HTTP $HTTP_CODE):"
echo "$BODY" | jq . 2>/dev/null || echo "$BODY"
exit 1
fi
CERT_ID=$(echo "$BODY" | jq -r '.id')
echo "Сертификат добавлен, ID: $CERT_ID"
echo "4. Подключение сертификата к proxy host cloud.katykhin.ru..."
PROXY_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$API/nginx/proxy-hosts" \
| jq -r '.[] | select(.domain_names[]? == "cloud.katykhin.ru") | .id')
if [ -z "$PROXY_ID" ]; then
echo "Proxy host для $DOMAIN не найден"
exit 1
fi
PROXY=$(curl -s -H "Authorization: Bearer $TOKEN" "$API/nginx/proxy-hosts/$PROXY_ID")
UPD=$(echo "$PROXY" | jq --argjson cid "$CERT_ID" '
.certificate_id = $cid |
.ssl_forced = true |
del(.owner, .certificate, .access_list)
')
# domain_names должен быть массив
UPD=$(echo "$UPD" | jq '.domain_names = ["cloud.katykhin.ru"]')
curl -s -X PUT "$API/nginx/proxy-hosts/$PROXY_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$UPD" | jq .
echo "Готово. Сертификат подключён к https://$DOMAIN"