1 Commits

Author SHA1 Message Date
Dmitriy Fofanov
08cf094827 Обновление документации по устранению неполадок и тестированию API RegRu
- Улучшена структура и содержание руководства по устранению неполадок API RegRu для большей ясности и согласованности.

- Документация по тестированию улучшена за счет подробных инструкций и сравнения методов тестирования.

- Улучшено форматирование и читаемость обоих документов.

- Обновлена ​​боковая навигация для лучшего доступа к разделам документации.
2026-02-25 14:41:57 +03:00
35 changed files with 14629 additions and 14628 deletions
+277 -277
View File
@@ -1,277 +1,277 @@
name: "Deploy scripts to remote server"
on:
workflow_dispatch:
inputs:
ref:
description: "Branch/tag/SHA for deployment"
required: false
default: "master"
jobs:
deploy:
name: "Upload and deploy on remote server"
runs-on: native
steps:
- name: "Checkout repository"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
if [ -z "${TOKEN}" ]; then
echo "ERROR: GIT_TOKEN (or GITEA_TOKEN) secret is required"
exit 1
fi
REF="${{ github.event.inputs.ref || 'master' }}"
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
if [ "${HOST}" = "github.com" ]; then
CLONE_URL="https://x-access-token:${TOKEN}@${HOST}/${REPO}.git"
else
CLONE_URL="https://${TOKEN}@${HOST}/${REPO}.git"
fi
git clone --branch "${REF}" --depth 1 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN}" || true
echo ">>> Source checked out: $(git log --oneline -1)"
- name: "Validate deployment secrets"
shell: bash
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
DEPLOY_SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
DEPLOY_SSH_KNOWN_HOSTS: ${{ secrets.DEPLOY_SSH_KNOWN_HOSTS }}
CFG_REGRU_USERNAME: ${{ secrets.CFG_REGRU_USERNAME }}
CFG_REGRU_PASSWORD: ${{ secrets.CFG_REGRU_PASSWORD }}
CFG_EMAIL: ${{ secrets.CFG_EMAIL }}
CFG_DOMAINS: ${{ secrets.CFG_DOMAINS }}
run: |
set -euo pipefail
: "${DEPLOY_HOST:?DEPLOY_HOST secret is required}"
: "${DEPLOY_PORT:?DEPLOY_PORT secret is required}"
: "${DEPLOY_USER:?DEPLOY_USER secret is required}"
: "${DEPLOY_PATH:?DEPLOY_PATH secret is required}"
: "${DEPLOY_SERVICE:?DEPLOY_SERVICE secret is required}"
: "${DEPLOY_SSH_PRIVATE_KEY:?DEPLOY_SSH_PRIVATE_KEY secret is required}"
: "${CFG_REGRU_USERNAME:?CFG_REGRU_USERNAME secret is required}"
: "${CFG_REGRU_PASSWORD:?CFG_REGRU_PASSWORD secret is required}"
: "${CFG_EMAIL:?CFG_EMAIL secret is required}"
: "${CFG_DOMAINS:?CFG_DOMAINS secret is required}"
echo ">>> Secrets validation passed"
- name: "Create deployment archive"
shell: bash
env:
CFG_REGRU_USERNAME: ${{ secrets.CFG_REGRU_USERNAME }}
CFG_REGRU_PASSWORD: ${{ secrets.CFG_REGRU_PASSWORD }}
CFG_DOMAIN: ${{ secrets.CFG_DOMAIN }}
CFG_DOMAINS: ${{ secrets.CFG_DOMAINS }}
CFG_WILDCARD: ${{ secrets.CFG_WILDCARD }}
CFG_EMAIL: ${{ secrets.CFG_EMAIL }}
CFG_CERT_DIR: ${{ secrets.CFG_CERT_DIR }}
CFG_LOG_FILE: ${{ secrets.CFG_LOG_FILE }}
CFG_DNS_PROPAGATION_WAIT: ${{ secrets.CFG_DNS_PROPAGATION_WAIT }}
CFG_DNS_CHECK_ATTEMPTS: ${{ secrets.CFG_DNS_CHECK_ATTEMPTS }}
CFG_DNS_CHECK_INTERVAL: ${{ secrets.CFG_DNS_CHECK_INTERVAL }}
CFG_RENEWAL_DAYS: ${{ secrets.CFG_RENEWAL_DAYS }}
CFG_NPM_ENABLED: ${{ secrets.CFG_NPM_ENABLED }}
CFG_NPM_HOST: ${{ secrets.CFG_NPM_HOST }}
CFG_NPM_EMAIL: ${{ secrets.CFG_NPM_EMAIL }}
CFG_NPM_PASSWORD: ${{ secrets.CFG_NPM_PASSWORD }}
run: |
set -euo pipefail
rm -rf .deploy-artifacts
mkdir -p .deploy-artifacts
if command -v rsync >/dev/null 2>&1; then
rsync -a \
--exclude '.git/' \
--exclude '.src-repo/' \
--exclude '.wiki-repo/' \
--exclude '.deploy-artifacts/' \
./ .deploy-artifacts/repo/
else
cp -a . .deploy-artifacts/repo
rm -rf .deploy-artifacts/repo/.git .deploy-artifacts/repo/.src-repo .deploy-artifacts/repo/.wiki-repo .deploy-artifacts/repo/.deploy-artifacts
fi
python3 - <<'PY'
import json
import os
def to_bool(value, default=False):
if value is None or value == "":
return default
return str(value).strip().lower() in {"1", "true", "yes", "on"}
def to_int(value, default):
if value is None or value == "":
return default
return int(value)
domains_raw = os.environ.get("CFG_DOMAINS", "").strip()
if domains_raw.startswith("["):
# JSON array: каждый элемент может содержать запятые для SAN групп
# Пример: ["*.example.com,example.com", "gitea.example.com"]
domains = json.loads(domains_raw)
else:
domains = [item.strip() for item in domains_raw.split(",") if item.strip()]
if not domains:
raise RuntimeError("CFG_DOMAINS must contain at least one domain")
# primary domain: CFG_DOMAIN → первый не-wildcard домен из первой SAN группы
first_group_domains = [d.strip() for d in domains[0].split(",") if d.strip()]
domain = os.environ.get("CFG_DOMAIN", "").strip() or next(
(d for d in first_group_domains if not d.startswith("*.")),
first_group_domains[0]
)
config = {
"regru_username": os.environ["CFG_REGRU_USERNAME"],
"regru_password": os.environ["CFG_REGRU_PASSWORD"],
"domain": domain,
"domains": domains,
"wildcard": to_bool(os.environ.get("CFG_WILDCARD"), True),
"email": os.environ["CFG_EMAIL"],
"cert_dir": os.environ.get("CFG_CERT_DIR") or "/etc/letsencrypt/live",
"log_file": os.environ.get("CFG_LOG_FILE") or "/var/log/letsencrypt_regru.log",
"dns_propagation_wait": to_int(os.environ.get("CFG_DNS_PROPAGATION_WAIT"), 180),
"dns_check_attempts": to_int(os.environ.get("CFG_DNS_CHECK_ATTEMPTS"), 20),
"dns_check_interval": to_int(os.environ.get("CFG_DNS_CHECK_INTERVAL"), 15),
"renewal_days": to_int(os.environ.get("CFG_RENEWAL_DAYS"), 30),
"npm_enabled": to_bool(os.environ.get("CFG_NPM_ENABLED"), True),
"npm_host": os.environ.get("CFG_NPM_HOST") or "",
"npm_email": os.environ.get("CFG_NPM_EMAIL") or "",
"npm_password": os.environ.get("CFG_NPM_PASSWORD") or "",
}
output_path = os.path.join(".deploy-artifacts", "repo", "config.json")
with open(output_path, "w", encoding="utf-8") as file:
json.dump(config, file, ensure_ascii=False, indent=4)
PY
tar -czf .deploy-artifacts/deploy.tar.gz -C .deploy-artifacts repo
ls -lh .deploy-artifacts/deploy.tar.gz
- name: "Configure SSH client"
shell: bash
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
DEPLOY_SSH_KNOWN_HOSTS: ${{ secrets.DEPLOY_SSH_KNOWN_HOSTS }}
run: |
set -euo pipefail
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Save private key preserving exact formatting
# Use printf with %b to handle \n sequences, strip trailing whitespace issues
echo "${DEPLOY_SSH_PRIVATE_KEY}" | sed 's/\r//' > ~/.ssh/id_deploy
# Ensure file ends with a newline (required by OpenSSH)
echo "" >> ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy
# Validate key and show fingerprint for debugging
echo ">>> Private key type: $(ssh-keygen -l -f ~/.ssh/id_deploy 2>&1 || echo 'INVALID KEY')"
if [ -n "${DEPLOY_SSH_KNOWN_HOSTS:-}" ]; then
printf '%s\n' "${DEPLOY_SSH_KNOWN_HOSTS}" > ~/.ssh/known_hosts
echo ">>> known_hosts: loaded from DEPLOY_SSH_KNOWN_HOSTS secret"
fi
# Always run ssh-keyscan to ensure all key types are covered
echo ">>> Scanning host keys for ${DEPLOY_HOST}:${DEPLOY_PORT}..."
ssh-keyscan -p "${DEPLOY_PORT}" -t ed25519,ecdsa-sha2-nistp256,rsa "${DEPLOY_HOST}" >> ~/.ssh/known_hosts 2>&1 || true
echo ">>> known_hosts entries: $(wc -l < ~/.ssh/known_hosts)"
chmod 644 ~/.ssh/known_hosts
{
echo "Host deploy-target"
echo " HostName ${DEPLOY_HOST}"
echo " Port ${DEPLOY_PORT}"
echo " User ${DEPLOY_USER}"
echo " IdentityFile ~/.ssh/id_deploy"
echo " UserKnownHostsFile ~/.ssh/known_hosts"
echo " StrictHostKeyChecking accept-new"
echo " ConnectTimeout 15"
echo " ServerAliveInterval 10"
echo " ServerAliveCountMax 3"
echo " BatchMode yes"
} > ~/.ssh/config
chmod 600 ~/.ssh/config
echo ">>> Testing SSH connection..."
ssh deploy-target "echo '>>> SSH connection ok:' \"\$(hostname)\""
echo ">>> SSH configured successfully"
- name: "Upload deployment archive"
shell: bash
run: |
set -euo pipefail
scp .deploy-artifacts/deploy.tar.gz deploy-target:/tmp/configure_nginx_manager_deploy.tar.gz
- name: "Deploy and restart remote service"
shell: bash
env:
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
DEPLOY_CONFIG_PATH: ${{ secrets.DEPLOY_CONFIG_PATH }}
run: |
set -euo pipefail
# DEPLOY_CONFIG_PATH: path to config.json on remote (default: /etc/letsencrypt-regru/config.json)
CONFIG_DEST="${DEPLOY_CONFIG_PATH:-/etc/letsencrypt-regru/config.json}"
ssh deploy-target "set -euo pipefail; \
TMP_DIR=\"/tmp/configure_nginx_manager_deploy\"; \
sudo rm -rf \"\${TMP_DIR}\"; \
sudo mkdir -p \"\${TMP_DIR}\"; \
sudo tar -xzf /tmp/configure_nginx_manager_deploy.tar.gz -C \"\${TMP_DIR}\"; \
sudo mkdir -p \"${DEPLOY_PATH}\"; \
sudo find \"${DEPLOY_PATH}\" -mindepth 1 -maxdepth 1 ! -name 'venv' -exec rm -rf {} + 2>/dev/null || true; \
sudo cp -a \"\${TMP_DIR}/repo/.\" \"${DEPLOY_PATH}/\"; \
if [ ! -d \"${DEPLOY_PATH}/venv\" ]; then \
echo \">>> venv not found, creating...\"; \
sudo python3 -m venv \"${DEPLOY_PATH}/venv\"; \
fi; \
echo \">>> Installing/updating Python dependencies...\"; \
sudo \"${DEPLOY_PATH}/venv/bin/pip\" install -q -r \"${DEPLOY_PATH}/requirements.txt\" 2>&1 | tail -5; \
sudo mkdir -p \"\$(dirname '${CONFIG_DEST}')\"; \
sudo cp -f \"\${TMP_DIR}/repo/config.json\" \"${CONFIG_DEST}\"; \
sudo chmod 600 \"${CONFIG_DEST}\"; \
echo \">>> config.json deployed to: ${CONFIG_DEST}\"; \
sudo rm -rf \"\${TMP_DIR}\" /tmp/configure_nginx_manager_deploy.tar.gz; \
sudo systemctl daemon-reload; \
sudo systemctl enable \"${DEPLOY_SERVICE}\" || true; \
echo \">>> Starting service...\"; \
sudo systemctl restart --no-block \"${DEPLOY_SERVICE}\" || true; \
sleep 3; \
echo \">>> Service status:\"; \
sudo systemctl --no-pager --full status \"${DEPLOY_SERVICE}\" | head -n 30 || true; \
echo \">>> Last journal entries:\"; \
sudo journalctl -u \"${DEPLOY_SERVICE}\" -n 30 --no-pager || true; \
echo \">>> Config used:\"; \
sudo cat \"${CONFIG_DEST}\" | python3 -c \"import json,sys; c=json.load(sys.stdin); c['regru_password']='***'; c['npm_password']='***'; print(json.dumps(c,indent=2,ensure_ascii=False))\" || true"
name: "Deploy scripts to remote server"
on:
workflow_dispatch:
inputs:
ref:
description: "Branch/tag/SHA for deployment"
required: false
default: "master"
jobs:
deploy:
name: "Upload and deploy on remote server"
runs-on: native
steps:
- name: "Checkout repository"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
if [ -z "${TOKEN}" ]; then
echo "ERROR: GIT_TOKEN (or GITEA_TOKEN) secret is required"
exit 1
fi
REF="${{ github.event.inputs.ref || 'master' }}"
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
if [ "${HOST}" = "github.com" ]; then
CLONE_URL="https://x-access-token:${TOKEN}@${HOST}/${REPO}.git"
else
CLONE_URL="https://${TOKEN}@${HOST}/${REPO}.git"
fi
git clone --branch "${REF}" --depth 1 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN}" || true
echo ">>> Source checked out: $(git log --oneline -1)"
- name: "Validate deployment secrets"
shell: bash
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
DEPLOY_SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
DEPLOY_SSH_KNOWN_HOSTS: ${{ secrets.DEPLOY_SSH_KNOWN_HOSTS }}
CFG_REGRU_USERNAME: ${{ secrets.CFG_REGRU_USERNAME }}
CFG_REGRU_PASSWORD: ${{ secrets.CFG_REGRU_PASSWORD }}
CFG_EMAIL: ${{ secrets.CFG_EMAIL }}
CFG_DOMAINS: ${{ secrets.CFG_DOMAINS }}
run: |
set -euo pipefail
: "${DEPLOY_HOST:?DEPLOY_HOST secret is required}"
: "${DEPLOY_PORT:?DEPLOY_PORT secret is required}"
: "${DEPLOY_USER:?DEPLOY_USER secret is required}"
: "${DEPLOY_PATH:?DEPLOY_PATH secret is required}"
: "${DEPLOY_SERVICE:?DEPLOY_SERVICE secret is required}"
: "${DEPLOY_SSH_PRIVATE_KEY:?DEPLOY_SSH_PRIVATE_KEY secret is required}"
: "${CFG_REGRU_USERNAME:?CFG_REGRU_USERNAME secret is required}"
: "${CFG_REGRU_PASSWORD:?CFG_REGRU_PASSWORD secret is required}"
: "${CFG_EMAIL:?CFG_EMAIL secret is required}"
: "${CFG_DOMAINS:?CFG_DOMAINS secret is required}"
echo ">>> Secrets validation passed"
- name: "Create deployment archive"
shell: bash
env:
CFG_REGRU_USERNAME: ${{ secrets.CFG_REGRU_USERNAME }}
CFG_REGRU_PASSWORD: ${{ secrets.CFG_REGRU_PASSWORD }}
CFG_DOMAIN: ${{ secrets.CFG_DOMAIN }}
CFG_DOMAINS: ${{ secrets.CFG_DOMAINS }}
CFG_WILDCARD: ${{ secrets.CFG_WILDCARD }}
CFG_EMAIL: ${{ secrets.CFG_EMAIL }}
CFG_CERT_DIR: ${{ secrets.CFG_CERT_DIR }}
CFG_LOG_FILE: ${{ secrets.CFG_LOG_FILE }}
CFG_DNS_PROPAGATION_WAIT: ${{ secrets.CFG_DNS_PROPAGATION_WAIT }}
CFG_DNS_CHECK_ATTEMPTS: ${{ secrets.CFG_DNS_CHECK_ATTEMPTS }}
CFG_DNS_CHECK_INTERVAL: ${{ secrets.CFG_DNS_CHECK_INTERVAL }}
CFG_RENEWAL_DAYS: ${{ secrets.CFG_RENEWAL_DAYS }}
CFG_NPM_ENABLED: ${{ secrets.CFG_NPM_ENABLED }}
CFG_NPM_HOST: ${{ secrets.CFG_NPM_HOST }}
CFG_NPM_EMAIL: ${{ secrets.CFG_NPM_EMAIL }}
CFG_NPM_PASSWORD: ${{ secrets.CFG_NPM_PASSWORD }}
run: |
set -euo pipefail
rm -rf .deploy-artifacts
mkdir -p .deploy-artifacts
if command -v rsync >/dev/null 2>&1; then
rsync -a \
--exclude '.git/' \
--exclude '.src-repo/' \
--exclude '.wiki-repo/' \
--exclude '.deploy-artifacts/' \
./ .deploy-artifacts/repo/
else
cp -a . .deploy-artifacts/repo
rm -rf .deploy-artifacts/repo/.git .deploy-artifacts/repo/.src-repo .deploy-artifacts/repo/.wiki-repo .deploy-artifacts/repo/.deploy-artifacts
fi
python3 - <<'PY'
import json
import os
def to_bool(value, default=False):
if value is None or value == "":
return default
return str(value).strip().lower() in {"1", "true", "yes", "on"}
def to_int(value, default):
if value is None or value == "":
return default
return int(value)
domains_raw = os.environ.get("CFG_DOMAINS", "").strip()
if domains_raw.startswith("["):
# JSON array: каждый элемент может содержать запятые для SAN групп
# Пример: ["*.example.com,example.com", "gitea.example.com"]
domains = json.loads(domains_raw)
else:
domains = [item.strip() for item in domains_raw.split(",") if item.strip()]
if not domains:
raise RuntimeError("CFG_DOMAINS must contain at least one domain")
# primary domain: CFG_DOMAIN → первый не-wildcard домен из первой SAN группы
first_group_domains = [d.strip() for d in domains[0].split(",") if d.strip()]
domain = os.environ.get("CFG_DOMAIN", "").strip() or next(
(d for d in first_group_domains if not d.startswith("*.")),
first_group_domains[0]
)
config = {
"regru_username": os.environ["CFG_REGRU_USERNAME"],
"regru_password": os.environ["CFG_REGRU_PASSWORD"],
"domain": domain,
"domains": domains,
"wildcard": to_bool(os.environ.get("CFG_WILDCARD"), True),
"email": os.environ["CFG_EMAIL"],
"cert_dir": os.environ.get("CFG_CERT_DIR") or "/etc/letsencrypt/live",
"log_file": os.environ.get("CFG_LOG_FILE") or "/var/log/letsencrypt_regru.log",
"dns_propagation_wait": to_int(os.environ.get("CFG_DNS_PROPAGATION_WAIT"), 180),
"dns_check_attempts": to_int(os.environ.get("CFG_DNS_CHECK_ATTEMPTS"), 20),
"dns_check_interval": to_int(os.environ.get("CFG_DNS_CHECK_INTERVAL"), 15),
"renewal_days": to_int(os.environ.get("CFG_RENEWAL_DAYS"), 30),
"npm_enabled": to_bool(os.environ.get("CFG_NPM_ENABLED"), True),
"npm_host": os.environ.get("CFG_NPM_HOST") or "",
"npm_email": os.environ.get("CFG_NPM_EMAIL") or "",
"npm_password": os.environ.get("CFG_NPM_PASSWORD") or "",
}
output_path = os.path.join(".deploy-artifacts", "repo", "config.json")
with open(output_path, "w", encoding="utf-8") as file:
json.dump(config, file, ensure_ascii=False, indent=4)
PY
tar -czf .deploy-artifacts/deploy.tar.gz -C .deploy-artifacts repo
ls -lh .deploy-artifacts/deploy.tar.gz
- name: "Configure SSH client"
shell: bash
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
DEPLOY_SSH_KNOWN_HOSTS: ${{ secrets.DEPLOY_SSH_KNOWN_HOSTS }}
run: |
set -euo pipefail
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Save private key preserving exact formatting
# Use printf with %b to handle \n sequences, strip trailing whitespace issues
echo "${DEPLOY_SSH_PRIVATE_KEY}" | sed 's/\r//' > ~/.ssh/id_deploy
# Ensure file ends with a newline (required by OpenSSH)
echo "" >> ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy
# Validate key and show fingerprint for debugging
echo ">>> Private key type: $(ssh-keygen -l -f ~/.ssh/id_deploy 2>&1 || echo 'INVALID KEY')"
if [ -n "${DEPLOY_SSH_KNOWN_HOSTS:-}" ]; then
printf '%s\n' "${DEPLOY_SSH_KNOWN_HOSTS}" > ~/.ssh/known_hosts
echo ">>> known_hosts: loaded from DEPLOY_SSH_KNOWN_HOSTS secret"
fi
# Always run ssh-keyscan to ensure all key types are covered
echo ">>> Scanning host keys for ${DEPLOY_HOST}:${DEPLOY_PORT}..."
ssh-keyscan -p "${DEPLOY_PORT}" -t ed25519,ecdsa-sha2-nistp256,rsa "${DEPLOY_HOST}" >> ~/.ssh/known_hosts 2>&1 || true
echo ">>> known_hosts entries: $(wc -l < ~/.ssh/known_hosts)"
chmod 644 ~/.ssh/known_hosts
{
echo "Host deploy-target"
echo " HostName ${DEPLOY_HOST}"
echo " Port ${DEPLOY_PORT}"
echo " User ${DEPLOY_USER}"
echo " IdentityFile ~/.ssh/id_deploy"
echo " UserKnownHostsFile ~/.ssh/known_hosts"
echo " StrictHostKeyChecking accept-new"
echo " ConnectTimeout 15"
echo " ServerAliveInterval 10"
echo " ServerAliveCountMax 3"
echo " BatchMode yes"
} > ~/.ssh/config
chmod 600 ~/.ssh/config
echo ">>> Testing SSH connection..."
ssh deploy-target "echo '>>> SSH connection ok:' \"\$(hostname)\""
echo ">>> SSH configured successfully"
- name: "Upload deployment archive"
shell: bash
run: |
set -euo pipefail
scp .deploy-artifacts/deploy.tar.gz deploy-target:/tmp/configure_nginx_manager_deploy.tar.gz
- name: "Deploy and restart remote service"
shell: bash
env:
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
DEPLOY_SERVICE: ${{ secrets.DEPLOY_SERVICE }}
DEPLOY_CONFIG_PATH: ${{ secrets.DEPLOY_CONFIG_PATH }}
run: |
set -euo pipefail
# DEPLOY_CONFIG_PATH: path to config.json on remote (default: /etc/letsencrypt-regru/config.json)
CONFIG_DEST="${DEPLOY_CONFIG_PATH:-/etc/letsencrypt-regru/config.json}"
ssh deploy-target "set -euo pipefail; \
TMP_DIR=\"/tmp/configure_nginx_manager_deploy\"; \
sudo rm -rf \"\${TMP_DIR}\"; \
sudo mkdir -p \"\${TMP_DIR}\"; \
sudo tar -xzf /tmp/configure_nginx_manager_deploy.tar.gz -C \"\${TMP_DIR}\"; \
sudo mkdir -p \"${DEPLOY_PATH}\"; \
sudo find \"${DEPLOY_PATH}\" -mindepth 1 -maxdepth 1 ! -name 'venv' -exec rm -rf {} + 2>/dev/null || true; \
sudo cp -a \"\${TMP_DIR}/repo/.\" \"${DEPLOY_PATH}/\"; \
if [ ! -d \"${DEPLOY_PATH}/venv\" ]; then \
echo \">>> venv not found, creating...\"; \
sudo python3 -m venv \"${DEPLOY_PATH}/venv\"; \
fi; \
echo \">>> Installing/updating Python dependencies...\"; \
sudo \"${DEPLOY_PATH}/venv/bin/pip\" install -q -r \"${DEPLOY_PATH}/requirements.txt\" 2>&1 | tail -5; \
sudo mkdir -p \"\$(dirname '${CONFIG_DEST}')\"; \
sudo cp -f \"\${TMP_DIR}/repo/config.json\" \"${CONFIG_DEST}\"; \
sudo chmod 600 \"${CONFIG_DEST}\"; \
echo \">>> config.json deployed to: ${CONFIG_DEST}\"; \
sudo rm -rf \"\${TMP_DIR}\" /tmp/configure_nginx_manager_deploy.tar.gz; \
sudo systemctl daemon-reload; \
sudo systemctl enable \"${DEPLOY_SERVICE}\" || true; \
echo \">>> Starting service...\"; \
sudo systemctl restart --no-block \"${DEPLOY_SERVICE}\" || true; \
sleep 3; \
echo \">>> Service status:\"; \
sudo systemctl --no-pager --full status \"${DEPLOY_SERVICE}\" | head -n 30 || true; \
echo \">>> Last journal entries:\"; \
sudo journalctl -u \"${DEPLOY_SERVICE}\" -n 30 --no-pager || true; \
echo \">>> Config used:\"; \
sudo cat \"${CONFIG_DEST}\" | python3 -c \"import json,sys; c=json.load(sys.stdin); c['regru_password']='***'; c['npm_password']='***'; print(json.dumps(c,indent=2,ensure_ascii=False))\" || true"
+388 -388
View File
@@ -1,388 +1,388 @@
name: "Релиз: архив исходников"
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Тег релиза (например: v2.2.0)"
required: true
permissions:
contents: write
env:
DIST_DIR: dist
jobs:
release:
name: "Упаковка и публикация релиза"
runs-on: native
steps:
- name: "Получение исходного кода"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG="${{ github.event.inputs.tag }}"
else
TAG="${GITHUB_REF_NAME}"
fi
if [ -z "${TAG}" ]; then
echo "ОШИБКА: не удалось определить тег релиза."
exit 1
fi
echo ">>> Клонирование ${REPO} (тег: ${TAG})"
if [ -n "${TOKEN}" ]; then
if [ "${HOST}" = "github.com" ]; then
CLONE_URL="https://x-access-token:${TOKEN}@${HOST}/${REPO}.git"
else
CLONE_URL="https://${TOKEN}@${HOST}/${REPO}.git"
fi
else
CLONE_URL="${SERVER}/${REPO}.git"
fi
# Check if tag exists on the remote
TAG_EXISTS=false
if git ls-remote --exit-code --tags "${CLONE_URL}" "refs/tags/${TAG}" >/dev/null 2>&1; then
TAG_EXISTS=true
fi
if [ "${TAG_EXISTS}" = "true" ]; then
echo ">>> Тег ${TAG} найден, клонирование..."
git clone --branch "${TAG}" --depth 50 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN:-}" || true
else
DEFAULT_BRANCH="${{ github.event.repository.default_branch }}"
if [ -z "${DEFAULT_BRANCH}" ] || [ "${DEFAULT_BRANCH}" = "null" ]; then
DEFAULT_BRANCH="master"
fi
echo ">>> Тег ${TAG} не найден, клонирование ветки ${DEFAULT_BRANCH}..."
git clone --branch "${DEFAULT_BRANCH}" --depth 50 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN:-}" || true
fi
git fetch --tags --force 2>/dev/null || true
# If tag doesn't exist locally, create and push it
if [ "${TAG_EXISTS}" = "false" ] && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo ">>> Создание тега ${TAG} на текущем коммите ($(git rev-parse --short HEAD))..."
git tag "${TAG}"
git push origin "${TAG}" 2>&1 | grep -F -v "${TOKEN:-}" || true
echo ">>> Тег ${TAG} создан и отправлен"
fi
echo "RELEASE_TAG=${TAG}" >> "$GITHUB_ENV"
echo ">>> Исходный код получен: $(git log --oneline -1 2>/dev/null || echo 'N/A')"
- name: "Подготовка метаданных релиза"
id: meta
shell: bash
run: |
set -euo pipefail
TAG="${RELEASE_TAG}"
VERSION="${TAG#v}"
PREV_TAG=$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || true)
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "prev_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT"
echo "══════════════════════════════════════"
echo " Тег: ${TAG}"
echo " Версия: ${VERSION}"
echo " Пред. тег: ${PREV_TAG:-<первый релиз>}"
echo " Коммит: ${GITHUB_SHA:0:8}"
echo "══════════════════════════════════════"
- name: "Создание архивов исходного кода"
shell: bash
run: |
set -euo pipefail
TAG="${{ steps.meta.outputs.tag }}"
REPO_NAME="${GITHUB_REPOSITORY##*/}"
ARCHIVE_BASE="${REPO_NAME}-${TAG}"
rm -rf .release-work "${DIST_DIR}"
mkdir -p .release-work "${DIST_DIR}"
if command -v rsync >/dev/null 2>&1; then
rsync -a \
--exclude '.git/' \
--exclude '.src-repo/' \
--exclude '.wiki-repo/' \
--exclude '.release-work/' \
--exclude "${DIST_DIR}/" \
./ ".release-work/${ARCHIVE_BASE}/"
else
cp -a . ".release-work/${ARCHIVE_BASE}"
rm -rf \
".release-work/${ARCHIVE_BASE}/.git" \
".release-work/${ARCHIVE_BASE}/.src-repo" \
".release-work/${ARCHIVE_BASE}/.wiki-repo" \
".release-work/${ARCHIVE_BASE}/.release-work" \
".release-work/${ARCHIVE_BASE}/${DIST_DIR}"
fi
tar -czf "${DIST_DIR}/${ARCHIVE_BASE}.tar.gz" -C .release-work "${ARCHIVE_BASE}"
if command -v zip >/dev/null 2>&1; then
(
cd .release-work
zip -qr "../${DIST_DIR}/${ARCHIVE_BASE}.zip" "${ARCHIVE_BASE}"
)
else
ARCHIVE_BASE="${ARCHIVE_BASE}" DIST_DIR="${DIST_DIR}" python3 - <<'PY'
import os
import zipfile
base = os.environ["ARCHIVE_BASE"]
src = os.path.join(".release-work", base)
dst = os.path.join(os.environ["DIST_DIR"], f"{base}.zip")
with zipfile.ZipFile(dst, "w", zipfile.ZIP_DEFLATED) as zf:
for root, _, files in os.walk(src):
for file_name in files:
full = os.path.join(root, file_name)
arc = os.path.relpath(full, ".release-work")
zf.write(full, arc)
PY
fi
sha256sum "${DIST_DIR}"/* > "${DIST_DIR}/checksums-sha256.txt"
echo "ARCHIVE_BASE=${ARCHIVE_BASE}" >> "$GITHUB_ENV"
echo ">>> Артефакты релиза:"
ls -lh "${DIST_DIR}"
- name: "Генерация описания релиза"
shell: bash
run: |
set -euo pipefail
TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}"
PREV_TAG="${{ steps.meta.outputs.prev_tag }}"
DATE_UTC=$(date -u '+%Y-%m-%d %H:%M UTC')
CHANGELOG_FILE=""
if [ -f "wiki/Changelog.md" ]; then
CHANGELOG_FILE="wiki/Changelog.md"
elif [ -f "docs/ru/CHANGELOG.md" ]; then
CHANGELOG_FILE="docs/ru/CHANGELOG.md"
elif [ -f "docs/en/CHANGELOG_EN.md" ]; then
CHANGELOG_FILE="docs/en/CHANGELOG_EN.md"
fi
CHANGELOG_SECTION=""
if [ -n "${CHANGELOG_FILE}" ]; then
# Поддерживаем оба формата заголовков: "## [VERSION]" и "### [VERSION] - DATE"
CHANGELOG_SECTION=$(awk -v ver="${VERSION}" '
$0 ~ "^#{2,3} \\[" ver "\\]" { in_section=1; next }
/^#{2,3} \[/ && in_section { exit }
in_section { print }
' "${CHANGELOG_FILE}")
fi
COMMITS=""
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
if [ -n "${PREV_TAG}" ]; then
COMMITS=$(git log --pretty=format:'- %s (%h)' "${PREV_TAG}..${TAG}" --no-merges | head -50)
else
COMMITS=$(git log --pretty=format:'- %s (%h)' --no-merges | head -50)
fi
else
echo ">>> Предупреждение: .git недоступен, список коммитов будет пропущен"
fi
{
echo "## Release ${TAG}"
echo ""
echo "Релиз скриптового проекта без компиляции бинарников."
echo ""
echo "### Что входит в релиз"
echo "- Исходный код в форматах: ${ARCHIVE_BASE}.tar.gz, ${ARCHIVE_BASE}.zip"
echo "- Контрольные суммы: checksums-sha256.txt"
echo ""
if [ -n "${CHANGELOG_SECTION}" ]; then
echo "### Что сделано (из CHANGELOG)"
echo "${CHANGELOG_SECTION}"
echo ""
fi
echo "### Коммиты релиза"
if [ -n "${COMMITS}" ]; then
echo "${COMMITS}"
else
echo "- Недоступно (runner без .git)"
fi
echo ""
echo "---"
echo ""
echo "- Тег: ${TAG}"
echo "- Коммит: ${GITHUB_SHA}"
echo "- Дата (UTC): ${DATE_UTC}"
} > /tmp/release_body.md
echo ">>> Сформировано описание релиза: /tmp/release_body.md"
- name: "Создание релиза и загрузка архивов"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
if [ -z "${TOKEN}" ]; then
echo "ОШИБКА: не задан секрет GIT_TOKEN (или GITEA_TOKEN)."
exit 1
fi
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
TAG="${{ steps.meta.outputs.tag }}"
# Set up API URLs and auth header early (needed for tag check below)
if [ "${HOST}" = "github.com" ]; then
CREATE_URL="https://api.github.com/repos/${REPO}/releases"
AUTH_HEADER="Authorization: Bearer ${TOKEN}"
EXTRA_HEADERS=(-H "Accept: application/vnd.github+json")
else
CREATE_URL="${SERVER}/api/v1/repos/${REPO}/releases"
AUTH_HEADER="Authorization: token ${TOKEN}"
EXTRA_HEADERS=()
fi
TARGET_COMMITISH="${RELEASE_REF:-${{ github.event.repository.default_branch }}}"
if [ -z "${TARGET_COMMITISH}" ] || [ "${TARGET_COMMITISH}" = "null" ]; then
TARGET_COMMITISH="master"
fi
if [ -n "${GITHUB_SHA:-}" ]; then
TARGET_COMMITISH="${GITHUB_SHA}"
fi
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
TARGET_COMMITISH="$(git rev-list -n 1 "${TAG}" 2>/dev/null || echo "${TARGET_COMMITISH}")"
fi
# Ensure the tag exists on the remote (Gitea requires it before creating a release)
if [ "${HOST}" != "github.com" ]; then
TAG_HTTP_CODE=$(curl -sS -o /dev/null -w '%{http_code}' \
-H "${AUTH_HEADER}" \
"${SERVER}/api/v1/repos/${REPO}/tags/${TAG}")
if [ "${TAG_HTTP_CODE}" != "200" ]; then
echo ">>> Тег ${TAG} не найден на сервере (HTTP ${TAG_HTTP_CODE}), создание через API..."
TAG_CREATE_RESP=$(curl -sS -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/json" \
"${SERVER}/api/v1/repos/${REPO}/tags" \
-d "{\"tag_name\":\"${TAG}\",\"target\":\"${TARGET_COMMITISH}\"}")
echo ">>> Ответ создания тега: ${TAG_CREATE_RESP}"
else
echo ">>> Тег ${TAG} существует на сервере"
fi
fi
BODY_JSON=$(python3 - <<'PY'
import json
with open('/tmp/release_body.md', 'r', encoding='utf-8') as f:
print(json.dumps(f.read(), ensure_ascii=False))
PY
)
if [ "${HOST}" = "github.com" ]; then
RELEASE_PAYLOAD="{\"tag_name\":\"${TAG}\",\"target_commitish\":\"${TARGET_COMMITISH}\",\"name\":\"Release ${TAG}\",\"body\":${BODY_JSON},\"draft\":false,\"prerelease\":false}"
else
RELEASE_PAYLOAD="{\"tag_name\":\"${TAG}\",\"target\":\"${TARGET_COMMITISH}\",\"title\":\"Release ${TAG}\",\"note\":${BODY_JSON},\"draft\":false,\"prerelease\":false}"
fi
echo ">>> Создание релиза для тега ${TAG}..."
RELEASE_JSON=$(curl -sS -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/json" \
"${EXTRA_HEADERS[@]}" \
"${CREATE_URL}" \
-d "${RELEASE_PAYLOAD}")
if ! printf '%s' "${RELEASE_JSON}" | python3 -c "import sys, json; j=json.load(sys.stdin); print(j.get('id',''));" >/tmp/release_id.txt 2>/dev/null; then
echo "ОШИБКА: API вернул не-JSON при создании релиза"
echo "Ответ: ${RELEASE_JSON}"
exit 1
fi
RELEASE_ID=$(cat /tmp/release_id.txt)
rm -f /tmp/release_id.txt
if [ -z "${RELEASE_ID}" ] && [ "${HOST}" != "github.com" ]; then
echo ">>> Не удалось получить ID из create-response, пытаемся найти существующий релиз по тегу ${TAG}..."
RELEASE_JSON=$(curl -sS \
-H "${AUTH_HEADER}" \
"${SERVER}/api/v1/repos/${REPO}/releases/tags/${TAG}")
if printf '%s' "${RELEASE_JSON}" | python3 -c "import sys, json; j=json.load(sys.stdin); print(j.get('id',''));" >/tmp/release_id.txt 2>/dev/null; then
RELEASE_ID=$(cat /tmp/release_id.txt)
fi
rm -f /tmp/release_id.txt
fi
if [ -z "${RELEASE_ID}" ]; then
echo "ОШИБКА: не удалось получить ID релиза"
echo "${RELEASE_JSON}"
exit 1
fi
if [ "${HOST}" = "github.com" ]; then
UPLOAD_BASE=$(printf '%s' "${RELEASE_JSON}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('upload_url','').split('{')[0])")
RELEASE_URL="https://github.com/${REPO}/releases/tag/${TAG}"
else
UPLOAD_BASE="${SERVER}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets"
RELEASE_URL="${SERVER}/${REPO}/releases/tag/${TAG}"
fi
echo ">>> Загрузка файлов в релиз ${TAG}"
for file in "${DIST_DIR}"/*; do
[ -f "${file}" ] || continue
name=$(basename "${file}")
if [ "${HOST}" = "github.com" ]; then
curl -sf -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/octet-stream" \
"${EXTRA_HEADERS[@]}" \
--data-binary @"${file}" \
"${UPLOAD_BASE}?name=${name}" >/dev/null
else
curl -sf -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"${file}" \
"${UPLOAD_BASE}?name=${name}" >/dev/null
fi
echo " ✓ ${name}"
done
echo ""
echo ">>> Релиз опубликован: ${RELEASE_URL}"
name: "Релиз: архив исходников"
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Тег релиза (например: v2.2.0)"
required: true
permissions:
contents: write
env:
DIST_DIR: dist
jobs:
release:
name: "Упаковка и публикация релиза"
runs-on: native
steps:
- name: "Получение исходного кода"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG="${{ github.event.inputs.tag }}"
else
TAG="${GITHUB_REF_NAME}"
fi
if [ -z "${TAG}" ]; then
echo "ОШИБКА: не удалось определить тег релиза."
exit 1
fi
echo ">>> Клонирование ${REPO} (тег: ${TAG})"
if [ -n "${TOKEN}" ]; then
if [ "${HOST}" = "github.com" ]; then
CLONE_URL="https://x-access-token:${TOKEN}@${HOST}/${REPO}.git"
else
CLONE_URL="https://${TOKEN}@${HOST}/${REPO}.git"
fi
else
CLONE_URL="${SERVER}/${REPO}.git"
fi
# Check if tag exists on the remote
TAG_EXISTS=false
if git ls-remote --exit-code --tags "${CLONE_URL}" "refs/tags/${TAG}" >/dev/null 2>&1; then
TAG_EXISTS=true
fi
if [ "${TAG_EXISTS}" = "true" ]; then
echo ">>> Тег ${TAG} найден, клонирование..."
git clone --branch "${TAG}" --depth 50 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN:-}" || true
else
DEFAULT_BRANCH="${{ github.event.repository.default_branch }}"
if [ -z "${DEFAULT_BRANCH}" ] || [ "${DEFAULT_BRANCH}" = "null" ]; then
DEFAULT_BRANCH="master"
fi
echo ">>> Тег ${TAG} не найден, клонирование ветки ${DEFAULT_BRANCH}..."
git clone --branch "${DEFAULT_BRANCH}" --depth 50 "${CLONE_URL}" . 2>&1 | grep -F -v "${TOKEN:-}" || true
fi
git fetch --tags --force 2>/dev/null || true
# If tag doesn't exist locally, create and push it
if [ "${TAG_EXISTS}" = "false" ] && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo ">>> Создание тега ${TAG} на текущем коммите ($(git rev-parse --short HEAD))..."
git tag "${TAG}"
git push origin "${TAG}" 2>&1 | grep -F -v "${TOKEN:-}" || true
echo ">>> Тег ${TAG} создан и отправлен"
fi
echo "RELEASE_TAG=${TAG}" >> "$GITHUB_ENV"
echo ">>> Исходный код получен: $(git log --oneline -1 2>/dev/null || echo 'N/A')"
- name: "Подготовка метаданных релиза"
id: meta
shell: bash
run: |
set -euo pipefail
TAG="${RELEASE_TAG}"
VERSION="${TAG#v}"
PREV_TAG=$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || true)
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "prev_tag=${PREV_TAG}" >> "$GITHUB_OUTPUT"
echo "══════════════════════════════════════"
echo " Тег: ${TAG}"
echo " Версия: ${VERSION}"
echo " Пред. тег: ${PREV_TAG:-<первый релиз>}"
echo " Коммит: ${GITHUB_SHA:0:8}"
echo "══════════════════════════════════════"
- name: "Создание архивов исходного кода"
shell: bash
run: |
set -euo pipefail
TAG="${{ steps.meta.outputs.tag }}"
REPO_NAME="${GITHUB_REPOSITORY##*/}"
ARCHIVE_BASE="${REPO_NAME}-${TAG}"
rm -rf .release-work "${DIST_DIR}"
mkdir -p .release-work "${DIST_DIR}"
if command -v rsync >/dev/null 2>&1; then
rsync -a \
--exclude '.git/' \
--exclude '.src-repo/' \
--exclude '.wiki-repo/' \
--exclude '.release-work/' \
--exclude "${DIST_DIR}/" \
./ ".release-work/${ARCHIVE_BASE}/"
else
cp -a . ".release-work/${ARCHIVE_BASE}"
rm -rf \
".release-work/${ARCHIVE_BASE}/.git" \
".release-work/${ARCHIVE_BASE}/.src-repo" \
".release-work/${ARCHIVE_BASE}/.wiki-repo" \
".release-work/${ARCHIVE_BASE}/.release-work" \
".release-work/${ARCHIVE_BASE}/${DIST_DIR}"
fi
tar -czf "${DIST_DIR}/${ARCHIVE_BASE}.tar.gz" -C .release-work "${ARCHIVE_BASE}"
if command -v zip >/dev/null 2>&1; then
(
cd .release-work
zip -qr "../${DIST_DIR}/${ARCHIVE_BASE}.zip" "${ARCHIVE_BASE}"
)
else
ARCHIVE_BASE="${ARCHIVE_BASE}" DIST_DIR="${DIST_DIR}" python3 - <<'PY'
import os
import zipfile
base = os.environ["ARCHIVE_BASE"]
src = os.path.join(".release-work", base)
dst = os.path.join(os.environ["DIST_DIR"], f"{base}.zip")
with zipfile.ZipFile(dst, "w", zipfile.ZIP_DEFLATED) as zf:
for root, _, files in os.walk(src):
for file_name in files:
full = os.path.join(root, file_name)
arc = os.path.relpath(full, ".release-work")
zf.write(full, arc)
PY
fi
sha256sum "${DIST_DIR}"/* > "${DIST_DIR}/checksums-sha256.txt"
echo "ARCHIVE_BASE=${ARCHIVE_BASE}" >> "$GITHUB_ENV"
echo ">>> Артефакты релиза:"
ls -lh "${DIST_DIR}"
- name: "Генерация описания релиза"
shell: bash
run: |
set -euo pipefail
TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}"
PREV_TAG="${{ steps.meta.outputs.prev_tag }}"
DATE_UTC=$(date -u '+%Y-%m-%d %H:%M UTC')
CHANGELOG_FILE=""
if [ -f "wiki/Changelog.md" ]; then
CHANGELOG_FILE="wiki/Changelog.md"
elif [ -f "docs/ru/CHANGELOG.md" ]; then
CHANGELOG_FILE="docs/ru/CHANGELOG.md"
elif [ -f "docs/en/CHANGELOG_EN.md" ]; then
CHANGELOG_FILE="docs/en/CHANGELOG_EN.md"
fi
CHANGELOG_SECTION=""
if [ -n "${CHANGELOG_FILE}" ]; then
# Поддерживаем оба формата заголовков: "## [VERSION]" и "### [VERSION] - DATE"
CHANGELOG_SECTION=$(awk -v ver="${VERSION}" '
$0 ~ "^#{2,3} \\[" ver "\\]" { in_section=1; next }
/^#{2,3} \[/ && in_section { exit }
in_section { print }
' "${CHANGELOG_FILE}")
fi
COMMITS=""
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
if [ -n "${PREV_TAG}" ]; then
COMMITS=$(git log --pretty=format:'- %s (%h)' "${PREV_TAG}..${TAG}" --no-merges | head -50)
else
COMMITS=$(git log --pretty=format:'- %s (%h)' --no-merges | head -50)
fi
else
echo ">>> Предупреждение: .git недоступен, список коммитов будет пропущен"
fi
{
echo "## Release ${TAG}"
echo ""
echo "Релиз скриптового проекта без компиляции бинарников."
echo ""
echo "### Что входит в релиз"
echo "- Исходный код в форматах: ${ARCHIVE_BASE}.tar.gz, ${ARCHIVE_BASE}.zip"
echo "- Контрольные суммы: checksums-sha256.txt"
echo ""
if [ -n "${CHANGELOG_SECTION}" ]; then
echo "### Что сделано (из CHANGELOG)"
echo "${CHANGELOG_SECTION}"
echo ""
fi
echo "### Коммиты релиза"
if [ -n "${COMMITS}" ]; then
echo "${COMMITS}"
else
echo "- Недоступно (runner без .git)"
fi
echo ""
echo "---"
echo ""
echo "- Тег: ${TAG}"
echo "- Коммит: ${GITHUB_SHA}"
echo "- Дата (UTC): ${DATE_UTC}"
} > /tmp/release_body.md
echo ">>> Сформировано описание релиза: /tmp/release_body.md"
- name: "Создание релиза и загрузка архивов"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
TOKEN="${GIT_TOKEN:-$GITEA_TOKEN}"
if [ -z "${TOKEN}" ]; then
echo "ОШИБКА: не задан секрет GIT_TOKEN (или GITEA_TOKEN)."
exit 1
fi
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
TAG="${{ steps.meta.outputs.tag }}"
# Set up API URLs and auth header early (needed for tag check below)
if [ "${HOST}" = "github.com" ]; then
CREATE_URL="https://api.github.com/repos/${REPO}/releases"
AUTH_HEADER="Authorization: Bearer ${TOKEN}"
EXTRA_HEADERS=(-H "Accept: application/vnd.github+json")
else
CREATE_URL="${SERVER}/api/v1/repos/${REPO}/releases"
AUTH_HEADER="Authorization: token ${TOKEN}"
EXTRA_HEADERS=()
fi
TARGET_COMMITISH="${RELEASE_REF:-${{ github.event.repository.default_branch }}}"
if [ -z "${TARGET_COMMITISH}" ] || [ "${TARGET_COMMITISH}" = "null" ]; then
TARGET_COMMITISH="master"
fi
if [ -n "${GITHUB_SHA:-}" ]; then
TARGET_COMMITISH="${GITHUB_SHA}"
fi
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
TARGET_COMMITISH="$(git rev-list -n 1 "${TAG}" 2>/dev/null || echo "${TARGET_COMMITISH}")"
fi
# Ensure the tag exists on the remote (Gitea requires it before creating a release)
if [ "${HOST}" != "github.com" ]; then
TAG_HTTP_CODE=$(curl -sS -o /dev/null -w '%{http_code}' \
-H "${AUTH_HEADER}" \
"${SERVER}/api/v1/repos/${REPO}/tags/${TAG}")
if [ "${TAG_HTTP_CODE}" != "200" ]; then
echo ">>> Тег ${TAG} не найден на сервере (HTTP ${TAG_HTTP_CODE}), создание через API..."
TAG_CREATE_RESP=$(curl -sS -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/json" \
"${SERVER}/api/v1/repos/${REPO}/tags" \
-d "{\"tag_name\":\"${TAG}\",\"target\":\"${TARGET_COMMITISH}\"}")
echo ">>> Ответ создания тега: ${TAG_CREATE_RESP}"
else
echo ">>> Тег ${TAG} существует на сервере"
fi
fi
BODY_JSON=$(python3 - <<'PY'
import json
with open('/tmp/release_body.md', 'r', encoding='utf-8') as f:
print(json.dumps(f.read(), ensure_ascii=False))
PY
)
if [ "${HOST}" = "github.com" ]; then
RELEASE_PAYLOAD="{\"tag_name\":\"${TAG}\",\"target_commitish\":\"${TARGET_COMMITISH}\",\"name\":\"Release ${TAG}\",\"body\":${BODY_JSON},\"draft\":false,\"prerelease\":false}"
else
RELEASE_PAYLOAD="{\"tag_name\":\"${TAG}\",\"target\":\"${TARGET_COMMITISH}\",\"title\":\"Release ${TAG}\",\"note\":${BODY_JSON},\"draft\":false,\"prerelease\":false}"
fi
echo ">>> Создание релиза для тега ${TAG}..."
RELEASE_JSON=$(curl -sS -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/json" \
"${EXTRA_HEADERS[@]}" \
"${CREATE_URL}" \
-d "${RELEASE_PAYLOAD}")
if ! printf '%s' "${RELEASE_JSON}" | python3 -c "import sys, json; j=json.load(sys.stdin); print(j.get('id',''));" >/tmp/release_id.txt 2>/dev/null; then
echo "ОШИБКА: API вернул не-JSON при создании релиза"
echo "Ответ: ${RELEASE_JSON}"
exit 1
fi
RELEASE_ID=$(cat /tmp/release_id.txt)
rm -f /tmp/release_id.txt
if [ -z "${RELEASE_ID}" ] && [ "${HOST}" != "github.com" ]; then
echo ">>> Не удалось получить ID из create-response, пытаемся найти существующий релиз по тегу ${TAG}..."
RELEASE_JSON=$(curl -sS \
-H "${AUTH_HEADER}" \
"${SERVER}/api/v1/repos/${REPO}/releases/tags/${TAG}")
if printf '%s' "${RELEASE_JSON}" | python3 -c "import sys, json; j=json.load(sys.stdin); print(j.get('id',''));" >/tmp/release_id.txt 2>/dev/null; then
RELEASE_ID=$(cat /tmp/release_id.txt)
fi
rm -f /tmp/release_id.txt
fi
if [ -z "${RELEASE_ID}" ]; then
echo "ОШИБКА: не удалось получить ID релиза"
echo "${RELEASE_JSON}"
exit 1
fi
if [ "${HOST}" = "github.com" ]; then
UPLOAD_BASE=$(printf '%s' "${RELEASE_JSON}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('upload_url','').split('{')[0])")
RELEASE_URL="https://github.com/${REPO}/releases/tag/${TAG}"
else
UPLOAD_BASE="${SERVER}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets"
RELEASE_URL="${SERVER}/${REPO}/releases/tag/${TAG}"
fi
echo ">>> Загрузка файлов в релиз ${TAG}"
for file in "${DIST_DIR}"/*; do
[ -f "${file}" ] || continue
name=$(basename "${file}")
if [ "${HOST}" = "github.com" ]; then
curl -sf -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/octet-stream" \
"${EXTRA_HEADERS[@]}" \
--data-binary @"${file}" \
"${UPLOAD_BASE}?name=${name}" >/dev/null
else
curl -sf -X POST \
-H "${AUTH_HEADER}" \
-H "Content-Type: application/octet-stream" \
--data-binary @"${file}" \
"${UPLOAD_BASE}?name=${name}" >/dev/null
fi
echo " ✓ ${name}"
done
echo ""
echo ">>> Релиз опубликован: ${RELEASE_URL}"
+141 -141
View File
@@ -1,141 +1,141 @@
name: "Синхронизация Wiki"
on:
workflow_dispatch:
inputs:
ref:
description: "Branch or tag to run wiki sync from"
required: false
default: "master"
push:
branches:
- master
paths:
- 'wiki/**'
jobs:
sync-wiki:
name: "Синхронизация Wiki"
runs-on: native
steps:
# ── Получение исходного кода (без actions/checkout) ────────────────
- name: "Получение исходного кода"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
run: |
set -e
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
redact() {
local token="$1"
if [ -n "${token}" ]; then
grep -F -v "${token}" || true
else
cat
fi
}
echo ">>> Клонирование ${REPO}..."
if [ -d ".src-repo" ]; then
rm -rf .src-repo
fi
if [ -n "${GIT_TOKEN}" ]; then
if [ "${HOST}" = "github.com" ]; then
CLONE_URL="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO}.git"
else
CLONE_URL="https://${GIT_TOKEN}@${HOST}/${REPO}.git"
fi
else
CLONE_URL="${SERVER}/${REPO}.git"
fi
git clone --depth 1 "${CLONE_URL}" .src-repo 2>&1 | redact "${GIT_TOKEN}"
echo ">>> Исходный код получен: $(cd .src-repo && git log --oneline -1)"
- name: "Проверка папки wiki/"
shell: bash
run: |
if [ ! -d ".src-repo/wiki" ]; then
echo "Папка wiki/ не найдена — синхронизация не требуется."
exit 0
fi
echo ">>> Найдено файлов wiki: $(find .src-repo/wiki -type f | wc -l)"
- name: "Синхронизация wiki в DFGit Wiki"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
run: |
set -e
redact() {
local token="$1"
if [ -n "${token}" ]; then
grep -F -v "${token}" || true
else
cat
fi
}
if [ -z "${GIT_TOKEN}" ]; then
echo "GIT_TOKEN не задан. Добавьте секрет в настройках: Settings -> Secrets -> Actions."
echo "Пропуск синхронизации wiki без ошибки."
exit 0
fi
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
WIKI_REPO_URL="${SERVER}/${REPO}.wiki.git"
if [ "${HOST}" = "github.com" ]; then
AUTH_WIKI_REPO_URL="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO}.wiki.git"
else
AUTH_WIKI_REPO_URL="https://oauth2:${GIT_TOKEN}@${HOST}/${REPO}.wiki.git"
fi
echo ">>> Клонируем wiki-репозиторий..."
if ! git clone --depth 1 "${AUTH_WIKI_REPO_URL}" .wiki-repo 2>&1 | redact "${GIT_TOKEN}"; then
echo "Wiki-репозиторий недоступен или ещё не инициализирован: ${WIKI_REPO_URL}"
echo "Пропуск синхронизации без ошибки."
exit 0
fi
# rsync или резервный вариант через cp
if command -v rsync &>/dev/null; then
rsync -a --delete --exclude '.git/' .src-repo/wiki/ .wiki-repo/
else
# Удаляем старые файлы (кроме .git) и копируем новые
find .wiki-repo -mindepth 1 -not -path '.wiki-repo/.git/*' -not -name '.git' -delete 2>/dev/null || true
cp -a .src-repo/wiki/* .wiki-repo/
fi
cd .wiki-repo
git add -A
if git diff --cached --quiet; then
echo ">>> Изменений в wiki нет — пуш не требуется."
exit 0
fi
git config user.name "dfgit-actions[bot]"
git config user.email "dfgit-actions@local"
DEFAULT_BRANCH=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p')
if [ -z "${DEFAULT_BRANCH}" ]; then
DEFAULT_BRANCH="master"
fi
git commit -m "docs(wiki): синхронизация из master @ ${{ github.sha }}"
git push origin "HEAD:${DEFAULT_BRANCH}" 2>&1 | redact "${GIT_TOKEN}"
echo ">>> Wiki синхронизирована в ветку ${DEFAULT_BRANCH}."
name: "Синхронизация Wiki"
on:
workflow_dispatch:
inputs:
ref:
description: "Branch or tag to run wiki sync from"
required: false
default: "master"
push:
branches:
- master
paths:
- 'wiki/**'
jobs:
sync-wiki:
name: "Синхронизация Wiki"
runs-on: native
steps:
# ── Получение исходного кода (без actions/checkout) ────────────────
- name: "Получение исходного кода"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
run: |
set -e
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
redact() {
local token="$1"
if [ -n "${token}" ]; then
grep -F -v "${token}" || true
else
cat
fi
}
echo ">>> Клонирование ${REPO}..."
if [ -d ".src-repo" ]; then
rm -rf .src-repo
fi
if [ -n "${GIT_TOKEN}" ]; then
if [ "${HOST}" = "github.com" ]; then
CLONE_URL="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO}.git"
else
CLONE_URL="https://${GIT_TOKEN}@${HOST}/${REPO}.git"
fi
else
CLONE_URL="${SERVER}/${REPO}.git"
fi
git clone --depth 1 "${CLONE_URL}" .src-repo 2>&1 | redact "${GIT_TOKEN}"
echo ">>> Исходный код получен: $(cd .src-repo && git log --oneline -1)"
- name: "Проверка папки wiki/"
shell: bash
run: |
if [ ! -d ".src-repo/wiki" ]; then
echo "Папка wiki/ не найдена — синхронизация не требуется."
exit 0
fi
echo ">>> Найдено файлов wiki: $(find .src-repo/wiki -type f | wc -l)"
- name: "Синхронизация wiki в DFGit Wiki"
shell: bash
env:
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}
run: |
set -e
redact() {
local token="$1"
if [ -n "${token}" ]; then
grep -F -v "${token}" || true
else
cat
fi
}
if [ -z "${GIT_TOKEN}" ]; then
echo "GIT_TOKEN не задан. Добавьте секрет в настройках: Settings -> Secrets -> Actions."
echo "Пропуск синхронизации wiki без ошибки."
exit 0
fi
SERVER="${{ github.server_url }}"
REPO="${{ github.repository }}"
HOST="${SERVER#https://}"
HOST="${HOST#http://}"
WIKI_REPO_URL="${SERVER}/${REPO}.wiki.git"
if [ "${HOST}" = "github.com" ]; then
AUTH_WIKI_REPO_URL="https://x-access-token:${GIT_TOKEN}@${HOST}/${REPO}.wiki.git"
else
AUTH_WIKI_REPO_URL="https://oauth2:${GIT_TOKEN}@${HOST}/${REPO}.wiki.git"
fi
echo ">>> Клонируем wiki-репозиторий..."
if ! git clone --depth 1 "${AUTH_WIKI_REPO_URL}" .wiki-repo 2>&1 | redact "${GIT_TOKEN}"; then
echo "Wiki-репозиторий недоступен или ещё не инициализирован: ${WIKI_REPO_URL}"
echo "Пропуск синхронизации без ошибки."
exit 0
fi
# rsync или резервный вариант через cp
if command -v rsync &>/dev/null; then
rsync -a --delete --exclude '.git/' .src-repo/wiki/ .wiki-repo/
else
# Удаляем старые файлы (кроме .git) и копируем новые
find .wiki-repo -mindepth 1 -not -path '.wiki-repo/.git/*' -not -name '.git' -delete 2>/dev/null || true
cp -a .src-repo/wiki/* .wiki-repo/
fi
cd .wiki-repo
git add -A
if git diff --cached --quiet; then
echo ">>> Изменений в wiki нет — пуш не требуется."
exit 0
fi
git config user.name "dfgit-actions[bot]"
git config user.email "dfgit-actions@local"
DEFAULT_BRANCH=$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p')
if [ -z "${DEFAULT_BRANCH}" ]; then
DEFAULT_BRANCH="master"
fi
git commit -m "docs(wiki): синхронизация из master @ ${{ github.sha }}"
git push origin "HEAD:${DEFAULT_BRANCH}" 2>&1 | redact "${GIT_TOKEN}"
echo ">>> Wiki синхронизирована в ветку ${DEFAULT_BRANCH}."
+193 -193
View File
@@ -1,193 +1,193 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
PIPE_MANIFEST
# PyInstaller
*.manifest
*.spec
# PyInstaller build artifacts
build/
dist/
*.tar.gz
*.zip
*.sha256
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
Pipfile.lock
# poetry
poetry.lock
# pdm
.pdm.toml
# PEP 582
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# SSL Certificates and Keys (CRITICAL - DO NOT COMMIT!)
*.pem
*.key
*.crt
*.csr
*.pfx
*.p12
/ssl/
/certs/
# Configuration files with credentials
config.yml
config.json
.regru_credentials
credentials.txt
*.secret
config.json
# Logs
*.log
logs/
/var/log/
# OS-specific
.DS_Store
Thumbs.db
desktop.ini
# Test certificates
test_certs/
*.test.pem
*.test.key
# Backup files
*.bak
*.backup
*~
# Temporary files
tmp/
temp/
*.tmp
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
PIPE_MANIFEST
# PyInstaller
*.manifest
*.spec
# PyInstaller build artifacts
build/
dist/
*.tar.gz
*.zip
*.sha256
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
Pipfile.lock
# poetry
poetry.lock
# pdm
.pdm.toml
# PEP 582
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# SSL Certificates and Keys (CRITICAL - DO NOT COMMIT!)
*.pem
*.key
*.crt
*.csr
*.pfx
*.p12
/ssl/
/certs/
# Configuration files with credentials
config.yml
config.json
.regru_credentials
credentials.txt
*.secret
config.json
# Logs
*.log
logs/
/var/log/
# OS-specific
.DS_Store
Thumbs.db
desktop.ini
# Test certificates
test_certs/
*.test.pem
*.test.key
# Backup files
*.bak
*.backup
*~
# Temporary files
tmp/
temp/
*.tmp
+896 -896
View File
File diff suppressed because it is too large Load Diff
+2167 -2167
View File
File diff suppressed because it is too large Load Diff
+21 -21
View File
@@ -1,21 +1,21 @@
{
"regru_username": "your_username",
"regru_password": "your_password",
"domain": "example.com",
"domains": [
"*.example.com,example.com",
"gitea.example.com"
],
"wildcard": true,
"email": "admin@example.com",
"cert_dir": "/etc/letsencrypt/live",
"log_file": "/var/log/letsencrypt_regru.log",
"dns_propagation_wait": 180,
"dns_check_attempts": 20,
"dns_check_interval": 15,
"renewal_days": 30,
"npm_enabled": true,
"npm_host": "http://192.0.2.1:81",
"npm_email": "admin@example.com",
"npm_password": "changeme"
}
{
"regru_username": "your_username",
"regru_password": "your_password",
"domain": "example.com",
"domains": [
"*.example.com,example.com",
"gitea.example.com"
],
"wildcard": true,
"email": "admin@example.com",
"cert_dir": "/etc/letsencrypt/live",
"log_file": "/var/log/letsencrypt_regru.log",
"dns_propagation_wait": 180,
"dns_check_attempts": 20,
"dns_check_interval": 15,
"renewal_days": 30,
"npm_enabled": true,
"npm_host": "http://192.0.2.1:81",
"npm_email": "admin@example.com",
"npm_password": "changeme"
}
+168 -168
View File
@@ -1,168 +1,168 @@
# Git Hooks для Gitea
Автоматическая синхронизация с GitHub после push в Gitea.
## 📁 Файлы
- **post-receive** - Hook для автоматического push в GitHub
## 🚀 Установка
### 1. Найдите путь к репозиторию на сервере Gitea
```bash
# Обычно это один из путей:
/var/lib/gitea/data/gitea-repositories/username/configure_nginx_manager.git
# или
/home/git/gitea-repositories/username/configure_nginx_manager.git
```
### 2. Скопируйте hook
```bash
# На сервере Gitea
cd /path/to/gitea-repositories/username/configure_nginx_manager.git/hooks/
# Скопируйте файл
cp /path/to/this/repo/gitea-hooks/post-receive ./
# Или загрузите напрямую
wget https://raw.githubusercontent.com/username/configure_nginx_manager/main/gitea-hooks/post-receive
```
### 3. Настройте hook
```bash
nano post-receive
```
Измените:
```bash
GITHUB_REPO="git@github.com:YOUR_USERNAME/configure_nginx_manager.git"
```
### 4. Сделайте исполняемым
```bash
chmod +x post-receive
chown git:git post-receive
```
### 5. Создайте директорию для логов
```bash
mkdir -p /var/log/gitea
chown git:git /var/log/gitea
```
## 🔑 Настройка аутентификации
### Вариант A: SSH (Рекомендуется)
```bash
# На сервере Gitea под пользователем git
sudo su - git
ssh-keygen -t ed25519 -C "gitea-sync"
# Скопируйте публичный ключ
cat ~/.ssh/id_ed25519.pub
# Добавьте на GitHub:
# Settings → SSH and GPG keys → New SSH key
# Проверьте
ssh -T git@github.com
```
### Вариант B: HTTPS с токеном
1. Создайте Personal Access Token на GitHub
- Settings → Developer settings → Personal access tokens
- Scope: `repo`
2. Используйте в hook:
```bash
GITHUB_REPO="https://YOUR_TOKEN@github.com/username/configure_nginx_manager.git"
```
## ✅ Проверка
```bash
# Тестовый push
cd /tmp
git clone http://gitea.example.com/username/configure_nginx_manager.git
cd configure_nginx_manager
echo "test" >> README.md
git add README.md
git commit -m "Test sync"
git push
# Проверьте лог
tail -f /var/log/gitea/github-sync.log
# Проверьте GitHub - изменения должны появиться через 1-2 секунды
```
## 📊 Что делает hook
1. ✅ Отслеживает push в ветки `main` и `master`
2. ✅ Автоматически пушит в GitHub
3. ✅ Синхронизирует теги
4. ✅ Логирует все операции
5. ✅ Показывает красивый вывод с эмодзи
## 🐛 Устранение проблем
### Hook не срабатывает
```bash
# Проверьте права
ls -la post-receive
# Должно быть: -rwxr-xr-x
# Проверьте владельца
chown git:git post-receive
# Проверьте синтаксис
bash -n post-receive
```
### Permission denied
```bash
# Для SSH
ssh -T git@github.com
# Проверьте права на ключ
chmod 600 ~/.ssh/id_ed25519
# Для HTTPS - проверьте токен
```
### Не находит git
```bash
# Добавьте PATH в начало hook:
export PATH=/usr/bin:/usr/local/bin:$PATH
```
## 📝 Логи
```bash
# Просмотр логов синхронизации
tail -f /var/log/gitea/github-sync.log
# Очистка старых логов
> /var/log/gitea/github-sync.log
```
## 🔄 Альтернативы
Если Git Hook не подходит, см. другие методы в [GITEA_SYNC.md](../GITEA_SYNC.md):
- GitHub Actions (каждый час)
- Gitea Mirror (встроенная функция)
- Двойной remote (локально)
---
**См. также**: [GITEA_SYNC.md](../GITEA_SYNC.md) для подробной документации
# Git Hooks для Gitea
Автоматическая синхронизация с GitHub после push в Gitea.
## 📁 Файлы
- **post-receive** - Hook для автоматического push в GitHub
## 🚀 Установка
### 1. Найдите путь к репозиторию на сервере Gitea
```bash
# Обычно это один из путей:
/var/lib/gitea/data/gitea-repositories/username/configure_nginx_manager.git
# или
/home/git/gitea-repositories/username/configure_nginx_manager.git
```
### 2. Скопируйте hook
```bash
# На сервере Gitea
cd /path/to/gitea-repositories/username/configure_nginx_manager.git/hooks/
# Скопируйте файл
cp /path/to/this/repo/gitea-hooks/post-receive ./
# Или загрузите напрямую
wget https://raw.githubusercontent.com/username/configure_nginx_manager/main/gitea-hooks/post-receive
```
### 3. Настройте hook
```bash
nano post-receive
```
Измените:
```bash
GITHUB_REPO="git@github.com:YOUR_USERNAME/configure_nginx_manager.git"
```
### 4. Сделайте исполняемым
```bash
chmod +x post-receive
chown git:git post-receive
```
### 5. Создайте директорию для логов
```bash
mkdir -p /var/log/gitea
chown git:git /var/log/gitea
```
## 🔑 Настройка аутентификации
### Вариант A: SSH (Рекомендуется)
```bash
# На сервере Gitea под пользователем git
sudo su - git
ssh-keygen -t ed25519 -C "gitea-sync"
# Скопируйте публичный ключ
cat ~/.ssh/id_ed25519.pub
# Добавьте на GitHub:
# Settings → SSH and GPG keys → New SSH key
# Проверьте
ssh -T git@github.com
```
### Вариант B: HTTPS с токеном
1. Создайте Personal Access Token на GitHub
- Settings → Developer settings → Personal access tokens
- Scope: `repo`
2. Используйте в hook:
```bash
GITHUB_REPO="https://YOUR_TOKEN@github.com/username/configure_nginx_manager.git"
```
## ✅ Проверка
```bash
# Тестовый push
cd /tmp
git clone http://gitea.example.com/username/configure_nginx_manager.git
cd configure_nginx_manager
echo "test" >> README.md
git add README.md
git commit -m "Test sync"
git push
# Проверьте лог
tail -f /var/log/gitea/github-sync.log
# Проверьте GitHub - изменения должны появиться через 1-2 секунды
```
## 📊 Что делает hook
1. ✅ Отслеживает push в ветки `main` и `master`
2. ✅ Автоматически пушит в GitHub
3. ✅ Синхронизирует теги
4. ✅ Логирует все операции
5. ✅ Показывает красивый вывод с эмодзи
## 🐛 Устранение проблем
### Hook не срабатывает
```bash
# Проверьте права
ls -la post-receive
# Должно быть: -rwxr-xr-x
# Проверьте владельца
chown git:git post-receive
# Проверьте синтаксис
bash -n post-receive
```
### Permission denied
```bash
# Для SSH
ssh -T git@github.com
# Проверьте права на ключ
chmod 600 ~/.ssh/id_ed25519
# Для HTTPS - проверьте токен
```
### Не находит git
```bash
# Добавьте PATH в начало hook:
export PATH=/usr/bin:/usr/local/bin:$PATH
```
## 📝 Логи
```bash
# Просмотр логов синхронизации
tail -f /var/log/gitea/github-sync.log
# Очистка старых логов
> /var/log/gitea/github-sync.log
```
## 🔄 Альтернативы
Если Git Hook не подходит, см. другие методы в [GITEA_SYNC.md](../GITEA_SYNC.md):
- GitHub Actions (каждый час)
- Gitea Mirror (встроенная функция)
- Двойной remote (локально)
---
**См. также**: [GITEA_SYNC.md](../GITEA_SYNC.md) для подробной документации
+168 -168
View File
@@ -1,168 +1,168 @@
# Git Hooks for Gitea
Automatic synchronization with GitHub after push to Gitea.
## 📁 Files
- **post-receive** - Hook for automatic push to GitHub
## 🚀 Installation
### 1. Find Repository Path on Gitea Server
```bash
# Usually one of these paths:
/var/lib/gitea/data/gitea-repositories/username/configure_nginx_manager.git
# or
/home/git/gitea-repositories/username/configure_nginx_manager.git
```
### 2. Copy Hook
```bash
# On Gitea server
cd /path/to/gitea-repositories/username/configure_nginx_manager.git/hooks/
# Copy file
cp /path/to/this/repo/gitea-hooks/post-receive ./
# Or download directly
wget https://raw.githubusercontent.com/username/configure_nginx_manager/main/gitea-hooks/post-receive
```
### 3. Configure Hook
```bash
nano post-receive
```
Change:
```bash
GITHUB_REPO="git@github.com:YOUR_USERNAME/configure_nginx_manager.git"
```
### 4. Make Executable
```bash
chmod +x post-receive
chown git:git post-receive
```
### 5. Create Log Directory
```bash
mkdir -p /var/log/gitea
chown git:git /var/log/gitea
```
## 🔑 Authentication Setup
### Option A: SSH (Recommended)
```bash
# On Gitea server as git user
sudo su - git
ssh-keygen -t ed25519 -C "gitea-sync"
# Copy public key
cat ~/.ssh/id_ed25519.pub
# Add to GitHub:
# Settings → SSH and GPG keys → New SSH key
# Verify
ssh -T git@github.com
```
### Option B: HTTPS with Token
1. Create Personal Access Token on GitHub
- Settings → Developer settings → Personal access tokens
- Scope: `repo`
2. Use in hook:
```bash
GITHUB_REPO="https://YOUR_TOKEN@github.com/username/configure_nginx_manager.git"
```
## ✅ Verification
```bash
# Test push
cd /tmp
git clone http://gitea.example.com/username/configure_nginx_manager.git
cd configure_nginx_manager
echo "test" >> README.md
git add README.md
git commit -m "Test sync"
git push
# Check log
tail -f /var/log/gitea/github-sync.log
# Check GitHub - changes should appear in 1-2 seconds
```
## 📊 What Hook Does
1. ✅ Monitors pushes to `main` and `master` branches
2. ✅ Automatically pushes to GitHub
3. ✅ Synchronizes tags
4. ✅ Logs all operations
5. ✅ Shows beautiful output with emojis
## 🐛 Troubleshooting
### Hook Not Firing
```bash
# Check permissions
ls -la post-receive
# Should be: -rwxr-xr-x
# Check owner
chown git:git post-receive
# Check syntax
bash -n post-receive
```
### Permission Denied
```bash
# For SSH
ssh -T git@github.com
# Check key permissions
chmod 600 ~/.ssh/id_ed25519
# For HTTPS - check token
```
### Can't Find Git
```bash
# Add PATH to beginning of hook:
export PATH=/usr/bin:/usr/local/bin:$PATH
```
## 📝 Logs
```bash
# View sync logs
tail -f /var/log/gitea/github-sync.log
# Clear old logs
> /var/log/gitea/github-sync.log
```
## 🔄 Alternatives
If Git Hook doesn't work, see other methods in [GITEA_SYNC_EN.md](../GITEA_SYNC_EN.md):
- GitHub Actions (every hour)
- Gitea Mirror (built-in feature)
- Double remote (locally)
---
**See also**: [GITEA_SYNC_EN.md](../GITEA_SYNC_EN.md) for detailed documentation
# Git Hooks for Gitea
Automatic synchronization with GitHub after push to Gitea.
## 📁 Files
- **post-receive** - Hook for automatic push to GitHub
## 🚀 Installation
### 1. Find Repository Path on Gitea Server
```bash
# Usually one of these paths:
/var/lib/gitea/data/gitea-repositories/username/configure_nginx_manager.git
# or
/home/git/gitea-repositories/username/configure_nginx_manager.git
```
### 2. Copy Hook
```bash
# On Gitea server
cd /path/to/gitea-repositories/username/configure_nginx_manager.git/hooks/
# Copy file
cp /path/to/this/repo/gitea-hooks/post-receive ./
# Or download directly
wget https://raw.githubusercontent.com/username/configure_nginx_manager/main/gitea-hooks/post-receive
```
### 3. Configure Hook
```bash
nano post-receive
```
Change:
```bash
GITHUB_REPO="git@github.com:YOUR_USERNAME/configure_nginx_manager.git"
```
### 4. Make Executable
```bash
chmod +x post-receive
chown git:git post-receive
```
### 5. Create Log Directory
```bash
mkdir -p /var/log/gitea
chown git:git /var/log/gitea
```
## 🔑 Authentication Setup
### Option A: SSH (Recommended)
```bash
# On Gitea server as git user
sudo su - git
ssh-keygen -t ed25519 -C "gitea-sync"
# Copy public key
cat ~/.ssh/id_ed25519.pub
# Add to GitHub:
# Settings → SSH and GPG keys → New SSH key
# Verify
ssh -T git@github.com
```
### Option B: HTTPS with Token
1. Create Personal Access Token on GitHub
- Settings → Developer settings → Personal access tokens
- Scope: `repo`
2. Use in hook:
```bash
GITHUB_REPO="https://YOUR_TOKEN@github.com/username/configure_nginx_manager.git"
```
## ✅ Verification
```bash
# Test push
cd /tmp
git clone http://gitea.example.com/username/configure_nginx_manager.git
cd configure_nginx_manager
echo "test" >> README.md
git add README.md
git commit -m "Test sync"
git push
# Check log
tail -f /var/log/gitea/github-sync.log
# Check GitHub - changes should appear in 1-2 seconds
```
## 📊 What Hook Does
1. ✅ Monitors pushes to `main` and `master` branches
2. ✅ Automatically pushes to GitHub
3. ✅ Synchronizes tags
4. ✅ Logs all operations
5. ✅ Shows beautiful output with emojis
## 🐛 Troubleshooting
### Hook Not Firing
```bash
# Check permissions
ls -la post-receive
# Should be: -rwxr-xr-x
# Check owner
chown git:git post-receive
# Check syntax
bash -n post-receive
```
### Permission Denied
```bash
# For SSH
ssh -T git@github.com
# Check key permissions
chmod 600 ~/.ssh/id_ed25519
# For HTTPS - check token
```
### Can't Find Git
```bash
# Add PATH to beginning of hook:
export PATH=/usr/bin:/usr/local/bin:$PATH
```
## 📝 Logs
```bash
# View sync logs
tail -f /var/log/gitea/github-sync.log
# Clear old logs
> /var/log/gitea/github-sync.log
```
## 🔄 Alternatives
If Git Hook doesn't work, see other methods in [GITEA_SYNC_EN.md](../GITEA_SYNC_EN.md):
- GitHub Actions (every hour)
- Gitea Mirror (built-in feature)
- Double remote (locally)
---
**See also**: [GITEA_SYNC_EN.md](../GITEA_SYNC_EN.md) for detailed documentation
+83 -83
View File
@@ -1,83 +1,83 @@
#!/bin/bash
# ==============================================================================
# Post-receive hook для Gitea
# Автоматически синхронизирует изменения с GitHub после push
#
# Установка:
# 1. Разместить в: /path/to/gitea/data/gitea-repositories/username/repo.git/hooks/
# 2. Переименовать в: post-receive
# 3. chmod +x post-receive
# 4. Настроить переменные ниже
# ==============================================================================
# Конфигурация
GITHUB_REPO="git@github.com:username/configure_nginx_manager.git"
# Или с HTTPS и токеном:
# GITHUB_REPO="https://YOUR_GITHUB_TOKEN@github.com/username/configure_nginx_manager.git"
LOG_FILE="/var/log/gitea/github-sync.log"
# Цвета для логов
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# ==============================================================================
# Функция логирования
# ==============================================================================
log() {
echo -e "${2:-$NC}[$(date +'%d.%m.%Y %H:%M:%S')] $1${NC}" | tee -a "$LOG_FILE"
}
# ==============================================================================
# Основная логика
# ==============================================================================
log "═══════════════════════════════════════════════════════════════" "$GREEN"
log "🔄 Начало синхронизации с GitHub" "$GREEN"
log "═══════════════════════════════════════════════════════════════" "$GREEN"
# Читаем информацию о push
while read oldrev newrev refname; do
log "📝 Изменения обнаружены:" "$YELLOW"
log " Branch: ${refname#refs/heads/}"
log " Old commit: ${oldrev:0:8}"
log " New commit: ${newrev:0:8}"
# Проверяем наличие GitHub remote
if ! git remote | grep -q github; then
log " Добавление GitHub remote..." "$YELLOW"
git remote add github "$GITHUB_REPO" 2>&1 | tee -a "$LOG_FILE"
fi
# Пушим в GitHub
log "⬆️ Отправка изменений в GitHub..." "$YELLOW"
# Только для main/master веток
if [[ "$refname" == "refs/heads/main" ]] || [[ "$refname" == "refs/heads/master" ]]; then
if git push github "$refname" --force 2>&1 | tee -a "$LOG_FILE"; then
log "✅ Успешно синхронизировано с GitHub" "$GREEN"
else
log "❌ Ошибка при синхронизации с GitHub" "$RED"
exit 1
fi
# Пушим теги
log "🏷️ Отправка тегов..." "$YELLOW"
if git push github --tags 2>&1 | tee -a "$LOG_FILE"; then
log "✅ Теги синхронизированы" "$GREEN"
else
log "⚠️ Не удалось синхронизировать теги" "$YELLOW"
fi
else
log " Ветка ${refname#refs/heads/} игнорируется (не main/master)" "$YELLOW"
fi
done
log "═══════════════════════════════════════════════════════════════" "$GREEN"
log "✅ Синхронизация завершена" "$GREEN"
log "═══════════════════════════════════════════════════════════════" "$GREEN"
exit 0
#!/bin/bash
# ==============================================================================
# Post-receive hook для Gitea
# Автоматически синхронизирует изменения с GitHub после push
#
# Установка:
# 1. Разместить в: /path/to/gitea/data/gitea-repositories/username/repo.git/hooks/
# 2. Переименовать в: post-receive
# 3. chmod +x post-receive
# 4. Настроить переменные ниже
# ==============================================================================
# Конфигурация
GITHUB_REPO="git@github.com:username/configure_nginx_manager.git"
# Или с HTTPS и токеном:
# GITHUB_REPO="https://YOUR_GITHUB_TOKEN@github.com/username/configure_nginx_manager.git"
LOG_FILE="/var/log/gitea/github-sync.log"
# Цвета для логов
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# ==============================================================================
# Функция логирования
# ==============================================================================
log() {
echo -e "${2:-$NC}[$(date +'%d.%m.%Y %H:%M:%S')] $1${NC}" | tee -a "$LOG_FILE"
}
# ==============================================================================
# Основная логика
# ==============================================================================
log "═══════════════════════════════════════════════════════════════" "$GREEN"
log "🔄 Начало синхронизации с GitHub" "$GREEN"
log "═══════════════════════════════════════════════════════════════" "$GREEN"
# Читаем информацию о push
while read oldrev newrev refname; do
log "📝 Изменения обнаружены:" "$YELLOW"
log " Branch: ${refname#refs/heads/}"
log " Old commit: ${oldrev:0:8}"
log " New commit: ${newrev:0:8}"
# Проверяем наличие GitHub remote
if ! git remote | grep -q github; then
log " Добавление GitHub remote..." "$YELLOW"
git remote add github "$GITHUB_REPO" 2>&1 | tee -a "$LOG_FILE"
fi
# Пушим в GitHub
log "⬆️ Отправка изменений в GitHub..." "$YELLOW"
# Только для main/master веток
if [[ "$refname" == "refs/heads/main" ]] || [[ "$refname" == "refs/heads/master" ]]; then
if git push github "$refname" --force 2>&1 | tee -a "$LOG_FILE"; then
log "✅ Успешно синхронизировано с GitHub" "$GREEN"
else
log "❌ Ошибка при синхронизации с GitHub" "$RED"
exit 1
fi
# Пушим теги
log "🏷️ Отправка тегов..." "$YELLOW"
if git push github --tags 2>&1 | tee -a "$LOG_FILE"; then
log "✅ Теги синхронизированы" "$GREEN"
else
log "⚠️ Не удалось синхронизировать теги" "$YELLOW"
fi
else
log " Ветка ${refname#refs/heads/} игнорируется (не main/master)" "$YELLOW"
fi
done
log "═══════════════════════════════════════════════════════════════" "$GREEN"
log "✅ Синхронизация завершена" "$GREEN"
log "═══════════════════════════════════════════════════════════════" "$GREEN"
exit 0
+556 -556
View File
File diff suppressed because it is too large Load Diff
+695 -695
View File
File diff suppressed because it is too large Load Diff
+3608 -3608
View File
File diff suppressed because it is too large Load Diff
+290 -290
View File
@@ -1,290 +1,290 @@
#!/bin/bash
###############################################################################
# Скрипт для создания и обновления SSL сертификата Let's Encrypt
# с использованием DNS-валидации через API reg.ru
#
# Автор: Фофанов Дмитрий
# Дата: 27.10.2025
# Описание: Автоматизация получения wildcard сертификата через Certbot
# с использованием DNS-01 challenge и API reg.ru
###############################################################################
# ==============================================================================
# КОНФИГУРАЦИЯ
# ==============================================================================
# Учетные данные API reg.ru (получить на https://www.reg.ru/user/account/)
REGRU_USERNAME="your_username" # Имя пользователя reg.ru
REGRU_PASSWORD="your_password" # Пароль от аккаунта reg.ru
# Параметры домена и сертификата
DOMAIN="example.com" # Основной домен
WILDCARD_DOMAIN="*.example.com" # Wildcard домен
EMAIL="admin@example.com" # Email для уведомлений Let's Encrypt
# Директории для хранения сертификатов
CERT_DIR="/etc/letsencrypt/live/$DOMAIN"
CREDENTIALS_DIR="/etc/letsencrypt/credentials"
CREDENTIALS_FILE="$CREDENTIALS_DIR/regru.ini"
# Логирование
LOG_FILE="/var/log/letsencrypt_regru.log"
TIMESTAMP=$(date '+%d.%m.%Y %H:%M:%S')
# ==============================================================================
# ФУНКЦИИ
# ==============================================================================
# Логирование сообщений
log() {
echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}
# Проверка установки необходимых пакетов
check_dependencies() {
log "Проверка зависимостей..."
# Проверка certbot
if ! command -v certbot &> /dev/null; then
log "ОШИБКА: certbot не установлен. Установите: apt-get install certbot"
exit 1
fi
# Проверка curl
if ! command -v curl &> /dev/null; then
log "ОШИБКА: curl не установлен. Установите: apt-get install curl"
exit 1
fi
# Проверка jq для обработки JSON
if ! command -v jq &> /dev/null; then
log "ОШИБКА: jq не установлен. Установите: apt-get install jq"
exit 1
fi
log "Все зависимости установлены"
}
# Создание директории для credentials
setup_credentials_dir() {
log "Настройка директории для учетных данных..."
if [ ! -d "$CREDENTIALS_DIR" ]; then
mkdir -p "$CREDENTIALS_DIR"
chmod 700 "$CREDENTIALS_DIR"
fi
}
# Создание файла с учетными данными для certbot-dns-regru
create_credentials_file() {
log "Создание файла с учетными данными reg.ru..."
cat > "$CREDENTIALS_FILE" <<EOF
# Учетные данные API reg.ru для DNS-валидации
dns_regru_username = $REGRU_USERNAME
dns_regru_password = $REGRU_PASSWORD
EOF
chmod 600 "$CREDENTIALS_FILE"
log "Файл учетных данных создан: $CREDENTIALS_FILE"
}
# Установка плагина certbot-dns-regru (если еще не установлен)
install_certbot_plugin() {
log "Проверка плагина certbot-dns-regru..."
if ! pip3 list | grep -q certbot-dns-regru; then
log "Установка certbot-dns-regru..."
pip3 install certbot-dns-regru
if [ $? -eq 0 ]; then
log "Плагин certbot-dns-regru успешно установлен"
else
log "ОШИБКА: Не удалось установить certbot-dns-regru"
exit 1
fi
else
log "Плагин certbot-dns-regru уже установлен"
fi
}
# Получение нового сертификата
obtain_certificate() {
log "Запрос нового SSL сертификата для домена: $DOMAIN и $WILDCARD_DOMAIN"
certbot certonly \
--dns-regru \
--dns-regru-credentials "$CREDENTIALS_FILE" \
--dns-regru-propagation-seconds 60 \
-d "$DOMAIN" \
-d "$WILDCARD_DOMAIN" \
--email "$EMAIL" \
--agree-tos \
--non-interactive \
--preferred-challenges dns-01
if [ $? -eq 0 ]; then
log "Сертификат успешно получен!"
log "Путь к сертификатам: $CERT_DIR"
return 0
else
log "ОШИБКА: Не удалось получить сертификат"
return 1
fi
}
# Обновление существующего сертификата
renew_certificate() {
log "Проверка и обновление существующих сертификатов..."
certbot renew \
--dns-regru \
--dns-regru-credentials "$CREDENTIALS_FILE" \
--dns-regru-propagation-seconds 60 \
--non-interactive
if [ $? -eq 0 ]; then
log "Проверка обновления завершена успешно"
return 0
else
log "ОШИБКА: Проблема при обновлении сертификата"
return 1
fi
}
# Проверка срока действия сертификата
check_certificate_expiry() {
log "Проверка срока действия сертификата..."
if [ -f "$CERT_DIR/cert.pem" ]; then
EXPIRY_DATE=$(openssl x509 -enddate -noout -in "$CERT_DIR/cert.pem" | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $CURRENT_EPOCH) / 86400 ))
log "Сертификат истекает: $EXPIRY_DATE (осталось дней: $DAYS_LEFT)"
if [ $DAYS_LEFT -lt 30 ]; then
log "ВНИМАНИЕ: Сертификат истекает менее чем через 30 дней. Требуется обновление!"
return 1
else
log "Сертификат действителен"
return 0
fi
else
log "Сертификат не найден. Требуется создание нового сертификата."
return 2
fi
}
# Перезагрузка веб-сервера (Nginx/Apache)
reload_webserver() {
log "Перезагрузка веб-сервера..."
# Определяем, какой веб-сервер используется
if systemctl is-active --quiet nginx; then
systemctl reload nginx
log "Nginx перезагружен"
elif systemctl is-active --quiet apache2; then
systemctl reload apache2
log "Apache перезагружен"
elif systemctl is-active --quiet httpd; then
systemctl reload httpd
log "Apache (httpd) перезагружен"
else
log "ВНИМАНИЕ: Веб-сервер не найден или не активен. Пропускаем перезагрузку."
fi
}
# Отправка уведомления (опционально)
send_notification() {
local MESSAGE=$1
log "Уведомление: $MESSAGE"
# Здесь можно добавить отправку email, Telegram, Slack и т.д.
# Пример: echo "$MESSAGE" | mail -s "SSL Certificate Update" admin@example.com
}
# Вывод информации о сертификате
display_certificate_info() {
if [ -f "$CERT_DIR/cert.pem" ]; then
log "=========================================="
log "Информация о сертификате:"
log "=========================================="
openssl x509 -in "$CERT_DIR/cert.pem" -text -noout | grep -E "(Subject:|Issuer:|Not Before|Not After|DNS:)" | tee -a "$LOG_FILE"
log "=========================================="
log "Пути к файлам сертификата:"
log " Сертификат: $CERT_DIR/cert.pem"
log " Приватный ключ: $CERT_DIR/privkey.pem"
log " Цепочка: $CERT_DIR/chain.pem"
log " Полная цепочка: $CERT_DIR/fullchain.pem"
log "=========================================="
fi
}
# ==============================================================================
# ОСНОВНАЯ ЛОГИКА
# ==============================================================================
main() {
log "=========================================="
log "Запуск скрипта управления SSL сертификатом"
log "=========================================="
# Проверка, что скрипт запущен от root
if [ "$EUID" -ne 0 ]; then
log "ОШИБКА: Скрипт должен быть запущен от имени root (sudo)"
exit 1
fi
# Проверка зависимостей
check_dependencies
# Настройка директории и файла учетных данных
setup_credentials_dir
create_credentials_file
# Установка плагина certbot-dns-regru
install_certbot_plugin
# Проверка существования сертификата
check_certificate_expiry
CERT_STATUS=$?
if [ $CERT_STATUS -eq 2 ]; then
# Сертификат не существует - создаем новый
obtain_certificate
if [ $? -eq 0 ]; then
display_certificate_info
reload_webserver
send_notification "Новый SSL сертификат успешно создан для $DOMAIN"
else
send_notification "ОШИБКА: Не удалось создать SSL сертификат для $DOMAIN"
exit 1
fi
elif [ $CERT_STATUS -eq 1 ]; then
# Сертификат скоро истекает - обновляем
renew_certificate
if [ $? -eq 0 ]; then
display_certificate_info
reload_webserver
send_notification "SSL сертификат успешно обновлен для $DOMAIN"
else
send_notification "ОШИБКА: Не удалось обновить SSL сертификат для $DOMAIN"
exit 1
fi
else
# Сертификат действителен - только проверяем обновление
log "Сертификат действителен. Выполняем проверку на наличие обновлений..."
renew_certificate
display_certificate_info
fi
log "=========================================="
log "Скрипт завершен успешно"
log "=========================================="
}
# Запуск основной функции
main
#!/bin/bash
###############################################################################
# Скрипт для создания и обновления SSL сертификата Let's Encrypt
# с использованием DNS-валидации через API reg.ru
#
# Автор: Фофанов Дмитрий
# Дата: 27.10.2025
# Описание: Автоматизация получения wildcard сертификата через Certbot
# с использованием DNS-01 challenge и API reg.ru
###############################################################################
# ==============================================================================
# КОНФИГУРАЦИЯ
# ==============================================================================
# Учетные данные API reg.ru (получить на https://www.reg.ru/user/account/)
REGRU_USERNAME="your_username" # Имя пользователя reg.ru
REGRU_PASSWORD="your_password" # Пароль от аккаунта reg.ru
# Параметры домена и сертификата
DOMAIN="example.com" # Основной домен
WILDCARD_DOMAIN="*.example.com" # Wildcard домен
EMAIL="admin@example.com" # Email для уведомлений Let's Encrypt
# Директории для хранения сертификатов
CERT_DIR="/etc/letsencrypt/live/$DOMAIN"
CREDENTIALS_DIR="/etc/letsencrypt/credentials"
CREDENTIALS_FILE="$CREDENTIALS_DIR/regru.ini"
# Логирование
LOG_FILE="/var/log/letsencrypt_regru.log"
TIMESTAMP=$(date '+%d.%m.%Y %H:%M:%S')
# ==============================================================================
# ФУНКЦИИ
# ==============================================================================
# Логирование сообщений
log() {
echo "[$TIMESTAMP] $1" | tee -a "$LOG_FILE"
}
# Проверка установки необходимых пакетов
check_dependencies() {
log "Проверка зависимостей..."
# Проверка certbot
if ! command -v certbot &> /dev/null; then
log "ОШИБКА: certbot не установлен. Установите: apt-get install certbot"
exit 1
fi
# Проверка curl
if ! command -v curl &> /dev/null; then
log "ОШИБКА: curl не установлен. Установите: apt-get install curl"
exit 1
fi
# Проверка jq для обработки JSON
if ! command -v jq &> /dev/null; then
log "ОШИБКА: jq не установлен. Установите: apt-get install jq"
exit 1
fi
log "Все зависимости установлены"
}
# Создание директории для credentials
setup_credentials_dir() {
log "Настройка директории для учетных данных..."
if [ ! -d "$CREDENTIALS_DIR" ]; then
mkdir -p "$CREDENTIALS_DIR"
chmod 700 "$CREDENTIALS_DIR"
fi
}
# Создание файла с учетными данными для certbot-dns-regru
create_credentials_file() {
log "Создание файла с учетными данными reg.ru..."
cat > "$CREDENTIALS_FILE" <<EOF
# Учетные данные API reg.ru для DNS-валидации
dns_regru_username = $REGRU_USERNAME
dns_regru_password = $REGRU_PASSWORD
EOF
chmod 600 "$CREDENTIALS_FILE"
log "Файл учетных данных создан: $CREDENTIALS_FILE"
}
# Установка плагина certbot-dns-regru (если еще не установлен)
install_certbot_plugin() {
log "Проверка плагина certbot-dns-regru..."
if ! pip3 list | grep -q certbot-dns-regru; then
log "Установка certbot-dns-regru..."
pip3 install certbot-dns-regru
if [ $? -eq 0 ]; then
log "Плагин certbot-dns-regru успешно установлен"
else
log "ОШИБКА: Не удалось установить certbot-dns-regru"
exit 1
fi
else
log "Плагин certbot-dns-regru уже установлен"
fi
}
# Получение нового сертификата
obtain_certificate() {
log "Запрос нового SSL сертификата для домена: $DOMAIN и $WILDCARD_DOMAIN"
certbot certonly \
--dns-regru \
--dns-regru-credentials "$CREDENTIALS_FILE" \
--dns-regru-propagation-seconds 60 \
-d "$DOMAIN" \
-d "$WILDCARD_DOMAIN" \
--email "$EMAIL" \
--agree-tos \
--non-interactive \
--preferred-challenges dns-01
if [ $? -eq 0 ]; then
log "Сертификат успешно получен!"
log "Путь к сертификатам: $CERT_DIR"
return 0
else
log "ОШИБКА: Не удалось получить сертификат"
return 1
fi
}
# Обновление существующего сертификата
renew_certificate() {
log "Проверка и обновление существующих сертификатов..."
certbot renew \
--dns-regru \
--dns-regru-credentials "$CREDENTIALS_FILE" \
--dns-regru-propagation-seconds 60 \
--non-interactive
if [ $? -eq 0 ]; then
log "Проверка обновления завершена успешно"
return 0
else
log "ОШИБКА: Проблема при обновлении сертификата"
return 1
fi
}
# Проверка срока действия сертификата
check_certificate_expiry() {
log "Проверка срока действия сертификата..."
if [ -f "$CERT_DIR/cert.pem" ]; then
EXPIRY_DATE=$(openssl x509 -enddate -noout -in "$CERT_DIR/cert.pem" | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $CURRENT_EPOCH) / 86400 ))
log "Сертификат истекает: $EXPIRY_DATE (осталось дней: $DAYS_LEFT)"
if [ $DAYS_LEFT -lt 30 ]; then
log "ВНИМАНИЕ: Сертификат истекает менее чем через 30 дней. Требуется обновление!"
return 1
else
log "Сертификат действителен"
return 0
fi
else
log "Сертификат не найден. Требуется создание нового сертификата."
return 2
fi
}
# Перезагрузка веб-сервера (Nginx/Apache)
reload_webserver() {
log "Перезагрузка веб-сервера..."
# Определяем, какой веб-сервер используется
if systemctl is-active --quiet nginx; then
systemctl reload nginx
log "Nginx перезагружен"
elif systemctl is-active --quiet apache2; then
systemctl reload apache2
log "Apache перезагружен"
elif systemctl is-active --quiet httpd; then
systemctl reload httpd
log "Apache (httpd) перезагружен"
else
log "ВНИМАНИЕ: Веб-сервер не найден или не активен. Пропускаем перезагрузку."
fi
}
# Отправка уведомления (опционально)
send_notification() {
local MESSAGE=$1
log "Уведомление: $MESSAGE"
# Здесь можно добавить отправку email, Telegram, Slack и т.д.
# Пример: echo "$MESSAGE" | mail -s "SSL Certificate Update" admin@example.com
}
# Вывод информации о сертификате
display_certificate_info() {
if [ -f "$CERT_DIR/cert.pem" ]; then
log "=========================================="
log "Информация о сертификате:"
log "=========================================="
openssl x509 -in "$CERT_DIR/cert.pem" -text -noout | grep -E "(Subject:|Issuer:|Not Before|Not After|DNS:)" | tee -a "$LOG_FILE"
log "=========================================="
log "Пути к файлам сертификата:"
log " Сертификат: $CERT_DIR/cert.pem"
log " Приватный ключ: $CERT_DIR/privkey.pem"
log " Цепочка: $CERT_DIR/chain.pem"
log " Полная цепочка: $CERT_DIR/fullchain.pem"
log "=========================================="
fi
}
# ==============================================================================
# ОСНОВНАЯ ЛОГИКА
# ==============================================================================
main() {
log "=========================================="
log "Запуск скрипта управления SSL сертификатом"
log "=========================================="
# Проверка, что скрипт запущен от root
if [ "$EUID" -ne 0 ]; then
log "ОШИБКА: Скрипт должен быть запущен от имени root (sudo)"
exit 1
fi
# Проверка зависимостей
check_dependencies
# Настройка директории и файла учетных данных
setup_credentials_dir
create_credentials_file
# Установка плагина certbot-dns-regru
install_certbot_plugin
# Проверка существования сертификата
check_certificate_expiry
CERT_STATUS=$?
if [ $CERT_STATUS -eq 2 ]; then
# Сертификат не существует - создаем новый
obtain_certificate
if [ $? -eq 0 ]; then
display_certificate_info
reload_webserver
send_notification "Новый SSL сертификат успешно создан для $DOMAIN"
else
send_notification "ОШИБКА: Не удалось создать SSL сертификат для $DOMAIN"
exit 1
fi
elif [ $CERT_STATUS -eq 1 ]; then
# Сертификат скоро истекает - обновляем
renew_certificate
if [ $? -eq 0 ]; then
display_certificate_info
reload_webserver
send_notification "SSL сертификат успешно обновлен для $DOMAIN"
else
send_notification "ОШИБКА: Не удалось обновить SSL сертификат для $DOMAIN"
exit 1
fi
else
# Сертификат действителен - только проверяем обновление
log "Сертификат действителен. Выполняем проверку на наличие обновлений..."
renew_certificate
display_certificate_info
fi
log "=========================================="
log "Скрипт завершен успешно"
log "=========================================="
}
# Запуск основной функции
main
+179 -179
View File
@@ -1,179 +1,179 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nginxproxymanager.com/
APP="Nginx Proxy Manager"
var_tags="${var_tags:-proxy}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /lib/systemd/system/npm.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if command -v node &> /dev/null; then
CURRENT_NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
if [[ "$CURRENT_NODE_VERSION" != "22" ]]; then
systemctl stop openresty
apt-get purge -y nodejs npm
apt-get autoremove -y
rm -rf /usr/local/bin/node /usr/local/bin/npm
rm -rf /usr/local/lib/node_modules
rm -rf ~/.npm
rm -rf /root/.npm
fi
fi
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
export NODE_OPTIONS="--openssl-legacy-provider"
RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
grep "tag_name" |
awk '{print substr($2, 3, length($2)-4) }')
msg_info "Downloading NPM v${RELEASE}"
curl -fsSL "https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE}" | tar -xz
cd nginx-proxy-manager-"${RELEASE}" || exit
msg_ok "Downloaded NPM v${RELEASE}"
msg_info "Building Frontend"
(
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json
cd ./frontend || exit
# Replace node-sass with sass in package.json before installation
sed -i 's/"node-sass".*$/"sass": "^1.92.1",/g' package.json
$STD yarn install --network-timeout 600000
$STD yarn build
)
msg_ok "Built Frontend"
msg_info "Stopping Services"
systemctl stop openresty
systemctl stop npm
msg_ok "Stopped Services"
msg_info "Cleaning Old Files"
rm -rf /app \
/var/www/html \
/etc/nginx \
/var/log/nginx \
/var/lib/nginx \
"$STD" /var/cache/nginx
msg_ok "Cleaned Old Files"
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /opt/certbot/bin/certbot /usr/local/bin/certbot
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r docker/rootfs/var/www/html/* /var/www/html/
cp -r docker/rootfs/etc/nginx/* /etc/nginx/
cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
$STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
fi
mkdir -p /app/global /app/frontend/images
cp -r frontend/dist/* /app/frontend
cp -r frontend/app-images/* /app/frontend/images
cp -r backend/* /app
cp -r global/* /app/global
# Update Certbot and plugins in virtual environment
if [ -d /opt/certbot ]; then
$STD /opt/certbot/bin/pip install --upgrade pip setuptools wheel
$STD /opt/certbot/bin/pip install --upgrade certbot certbot-dns-cloudflare
fi
msg_ok "Setup Environment"
msg_info "Initializing Backend"
$STD rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}
EOF
fi
cd /app || exit
export NODE_OPTIONS="--openssl-legacy-provider"
$STD yarn install --network-timeout 600000
msg_ok "Initialized Backend"
msg_info "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -i 's/su npm npm/su root root/g' /etc/logrotate.d/nginx-proxy-manager
sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
systemctl enable -q --now openresty
systemctl enable -q --now npm
msg_ok "Started Services"
msg_info "Cleaning up"
rm -rf ~/nginx-proxy-manager-*
msg_ok "Cleaned"
msg_ok "Updated Successfully"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:81${CL}"
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nginxproxymanager.com/
APP="Nginx Proxy Manager"
var_tags="${var_tags:-proxy}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /lib/systemd/system/npm.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if command -v node &> /dev/null; then
CURRENT_NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
if [[ "$CURRENT_NODE_VERSION" != "22" ]]; then
systemctl stop openresty
apt-get purge -y nodejs npm
apt-get autoremove -y
rm -rf /usr/local/bin/node /usr/local/bin/npm
rm -rf /usr/local/lib/node_modules
rm -rf ~/.npm
rm -rf /root/.npm
fi
fi
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
export NODE_OPTIONS="--openssl-legacy-provider"
RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
grep "tag_name" |
awk '{print substr($2, 3, length($2)-4) }')
msg_info "Downloading NPM v${RELEASE}"
curl -fsSL "https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE}" | tar -xz
cd nginx-proxy-manager-"${RELEASE}" || exit
msg_ok "Downloaded NPM v${RELEASE}"
msg_info "Building Frontend"
(
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json
sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json
cd ./frontend || exit
# Replace node-sass with sass in package.json before installation
sed -i 's/"node-sass".*$/"sass": "^1.92.1",/g' package.json
$STD yarn install --network-timeout 600000
$STD yarn build
)
msg_ok "Built Frontend"
msg_info "Stopping Services"
systemctl stop openresty
systemctl stop npm
msg_ok "Stopped Services"
msg_info "Cleaning Old Files"
rm -rf /app \
/var/www/html \
/etc/nginx \
/var/log/nginx \
/var/lib/nginx \
"$STD" /var/cache/nginx
msg_ok "Cleaned Old Files"
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /opt/certbot/bin/certbot /usr/local/bin/certbot
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r docker/rootfs/var/www/html/* /var/www/html/
cp -r docker/rootfs/etc/nginx/* /etc/nginx/
cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
$STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
fi
mkdir -p /app/global /app/frontend/images
cp -r frontend/dist/* /app/frontend
cp -r frontend/app-images/* /app/frontend/images
cp -r backend/* /app
cp -r global/* /app/global
# Update Certbot and plugins in virtual environment
if [ -d /opt/certbot ]; then
$STD /opt/certbot/bin/pip install --upgrade pip setuptools wheel
$STD /opt/certbot/bin/pip install --upgrade certbot certbot-dns-cloudflare
fi
msg_ok "Setup Environment"
msg_info "Initializing Backend"
$STD rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}
EOF
fi
cd /app || exit
export NODE_OPTIONS="--openssl-legacy-provider"
$STD yarn install --network-timeout 600000
msg_ok "Initialized Backend"
msg_info "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -i 's/su npm npm/su root root/g' /etc/logrotate.d/nginx-proxy-manager
sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
systemctl enable -q --now openresty
systemctl enable -q --now npm
msg_ok "Started Services"
msg_info "Cleaning up"
rm -rf ~/nginx-proxy-manager-*
msg_ok "Cleaned"
msg_ok "Updated Successfully"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:81${CL}"
+1
View File
@@ -0,0 +1 @@
<h1>Test</h1>
+13 -13
View File
@@ -1,13 +1,13 @@
# Зависимости для Let's Encrypt RegRu Manager
# HTTP запросы к API
requests>=2.25.0
# Работа с SSL сертификатами
cryptography>=3.4.0
# Let's Encrypt клиент
certbot>=1.12.0
# Опционально: для сборки исполняемых файлов
pyinstaller>=4.10
# Зависимости для Let's Encrypt RegRu Manager
# HTTP запросы к API
requests>=2.25.0
# Работа с SSL сертификатами
cryptography>=3.4.0
# Let's Encrypt клиент
certbot>=1.12.0
# Опционально: для сборки исполняемых файлов
pyinstaller>=4.10
+137 -137
View File
@@ -1,137 +1,137 @@
#!/usr/bin/env python3
import argparse
import json
import os
import re
import sys
import urllib.error
import urllib.request
from subprocess import PIPE, run
def get_env(name: str, default: str = "") -> str:
value = os.getenv(name, default)
return value.strip() if isinstance(value, str) else default
def fail(message: str, code: int = 1) -> None:
print(f"{message}")
sys.exit(code)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Dispatch Gitea Actions workflow")
parser.add_argument("--workflow", default="wiki-sync.yml", help="Workflow file name (e.g. wiki-sync.yml)")
parser.add_argument("--ref", default="master", help="Git ref for workflow dispatch")
parser.add_argument(
"--input",
action="append",
default=[],
help="Workflow input in key=value format. Can be provided multiple times.",
)
parser.add_argument(
"--require-input",
action="append",
default=[],
help="Required input key(s). Fails if key is missing or empty.",
)
return parser.parse_args()
def parse_inputs(items: list[str]) -> dict[str, str]:
result: dict[str, str] = {}
for item in items:
if "=" not in item:
fail(f"Неверный формат --input '{item}'. Используйте key=value")
key, value = item.split("=", 1)
key = key.strip()
value = value.strip()
if not key:
fail(f"Пустой ключ в --input '{item}'")
result[key] = value
return result
def get_repo_path() -> str:
result = run(["git", "config", "--get", "remote.origin.url"], stdout=PIPE, stderr=PIPE, text=True)
origin_url = (result.stdout or "").strip()
if result.returncode != 0 or not origin_url:
fail("remote.origin.url не найден. Проверьте, что команда запущена внутри git-репозитория.")
repo_path = re.sub(r"^(https?://[^/]+/|git@[^:]+:)", "", origin_url)
repo_path = re.sub(r"\.git$", "", repo_path)
if not repo_path:
fail(f"Не удалось вычислить owner/repo из remote.origin.url: {origin_url}")
return repo_path
def main() -> None:
args = parse_args()
token = get_env("DFGIT_TOKEN") or get_env("GIT_TOKEN")
if not token:
fail("не задан DFGIT_TOKEN (или GIT_TOKEN).")
dfgit_url = get_env("DFGIT_URL", "http://dfgit").rstrip("/")
workflow = args.workflow.strip() or "wiki-sync.yml"
ref = args.ref.strip() or "master"
inputs = parse_inputs(args.input)
for required_key in args.require_input:
required_key = required_key.strip()
if required_key and not inputs.get(required_key, "").strip():
fail(
f"Обязательный input '{required_key}' не задан. "
f"Передайте --input {required_key}=..."
)
repo_path = get_repo_path()
dispatch_url = f"{dfgit_url}/api/v1/repos/{repo_path}/actions/workflows/{workflow}/dispatches"
payload_data: dict[str, object] = {"ref": ref}
if inputs:
payload_data["inputs"] = inputs
payload = json.dumps(payload_data).encode("utf-8")
print(f"→ Репозиторий: {repo_path}")
print(f"→ Workflow: {workflow}, ref: {ref}")
if inputs:
print(f"→ Inputs: {json.dumps(inputs, ensure_ascii=False)}")
print(f"→ Запрос: {dispatch_url}")
request = urllib.request.Request(
dispatch_url,
data=payload,
method="POST",
headers={
"Authorization": f"token {token}",
"Content-Type": "application/json",
"Accept": "application/json",
},
)
try:
with urllib.request.urlopen(request, timeout=30) as response:
status = response.getcode()
body = response.read().decode("utf-8", errors="replace").strip()
except urllib.error.HTTPError as error:
status = error.code
body = error.read().decode("utf-8", errors="replace").strip()
except urllib.error.URLError as error:
fail(f"Ошибка сети при обращении к dfgit: {error}")
if status in (200, 201, 204):
print("✓ Workflow успешно запущен")
print("Проверьте статус в Actions на сервере dfgit.")
return
print(f"✗ Ошибка запуска workflow (HTTP {status})")
if body:
print("Ответ API:")
print(body)
sys.exit(1)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
import argparse
import json
import os
import re
import sys
import urllib.error
import urllib.request
from subprocess import PIPE, run
def get_env(name: str, default: str = "") -> str:
value = os.getenv(name, default)
return value.strip() if isinstance(value, str) else default
def fail(message: str, code: int = 1) -> None:
print(f"{message}")
sys.exit(code)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Dispatch Gitea Actions workflow")
parser.add_argument("--workflow", default="wiki-sync.yml", help="Workflow file name (e.g. wiki-sync.yml)")
parser.add_argument("--ref", default="master", help="Git ref for workflow dispatch")
parser.add_argument(
"--input",
action="append",
default=[],
help="Workflow input in key=value format. Can be provided multiple times.",
)
parser.add_argument(
"--require-input",
action="append",
default=[],
help="Required input key(s). Fails if key is missing or empty.",
)
return parser.parse_args()
def parse_inputs(items: list[str]) -> dict[str, str]:
result: dict[str, str] = {}
for item in items:
if "=" not in item:
fail(f"Неверный формат --input '{item}'. Используйте key=value")
key, value = item.split("=", 1)
key = key.strip()
value = value.strip()
if not key:
fail(f"Пустой ключ в --input '{item}'")
result[key] = value
return result
def get_repo_path() -> str:
result = run(["git", "config", "--get", "remote.origin.url"], stdout=PIPE, stderr=PIPE, text=True)
origin_url = (result.stdout or "").strip()
if result.returncode != 0 or not origin_url:
fail("remote.origin.url не найден. Проверьте, что команда запущена внутри git-репозитория.")
repo_path = re.sub(r"^(https?://[^/]+/|git@[^:]+:)", "", origin_url)
repo_path = re.sub(r"\.git$", "", repo_path)
if not repo_path:
fail(f"Не удалось вычислить owner/repo из remote.origin.url: {origin_url}")
return repo_path
def main() -> None:
args = parse_args()
token = get_env("DFGIT_TOKEN") or get_env("GIT_TOKEN")
if not token:
fail("не задан DFGIT_TOKEN (или GIT_TOKEN).")
dfgit_url = get_env("DFGIT_URL", "http://dfgit").rstrip("/")
workflow = args.workflow.strip() or "wiki-sync.yml"
ref = args.ref.strip() or "master"
inputs = parse_inputs(args.input)
for required_key in args.require_input:
required_key = required_key.strip()
if required_key and not inputs.get(required_key, "").strip():
fail(
f"Обязательный input '{required_key}' не задан. "
f"Передайте --input {required_key}=..."
)
repo_path = get_repo_path()
dispatch_url = f"{dfgit_url}/api/v1/repos/{repo_path}/actions/workflows/{workflow}/dispatches"
payload_data: dict[str, object] = {"ref": ref}
if inputs:
payload_data["inputs"] = inputs
payload = json.dumps(payload_data).encode("utf-8")
print(f"→ Репозиторий: {repo_path}")
print(f"→ Workflow: {workflow}, ref: {ref}")
if inputs:
print(f"→ Inputs: {json.dumps(inputs, ensure_ascii=False)}")
print(f"→ Запрос: {dispatch_url}")
request = urllib.request.Request(
dispatch_url,
data=payload,
method="POST",
headers={
"Authorization": f"token {token}",
"Content-Type": "application/json",
"Accept": "application/json",
},
)
try:
with urllib.request.urlopen(request, timeout=30) as response:
status = response.getcode()
body = response.read().decode("utf-8", errors="replace").strip()
except urllib.error.HTTPError as error:
status = error.code
body = error.read().decode("utf-8", errors="replace").strip()
except urllib.error.URLError as error:
fail(f"Ошибка сети при обращении к dfgit: {error}")
if status in (200, 201, 204):
print("✓ Workflow успешно запущен")
print("Проверьте статус в Actions на сервере dfgit.")
return
print(f"✗ Ошибка запуска workflow (HTTP {status})")
if body:
print("Ответ API:")
print(body)
sys.exit(1)
if __name__ == "__main__":
main()
+16 -16
View File
@@ -1,16 +1,16 @@
[Unit]
Description=Let's Encrypt Certificate Manager for reg.ru
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
WorkingDirectory=/opt/letsencrypt-regru
ExecStart=/opt/letsencrypt-regru/venv/bin/python /opt/letsencrypt-regru/letsencrypt_regru_api.py --config /etc/letsencrypt-regru/config.json --auto
StandardOutput=journal
StandardError=journal
SyslogIdentifier=letsencrypt-regru
[Install]
WantedBy=multi-user.target
[Unit]
Description=Let's Encrypt Certificate Manager for reg.ru
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
WorkingDirectory=/opt/letsencrypt-regru
ExecStart=/opt/letsencrypt-regru/venv/bin/python /opt/letsencrypt-regru/letsencrypt_regru_api.py --config /etc/letsencrypt-regru/config.json --auto
StandardOutput=journal
StandardError=journal
SyslogIdentifier=letsencrypt-regru
[Install]
WantedBy=multi-user.target
+19 -19
View File
@@ -1,19 +1,19 @@
[Unit]
Description=Let's Encrypt Certificate Auto-Renewal Timer
Requires=letsencrypt-regru.service
[Timer]
# Запустить через 15 минут после загрузки системы
OnBootSec=15min
# Запускать каждые 12 часов
OnUnitActiveSec=12h
# Добавить случайную задержку до 1 часа
RandomizedDelaySec=1h
# Сохранять информацию о последнем запуске
Persistent=true
[Install]
WantedBy=timers.target
[Unit]
Description=Let's Encrypt Certificate Auto-Renewal Timer
Requires=letsencrypt-regru.service
[Timer]
# Запустить через 15 минут после загрузки системы
OnBootSec=15min
# Запускать каждые 12 часов
OnUnitActiveSec=12h
# Добавить случайную задержку до 1 часа
RandomizedDelaySec=1h
# Сохранять информацию о последнем запуске
Persistent=true
[Install]
WantedBy=timers.target
+143 -143
View File
@@ -1,143 +1,143 @@
#!/bin/bash
# ==============================================================================
# Скрипт для быстрого создания тестового самоподписанного SSL сертификата
# Использует: openssl (альтернатива Python скрипту)
# ==============================================================================
set -e
# Цвета
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Параметры по умолчанию
DOMAIN="${1:-example.com}"
WILDCARD="${2:-yes}"
CERT_DIR="/etc/letsencrypt/live/${DOMAIN}"
VALIDITY_DAYS=90
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Создание тестового самоподписанного SSL сертификата ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}Параметры:${NC}"
echo -e " Домен: ${GREEN}${DOMAIN}${NC}"
echo -e " Wildcard: ${GREEN}${WILDCARD}${NC}"
echo -e " Срок действия: ${GREEN}${VALIDITY_DAYS} дней${NC}"
echo -e " Директория: ${GREEN}${CERT_DIR}${NC}"
echo ""
echo -e "${YELLOW}⚠️ ВНИМАНИЕ: Это тестовый сертификат для разработки!${NC}"
echo -e "${YELLOW} Браузеры будут показывать предупреждение безопасности.${NC}"
echo ""
# Проверка прав root
if [ "$(id -u)" != "0" ]; then
echo -e "${RED}✗ Требуются права root${NC}"
echo -e "Запустите: sudo $0 $@"
exit 1
fi
# Создание директории
echo -e "${YELLOW}→ Создание директории...${NC}"
mkdir -p "${CERT_DIR}"
cd "${CERT_DIR}"
# Подготовка конфигурации для альтернативных имен (SAN)
if [ "${WILDCARD}" = "yes" ]; then
SAN="DNS:${DOMAIN},DNS:*.${DOMAIN}"
else
SAN="DNS:${DOMAIN}"
fi
# Создание конфигурации OpenSSL
cat > openssl.cnf <<EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req
[dn]
C=RU
ST=Moscow
L=Moscow
O=Test Certificate
CN=${DOMAIN}
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = ${SAN}
EOF
# Генерация приватного ключа
echo -e "${YELLOW}→ Генерация приватного ключа RSA 2048 бит...${NC}"
openssl genrsa -out privkey.pem 2048 2>/dev/null
chmod 600 privkey.pem
echo -e "${GREEN}✓ Приватный ключ сохранен: ${CERT_DIR}/privkey.pem${NC}"
# Генерация сертификата
echo -e "${YELLOW}→ Генерация самоподписанного сертификата...${NC}"
openssl req \
-new \
-x509 \
-key privkey.pem \
-out cert.pem \
-days ${VALIDITY_DAYS} \
-config openssl.cnf \
-extensions v3_req \
2>/dev/null
echo -e "${GREEN}✓ Сертификат сохранен: ${CERT_DIR}/cert.pem${NC}"
# Создание fullchain (копия cert для самоподписанного)
cp cert.pem fullchain.pem
echo -e "${GREEN}✓ Fullchain сохранен: ${CERT_DIR}/fullchain.pem${NC}"
# Создание пустого chain.pem
touch chain.pem
echo -e "${GREEN}✓ Chain файл создан: ${CERT_DIR}/chain.pem${NC}"
# Удаление временного файла конфигурации
rm -f openssl.cnf
echo ""
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Информация о сертификате ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
# Вывод информации о сертификате
openssl x509 -in cert.pem -noout -subject -dates -ext subjectAltName
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ ✓ Тестовый сертификат успешно создан ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}📁 Файлы сертификата:${NC}"
echo -e " • Приватный ключ: ${CERT_DIR}/privkey.pem"
echo -e " • Сертификат: ${CERT_DIR}/cert.pem"
echo -e " • Fullchain: ${CERT_DIR}/fullchain.pem"
echo -e " • Chain: ${CERT_DIR}/chain.pem"
echo ""
echo -e "${YELLOW}⚠️ ВНИМАНИЕ:${NC}"
echo -e " Это самоподписанный тестовый сертификат!"
echo -e " Браузеры будут показывать предупреждение о безопасности."
echo -e " Используйте ТОЛЬКО для тестирования и разработки!"
echo ""
echo -e "${YELLOW}Использование в Nginx:${NC}"
echo -e " ssl_certificate ${CERT_DIR}/fullchain.pem;"
echo -e " ssl_certificate_key ${CERT_DIR}/privkey.pem;"
echo ""
# Предложение загрузить в NPM
echo -e "${YELLOW}Загрузить в Nginx Proxy Manager?${NC}"
echo -e " Используйте Python скрипт с опцией --test-cert"
echo -e " или загрузите вручную через веб-интерфейс NPM"
echo ""
#!/bin/bash
# ==============================================================================
# Скрипт для быстрого создания тестового самоподписанного SSL сертификата
# Использует: openssl (альтернатива Python скрипту)
# ==============================================================================
set -e
# Цвета
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Параметры по умолчанию
DOMAIN="${1:-example.com}"
WILDCARD="${2:-yes}"
CERT_DIR="/etc/letsencrypt/live/${DOMAIN}"
VALIDITY_DAYS=90
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Создание тестового самоподписанного SSL сертификата ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}Параметры:${NC}"
echo -e " Домен: ${GREEN}${DOMAIN}${NC}"
echo -e " Wildcard: ${GREEN}${WILDCARD}${NC}"
echo -e " Срок действия: ${GREEN}${VALIDITY_DAYS} дней${NC}"
echo -e " Директория: ${GREEN}${CERT_DIR}${NC}"
echo ""
echo -e "${YELLOW}⚠️ ВНИМАНИЕ: Это тестовый сертификат для разработки!${NC}"
echo -e "${YELLOW} Браузеры будут показывать предупреждение безопасности.${NC}"
echo ""
# Проверка прав root
if [ "$(id -u)" != "0" ]; then
echo -e "${RED}✗ Требуются права root${NC}"
echo -e "Запустите: sudo $0 $@"
exit 1
fi
# Создание директории
echo -e "${YELLOW}→ Создание директории...${NC}"
mkdir -p "${CERT_DIR}"
cd "${CERT_DIR}"
# Подготовка конфигурации для альтернативных имен (SAN)
if [ "${WILDCARD}" = "yes" ]; then
SAN="DNS:${DOMAIN},DNS:*.${DOMAIN}"
else
SAN="DNS:${DOMAIN}"
fi
# Создание конфигурации OpenSSL
cat > openssl.cnf <<EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req
[dn]
C=RU
ST=Moscow
L=Moscow
O=Test Certificate
CN=${DOMAIN}
[v3_req]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = ${SAN}
EOF
# Генерация приватного ключа
echo -e "${YELLOW}→ Генерация приватного ключа RSA 2048 бит...${NC}"
openssl genrsa -out privkey.pem 2048 2>/dev/null
chmod 600 privkey.pem
echo -e "${GREEN}✓ Приватный ключ сохранен: ${CERT_DIR}/privkey.pem${NC}"
# Генерация сертификата
echo -e "${YELLOW}→ Генерация самоподписанного сертификата...${NC}"
openssl req \
-new \
-x509 \
-key privkey.pem \
-out cert.pem \
-days ${VALIDITY_DAYS} \
-config openssl.cnf \
-extensions v3_req \
2>/dev/null
echo -e "${GREEN}✓ Сертификат сохранен: ${CERT_DIR}/cert.pem${NC}"
# Создание fullchain (копия cert для самоподписанного)
cp cert.pem fullchain.pem
echo -e "${GREEN}✓ Fullchain сохранен: ${CERT_DIR}/fullchain.pem${NC}"
# Создание пустого chain.pem
touch chain.pem
echo -e "${GREEN}✓ Chain файл создан: ${CERT_DIR}/chain.pem${NC}"
# Удаление временного файла конфигурации
rm -f openssl.cnf
echo ""
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Информация о сертификате ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
# Вывод информации о сертификате
openssl x509 -in cert.pem -noout -subject -dates -ext subjectAltName
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ ✓ Тестовый сертификат успешно создан ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}📁 Файлы сертификата:${NC}"
echo -e " • Приватный ключ: ${CERT_DIR}/privkey.pem"
echo -e " • Сертификат: ${CERT_DIR}/cert.pem"
echo -e " • Fullchain: ${CERT_DIR}/fullchain.pem"
echo -e " • Chain: ${CERT_DIR}/chain.pem"
echo ""
echo -e "${YELLOW}⚠️ ВНИМАНИЕ:${NC}"
echo -e " Это самоподписанный тестовый сертификат!"
echo -e " Браузеры будут показывать предупреждение о безопасности."
echo -e " Используйте ТОЛЬКО для тестирования и разработки!"
echo ""
echo -e "${YELLOW}Использование в Nginx:${NC}"
echo -e " ssl_certificate ${CERT_DIR}/fullchain.pem;"
echo -e " ssl_certificate_key ${CERT_DIR}/privkey.pem;"
echo ""
# Предложение загрузить в NPM
echo -e "${YELLOW}Загрузить в Nginx Proxy Manager?${NC}"
echo -e " Используйте Python скрипт с опцией --test-cert"
echo -e " или загрузите вручную через веб-интерфейс NPM"
echo ""
+797 -797
View File
File diff suppressed because it is too large Load Diff
+178 -178
View File
@@ -1,178 +1,178 @@
# Changelog
Краткое резюме по основным версиям (подробности — ниже на этой странице).
## 2.1.0 (20251027)
- Добавлена генерация тестовых самоподписанных сертификатов (`--test-cert`, `make test-cert`, `test_certificate.sh`)
- Расширена документация (testing guide, cheatsheet, project structure)
## 2.0.0 (20251027)
- Интеграция с Nginx Proxy Manager (API)
- Makefile, systemd timer/service, авто-режим
## 1.0.0 (20251026)
- Первый релиз: LE+reg.ru DNS-01, bash/ps1 версии
---
## Appendix (migrated from docs/CHANGELOG.md)
<!-- MIGRATED_FROM_DOCS:CHANGELOG.md -->
## 📋 Журнал изменений (Changelog)
### [2.1.0] - 2025-10-27
#### 🆕 Добавлено
##### Генерация тестовых SSL сертификатов
-**Новый класс `TestCertificateGenerator`** - генерация самоподписанных сертификатов
-**Команда `--test-cert`** в Python скрипте для создания тестовых сертификатов
-**Скрипт `test_certificate.sh`** - автономное создание через OpenSSL
-**Команда `make test-cert`** в Makefile для быстрого тестирования
##### Документация
- 📘 **TESTING_GUIDE.md** (370+ строк) - полное руководство по тестированию
- Обход лимитов Let's Encrypt (5 сертификатов в неделю)
- Сравнение методов создания сертификатов
- Примеры для CI/CD и Docker
- Переход с тестовых на production
- Частые вопросы и решения
- 📘 **PROJECT_STRUCTURE.md** - структура проекта
- Описание всех файлов
- Список возможностей
- Технологии
- 📘 **CHEATSHEET.md** - быстрая шпаргалка
- Основные команды
- Сценарии использования
- Частые ошибки и решения
- Workflow разработки
##### Функциональность
- ✨ Поддержка **неограниченного количества** тестовых сертификатов
-**Мгновенное создание** (1-2 секунды) без DNS валидации
-**Автоматическая загрузка** тестовых сертификатов в NPM
-**Полная совместимость** структуры с Let's Encrypt
-**Wildcard поддержка** для тестовых сертификатов
#### 🔧 Улучшено
##### Python скрипт
- Добавлен импорт библиотеки `cryptography` с проверкой установки
- Новые параметры командной строки:
- `--test-cert` - создание тестового сертификата
- `--auto` - явное указание автоматического режима
- Улучшенная обработка тестовых сертификатов в NPM
- Детальное логирование процесса генерации
##### Makefile
- Добавлена команда `make test-cert` с красивым выводом
- Информационные сообщения о преимуществах тестовых сертификатов
- Предупреждения о безопасности
##### README.md
- Раздел "Создание тестового самоподписанного сертификата"
- Обновленное содержание с ссылкой на тестовые сертификаты
- Примеры использования тестовых сертификатов
- Интеграция с NPM для тестовых сертификатов
- Ссылки на дополнительную документацию
#### 🎯 Преимущества
##### Для разработчиков
-**Нет лимитов** - неограниченное количество сертификатов
-**Быстро** - создание за 1-2 секунды
-**Офлайн** - работает без интернета
-**Идентичная структура** - те же файлы что и Let's Encrypt
##### Для тестирования
-**CI/CD friendly** - быстрое создание в pipeline
-**Docker ready** - легко встраивается в контейнеры
-**Staging окружения** - идеально для тестовых серверов
-**Локальная разработка** - HTTPS на localhost
#### 📊 Статистика
- **Строк кода**: 1,411 (Python скрипт)
- **Строк в Makefile**: 415
- **Строк документации**: 2,200+
- **Команд в Makefile**: 13
- **Режимов работы**: 4 (obtain, renew, auto, test-cert)
---
### [2.0.0] - 2025-10-27
#### 🆕 Добавлено
- ✨ Интеграция с Nginx Proxy Manager (NPM)
- ✨ Класс `NginxProxyManagerAPI` для управления сертификатами через API
- ✨ Автоматическая загрузка сертификатов в NPM
- ✨ Автоматическое обновление сертификатов в NPM
- ✨ Автоматическая проверка срока действия
- ✨ Настраиваемый порог обновления (`renewal_days`)
- ✨ Makefile для автоматизации установки/удаления
- ✨ Systemd service + timer
- ✨ Cron автоматизация
#### 🔧 Улучшено
- Консолидация документации в единый README.md
- Подробное логирование с статусами операций
- Валидация конфигурации
- Улучшенная обработка ошибок
#### 📘 Документация
- Полное руководство по NPM интеграции
- Быстрый старт за 3 команды
- Примеры автоматизации
---
### [1.0.0] - 2025-10-26
#### 🆕 Первый релиз
- Python скрипт для Let's Encrypt через reg.ru API
- Bash скрипт с certbot-dns-regru
- PowerShell версия для Windows
- DNS-01 валидация
- Wildcard сертификаты
- Базовая документация
---
### Roadmap (Планы)
#### [2.2.0] - Планируется
- [ ] Веб-интерфейс для управления
- [ ] Поддержка множественных доменов
- [ ] Notifications (email, telegram)
- [ ] Grafana dashboard для мониторинга
- [ ] Backup сертификатов
#### [3.0.0] - Будущее
- [ ] Поддержка других DNS провайдеров
- [ ] Cloudflare API
- [ ] Route53 (AWS)
- [ ] Google Cloud DNS
---
### Типы изменений
- `🆕 Добавлено` - новый функционал
- `🔧 Улучшено` - улучшения существующего функционала
- `🐛 Исправлено` - исправление багов
- `🗑️ Удалено` - удаленный функционал
- `🔒 Безопасность` - изменения безопасности
- `📘 Документация` - изменения в документации
---
**Версионирование**: Semantic Versioning (MAJOR.MINOR.PATCH)
- **MAJOR**: Несовместимые изменения API
- **MINOR**: Новый функционал с обратной совместимостью
- **PATCH**: Исправления багов
# Changelog
Краткое резюме по основным версиям (подробности — ниже на этой странице).
## 2.1.0 (20251027)
- Добавлена генерация тестовых самоподписанных сертификатов (`--test-cert`, `make test-cert`, `test_certificate.sh`)
- Расширена документация (testing guide, cheatsheet, project structure)
## 2.0.0 (20251027)
- Интеграция с Nginx Proxy Manager (API)
- Makefile, systemd timer/service, авто-режим
## 1.0.0 (20251026)
- Первый релиз: LE+reg.ru DNS-01, bash/ps1 версии
---
## Appendix (migrated from docs/CHANGELOG.md)
<!-- MIGRATED_FROM_DOCS:CHANGELOG.md -->
## 📋 Журнал изменений (Changelog)
### [2.1.0] - 2025-10-27
#### 🆕 Добавлено
##### Генерация тестовых SSL сертификатов
-**Новый класс `TestCertificateGenerator`** - генерация самоподписанных сертификатов
-**Команда `--test-cert`** в Python скрипте для создания тестовых сертификатов
-**Скрипт `test_certificate.sh`** - автономное создание через OpenSSL
-**Команда `make test-cert`** в Makefile для быстрого тестирования
##### Документация
- 📘 **TESTING_GUIDE.md** (370+ строк) - полное руководство по тестированию
- Обход лимитов Let's Encrypt (5 сертификатов в неделю)
- Сравнение методов создания сертификатов
- Примеры для CI/CD и Docker
- Переход с тестовых на production
- Частые вопросы и решения
- 📘 **PROJECT_STRUCTURE.md** - структура проекта
- Описание всех файлов
- Список возможностей
- Технологии
- 📘 **CHEATSHEET.md** - быстрая шпаргалка
- Основные команды
- Сценарии использования
- Частые ошибки и решения
- Workflow разработки
##### Функциональность
- ✨ Поддержка **неограниченного количества** тестовых сертификатов
-**Мгновенное создание** (1-2 секунды) без DNS валидации
-**Автоматическая загрузка** тестовых сертификатов в NPM
-**Полная совместимость** структуры с Let's Encrypt
-**Wildcard поддержка** для тестовых сертификатов
#### 🔧 Улучшено
##### Python скрипт
- Добавлен импорт библиотеки `cryptography` с проверкой установки
- Новые параметры командной строки:
- `--test-cert` - создание тестового сертификата
- `--auto` - явное указание автоматического режима
- Улучшенная обработка тестовых сертификатов в NPM
- Детальное логирование процесса генерации
##### Makefile
- Добавлена команда `make test-cert` с красивым выводом
- Информационные сообщения о преимуществах тестовых сертификатов
- Предупреждения о безопасности
##### README.md
- Раздел "Создание тестового самоподписанного сертификата"
- Обновленное содержание с ссылкой на тестовые сертификаты
- Примеры использования тестовых сертификатов
- Интеграция с NPM для тестовых сертификатов
- Ссылки на дополнительную документацию
#### 🎯 Преимущества
##### Для разработчиков
-**Нет лимитов** - неограниченное количество сертификатов
-**Быстро** - создание за 1-2 секунды
-**Офлайн** - работает без интернета
-**Идентичная структура** - те же файлы что и Let's Encrypt
##### Для тестирования
-**CI/CD friendly** - быстрое создание в pipeline
-**Docker ready** - легко встраивается в контейнеры
-**Staging окружения** - идеально для тестовых серверов
-**Локальная разработка** - HTTPS на localhost
#### 📊 Статистика
- **Строк кода**: 1,411 (Python скрипт)
- **Строк в Makefile**: 415
- **Строк документации**: 2,200+
- **Команд в Makefile**: 13
- **Режимов работы**: 4 (obtain, renew, auto, test-cert)
---
### [2.0.0] - 2025-10-27
#### 🆕 Добавлено
- ✨ Интеграция с Nginx Proxy Manager (NPM)
- ✨ Класс `NginxProxyManagerAPI` для управления сертификатами через API
- ✨ Автоматическая загрузка сертификатов в NPM
- ✨ Автоматическое обновление сертификатов в NPM
- ✨ Автоматическая проверка срока действия
- ✨ Настраиваемый порог обновления (`renewal_days`)
- ✨ Makefile для автоматизации установки/удаления
- ✨ Systemd service + timer
- ✨ Cron автоматизация
#### 🔧 Улучшено
- Консолидация документации в единый README.md
- Подробное логирование с статусами операций
- Валидация конфигурации
- Улучшенная обработка ошибок
#### 📘 Документация
- Полное руководство по NPM интеграции
- Быстрый старт за 3 команды
- Примеры автоматизации
---
### [1.0.0] - 2025-10-26
#### 🆕 Первый релиз
- Python скрипт для Let's Encrypt через reg.ru API
- Bash скрипт с certbot-dns-regru
- PowerShell версия для Windows
- DNS-01 валидация
- Wildcard сертификаты
- Базовая документация
---
### Roadmap (Планы)
#### [2.2.0] - Планируется
- [ ] Веб-интерфейс для управления
- [ ] Поддержка множественных доменов
- [ ] Notifications (email, telegram)
- [ ] Grafana dashboard для мониторинга
- [ ] Backup сертификатов
#### [3.0.0] - Будущее
- [ ] Поддержка других DNS провайдеров
- [ ] Cloudflare API
- [ ] Route53 (AWS)
- [ ] Google Cloud DNS
---
### Типы изменений
- `🆕 Добавлено` - новый функционал
- `🔧 Улучшено` - улучшения существующего функционала
- `🐛 Исправлено` - исправление багов
- `🗑️ Удалено` - удаленный функционал
- `🔒 Безопасность` - изменения безопасности
- `📘 Документация` - изменения в документации
---
**Версионирование**: Semantic Versioning (MAJOR.MINOR.PATCH)
- **MAJOR**: Несовместимые изменения API
- **MINOR**: Новый функционал с обратной совместимостью
- **PATCH**: Исправления багов
+547 -547
View File
File diff suppressed because it is too large Load Diff
+92 -92
View File
@@ -1,92 +1,92 @@
# Конфигурация
Проект использует JSON конфиг (пример: `config.json.example`).
## Важно про мультидоменный режим
Скрипт поддерживает:
- один домен в поле `domain`
- список доменов в поле `domains` (массив строк)
- оба поля одновременно (будет объединение без дублей)
Пример:
```json
{
"regru_username": "your_username",
"regru_password": "your_password",
"domain": "example.com",
"domains": [
"example.com",
"pages.gitea.example.com"
],
"wildcard": true,
"email": "admin@example.com",
"cert_dir": "/etc/letsencrypt/live",
"log_file": "/var/log/letsencrypt_regru.log",
"dns_propagation_wait": 180,
"dns_check_attempts": 20,
"dns_check_interval": 15,
"renewal_days": 30,
"npm_enabled": true,
"npm_host": "http://192.0.2.1:81",
"npm_email": "admin@example.com",
"npm_password": "changeme"
}
```
## Параметры конфигурации
### reg.ru API
- `regru_username`, `regru_password`
- учётные данные для API reg.ru
- IP должен быть разрешён в настройках API (см. [RegRu_API_Troubleshooting](RegRu_API_Troubleshooting.md))
### Домены
- `domain`: основной домен (строка)
- `domains`: массив доменов
- `wildcard`: если `true`, скрипт будет запрашивать `-d <domain>` и `-d *.<domain>`
- обратите внимание: этот флаг сейчас общий для всех доменов из массива
### Lets Encrypt
- `email`: email для регистрации в Lets Encrypt
- `renewal_days`: порог автопродления (например, 30)
### DNS ожидание/проверки
- `dns_propagation_wait`: сколько секунд ждать после добавления TXT
- `dns_check_attempts`: сколько попыток проверки через `nslookup`
- `dns_check_interval`: интервал между попытками
### Пути
- `cert_dir`: базовая папка сертификатов (обычно `/etc/letsencrypt/live`)
- `log_file`: файл логов
### Nginx Proxy Manager (опционально)
- `npm_enabled`: включить синхронизацию сертификатов в NPM
- `npm_host`: URL NPM (пример: `http://10.10.10.14:81`)
- `npm_email`, `npm_password`: учётные данные
Подробности: [Nginx_Proxy_Manager](Nginx_Proxy_Manager.md).
## Проверка конфига
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
- `letsencrypt-regru --check -v`
## Где хранить конфиг
- храните конфиг с правами `600`
- владелец: root
Пример:
- `sudo chmod 600 /etc/letsencrypt/regru_config.json`
- `sudo chown root:root /etc/letsencrypt/regru_config.json`
# Конфигурация
Проект использует JSON конфиг (пример: `config.json.example`).
## Важно про мультидоменный режим
Скрипт поддерживает:
- один домен в поле `domain`
- список доменов в поле `domains` (массив строк)
- оба поля одновременно (будет объединение без дублей)
Пример:
```json
{
"regru_username": "your_username",
"regru_password": "your_password",
"domain": "example.com",
"domains": [
"example.com",
"pages.gitea.example.com"
],
"wildcard": true,
"email": "admin@example.com",
"cert_dir": "/etc/letsencrypt/live",
"log_file": "/var/log/letsencrypt_regru.log",
"dns_propagation_wait": 180,
"dns_check_attempts": 20,
"dns_check_interval": 15,
"renewal_days": 30,
"npm_enabled": true,
"npm_host": "http://192.0.2.1:81",
"npm_email": "admin@example.com",
"npm_password": "changeme"
}
```
## Параметры конфигурации
### reg.ru API
- `regru_username`, `regru_password`
- учётные данные для API reg.ru
- IP должен быть разрешён в настройках API (см. [RegRu_API_Troubleshooting](RegRu_API_Troubleshooting.md))
### Домены
- `domain`: основной домен (строка)
- `domains`: массив доменов
- `wildcard`: если `true`, скрипт будет запрашивать `-d <domain>` и `-d *.<domain>`
- обратите внимание: этот флаг сейчас общий для всех доменов из массива
### Lets Encrypt
- `email`: email для регистрации в Lets Encrypt
- `renewal_days`: порог автопродления (например, 30)
### DNS ожидание/проверки
- `dns_propagation_wait`: сколько секунд ждать после добавления TXT
- `dns_check_attempts`: сколько попыток проверки через `nslookup`
- `dns_check_interval`: интервал между попытками
### Пути
- `cert_dir`: базовая папка сертификатов (обычно `/etc/letsencrypt/live`)
- `log_file`: файл логов
### Nginx Proxy Manager (опционально)
- `npm_enabled`: включить синхронизацию сертификатов в NPM
- `npm_host`: URL NPM (пример: `http://10.10.10.14:81`)
- `npm_email`, `npm_password`: учётные данные
Подробности: [Nginx_Proxy_Manager](Nginx_Proxy_Manager.md).
## Проверка конфига
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
- `letsencrypt-regru --check -v`
## Где хранить конфиг
- храните конфиг с правами `600`
- владелец: root
Пример:
- `sudo chmod 600 /etc/letsencrypt/regru_config.json`
- `sudo chown root:root /etc/letsencrypt/regru_config.json`
+124 -124
View File
@@ -1,124 +1,124 @@
# Deploy через Actions и Secrets
Эта страница описывает деплой через workflow `.github/workflows/deploy-service.yml`.
## Триггеры (когда запускается)
1) Автоматически по push
- ветка: `master`
- только если изменились файлы:
- `letsencrypt_regru_api.py`, `letsencrypt_regru*.sh`, `letsencrypt_regru.ps1`
- `requirements.txt`
- `systemd/**`
- `.github/workflows/deploy-service.yml`
2) Вручную (workflow_dispatch)
- из UI Actions
- или через Makefile командой `make deploy-service` (Makefile делает API dispatch)
## Что делает workflow
- деплоит проект на сервер `192.0.2.1` по SSH (ключ)
- перед деплоем генерирует `config.json` из secrets
- копирует архив на сервер, распаковывает в `DEPLOY_PATH`
- перезапускает systemd сервис `DEPLOY_SERVICE`
## Обязательные secrets
### Доступ к репозиторию
- `GIT_TOKEN` (или `GITEA_TOKEN`)
### SSH и деплой
- `DEPLOY_HOST` — должен быть `192.0.2.1`
- `DEPLOY_PORT` — обычно `22`
- `DEPLOY_USER`
- `DEPLOY_SSH_PRIVATE_KEY`
- `DEPLOY_PATH`
- `DEPLOY_SERVICE`
### Генерация config.json
- `CFG_REGRU_USERNAME`
- `CFG_REGRU_PASSWORD`
- `CFG_EMAIL`
- `CFG_DOMAINS`
`CFG_DOMAINS` поддерживает два формата:
1) JSON массив:
```json
["example.com", "pages.gitea.example.com"]
```
2) строка через запятую:
```text
example.com,pages.gitea.example.com
```
Если `CFG_DOMAIN` не указан, в поле `domain` берётся первый домен из `CFG_DOMAINS`.
## Опциональные secrets
- `DEPLOY_SSH_KNOWN_HOSTS`
- `CFG_DOMAIN`
- `CFG_WILDCARD`
- `CFG_CERT_DIR`
- `CFG_LOG_FILE`
- `CFG_DNS_PROPAGATION_WAIT`
- `CFG_DNS_CHECK_ATTEMPTS`
- `CFG_DNS_CHECK_INTERVAL`
- `CFG_RENEWAL_DAYS`
- `CFG_NPM_ENABLED`
- `CFG_NPM_HOST`
- `CFG_NPM_EMAIL`
- `CFG_NPM_PASSWORD`
## Соответствие полей config.json
- `CFG_REGRU_USERNAME``regru_username`
- `CFG_REGRU_PASSWORD``regru_password`
- `CFG_DOMAIN` / первый из `CFG_DOMAINS``domain`
- `CFG_DOMAINS``domains`
- `CFG_WILDCARD``wildcard`
- `CFG_EMAIL``email`
- `CFG_CERT_DIR``cert_dir`
- `CFG_LOG_FILE``log_file`
- `CFG_DNS_PROPAGATION_WAIT``dns_propagation_wait`
- `CFG_DNS_CHECK_ATTEMPTS``dns_check_attempts`
- `CFG_DNS_CHECK_INTERVAL``dns_check_interval`
- `CFG_RENEWAL_DAYS``renewal_days`
- `CFG_NPM_ENABLED``npm_enabled`
- `CFG_NPM_HOST``npm_host`
- `CFG_NPM_EMAIL``npm_email`
- `CFG_NPM_PASSWORD``npm_password`
## Как запустить деплой
1. Откройте Actions
2. Запустите workflow `Deploy scripts to remote server`
3. При необходимости задайте `ref` (ветка/тег/коммит)
### Запуск через Makefile
Makefile умеет запускать workflow через API на `gitea.example.com`:
- `make deploy-service` — деплой `master`
- `make deploy-service REF=<branch_or_tag>` — деплой указанной ветки/тега
Нужен токен (любой из): `DFGIT_TOKEN` / `GIT_TOKEN` / `GITEA_TOKEN` / `GITEA_ACCESS_TOKEN`.
Важно: токен для **запуска** workflow (Makefile) и секреты для **выполнения** workflow (Actions secrets)
— это разные вещи. Workflow внутри всё равно требует `GIT_TOKEN` (или `GITEA_TOKEN`) secret,
SSH ключ и остальные secrets из списка выше.
После завершения проверьте статус сервиса на сервере:
```bash
sudo systemctl status letsencrypt-regru.service
```
# Deploy через Actions и Secrets
Эта страница описывает деплой через workflow `.github/workflows/deploy-service.yml`.
## Триггеры (когда запускается)
1) Автоматически по push
- ветка: `master`
- только если изменились файлы:
- `letsencrypt_regru_api.py`, `letsencrypt_regru*.sh`, `letsencrypt_regru.ps1`
- `requirements.txt`
- `systemd/**`
- `.github/workflows/deploy-service.yml`
2) Вручную (workflow_dispatch)
- из UI Actions
- или через Makefile командой `make deploy-service` (Makefile делает API dispatch)
## Что делает workflow
- деплоит проект на сервер `192.0.2.1` по SSH (ключ)
- перед деплоем генерирует `config.json` из secrets
- копирует архив на сервер, распаковывает в `DEPLOY_PATH`
- перезапускает systemd сервис `DEPLOY_SERVICE`
## Обязательные secrets
### Доступ к репозиторию
- `GIT_TOKEN` (или `GITEA_TOKEN`)
### SSH и деплой
- `DEPLOY_HOST` — должен быть `192.0.2.1`
- `DEPLOY_PORT` — обычно `22`
- `DEPLOY_USER`
- `DEPLOY_SSH_PRIVATE_KEY`
- `DEPLOY_PATH`
- `DEPLOY_SERVICE`
### Генерация config.json
- `CFG_REGRU_USERNAME`
- `CFG_REGRU_PASSWORD`
- `CFG_EMAIL`
- `CFG_DOMAINS`
`CFG_DOMAINS` поддерживает два формата:
1) JSON массив:
```json
["example.com", "pages.gitea.example.com"]
```
2) строка через запятую:
```text
example.com,pages.gitea.example.com
```
Если `CFG_DOMAIN` не указан, в поле `domain` берётся первый домен из `CFG_DOMAINS`.
## Опциональные secrets
- `DEPLOY_SSH_KNOWN_HOSTS`
- `CFG_DOMAIN`
- `CFG_WILDCARD`
- `CFG_CERT_DIR`
- `CFG_LOG_FILE`
- `CFG_DNS_PROPAGATION_WAIT`
- `CFG_DNS_CHECK_ATTEMPTS`
- `CFG_DNS_CHECK_INTERVAL`
- `CFG_RENEWAL_DAYS`
- `CFG_NPM_ENABLED`
- `CFG_NPM_HOST`
- `CFG_NPM_EMAIL`
- `CFG_NPM_PASSWORD`
## Соответствие полей config.json
- `CFG_REGRU_USERNAME``regru_username`
- `CFG_REGRU_PASSWORD``regru_password`
- `CFG_DOMAIN` / первый из `CFG_DOMAINS``domain`
- `CFG_DOMAINS``domains`
- `CFG_WILDCARD``wildcard`
- `CFG_EMAIL``email`
- `CFG_CERT_DIR``cert_dir`
- `CFG_LOG_FILE``log_file`
- `CFG_DNS_PROPAGATION_WAIT``dns_propagation_wait`
- `CFG_DNS_CHECK_ATTEMPTS``dns_check_attempts`
- `CFG_DNS_CHECK_INTERVAL``dns_check_interval`
- `CFG_RENEWAL_DAYS``renewal_days`
- `CFG_NPM_ENABLED``npm_enabled`
- `CFG_NPM_HOST``npm_host`
- `CFG_NPM_EMAIL``npm_email`
- `CFG_NPM_PASSWORD``npm_password`
## Как запустить деплой
1. Откройте Actions
2. Запустите workflow `Deploy scripts to remote server`
3. При необходимости задайте `ref` (ветка/тег/коммит)
### Запуск через Makefile
Makefile умеет запускать workflow через API на `gitea.example.com`:
- `make deploy-service` — деплой `master`
- `make deploy-service REF=<branch_or_tag>` — деплой указанной ветки/тега
Нужен токен (любой из): `DFGIT_TOKEN` / `GIT_TOKEN` / `GITEA_TOKEN` / `GITEA_ACCESS_TOKEN`.
Важно: токен для **запуска** workflow (Makefile) и секреты для **выполнения** workflow (Actions secrets)
— это разные вещи. Workflow внутри всё равно требует `GIT_TOKEN` (или `GITEA_TOKEN`) secret,
SSH ключ и остальные secrets из списка выше.
После завершения проверьте статус сервиса на сервере:
```bash
sudo systemctl status letsencrypt-regru.service
```
+462 -462
View File
@@ -1,462 +1,462 @@
# Синхронизация Gitea → GitHub
Проект описывает несколько способов синхронизировать репозиторий из Gitea в GitHub после push.
## Варианты
1) Git Hooks (рекомендуется) — мгновенно
2) GitHub Actions — 15 минут, гибко
3) Gitea Mirror — просто, но по расписанию
4) Два remote — локальный рабочий процесс
## Рекомендуемый способ: Git Hooks
Идея: на сервере Gitea в `hooks/post-receive` выполнить `git push` в GitHub.
Ключевые шаги:
- найти путь к bare репозиторию на сервере Gitea
- установить `post-receive` из `gitea-hooks/post-receive`
- настроить аутентификацию (SSH ключ или HTTPS token)
- вести лог (например `/var/log/gitea/github-sync.log`)
## Вариант: GitHub Actions
- настроить секреты (`GITEA_URL`, `GITEA_TOKEN`)
- workflow по расписанию/ручному триггеру
- опционально webhook из Gitea
Подробные пошаговые инструкции — см. Appendix ниже.
---
## Appendix (migrated from docs/GITEA_SYNC.md)
<!-- MIGRATED_FROM_DOCS:GITEA_SYNC.md -->
## 🔄 Синхронизация Gitea → GitHub
Автоматическая синхронизация репозитория из Gitea в GitHub после каждого push.
---
### 📋 Доступные методы
| Метод | Сложность | Скорость | Надежность | Рекомендация |
|-------|-----------|----------|------------|--------------|
| **1. Git Hooks** | ⭐⭐ | ⚡ Мгновенно | ✅ Высокая | Рекомендуется |
| **2. GitHub Actions** | ⭐⭐⭐ | ⏱️ 1-5 мин | ✅ Высокая | Для сложных сценариев |
| **3. Gitea Mirror** | ⭐ | ⏱️ По расписанию | ⭐⭐ Средняя | Самый простой |
| **4. Двойной Remote** | ⭐ | ⚡ Мгновенно | ⭐⭐ Средняя | Локальная работа |
---
### 🚀 Метод 1: Git Hooks (Рекомендуется)
#### Установка
**1. На сервере Gitea найдите путь к репозиторию:**
```bash
## Обычно это:
/var/lib/gitea/data/gitea-repositories/username/configure_nginx_manager.git
## Или
/home/git/gitea-repositories/username/configure_nginx_manager.git
```
**2. Создайте post-receive hook:**
```bash
cd /path/to/gitea/repos/username/configure_nginx_manager.git/hooks/
nano post-receive
```
**3. Вставьте содержимое** из файла `gitea-hooks/post-receive` (в этом репозитории)
**4. Настройте параметры:**
```bash
## В файле post-receive измените:
GITHUB_REPO="git@github.com:YOUR_USERNAME/configure_nginx_manager.git"
## Или для HTTPS с токеном:
GITHUB_REPO="https://YOUR_TOKEN@github.com/YOUR_USERNAME/configure_nginx_manager.git"
```
**5. Сделайте скрипт исполняемым:**
```bash
chmod +x post-receive
```
**6. Создайте директорию для логов:**
```bash
mkdir -p /var/log/gitea
chown git:git /var/log/gitea
```
#### Настройка SSH ключей (для git@github.com)
**На сервере Gitea:**
**Шаг 1: Определите пользователя Gitea**
```bash
## Проверьте под каким пользователем запущен Gitea
ps aux | grep gitea | grep -v grep
## Обычно это один из:
## - git (стандартная установка)
## - gitea (установка через Docker/LXC)
```
**Шаг 2: Переключитесь на этого пользователя**
```bash
## Попробуйте git:
sudo su - git
## Если не работает, попробуйте gitea:
sudo su - gitea
## Проверьте текущего пользователя
whoami # Должно быть: git или gitea
```
**Шаг 3: Создайте SSH ключ**
```bash
## Создайте SSH ключ (если его ещё нет)
ssh-keygen -t ed25519 -C "gitea-to-github-sync" -f ~/.ssh/id_ed25519 -N ""
## Скопируйте публичный ключ
cat ~/.ssh/id_ed25519.pub
```
**На GitHub:**
1. Settings → SSH and GPG keys
2. New SSH key
3. Вставьте публичный ключ
4. Save
**⚠️ ВАЖНО: Добавьте GitHub в known_hosts:**
```bash
## От того же пользователя (git или gitea)
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
## Проверьте что ключ добавлен
cat ~/.ssh/known_hosts | grep github.com
```
**Проверка подключения:**
```bash
ssh -T git@github.com
## Должно вывести: Hi username! You've successfully authenticated...
```
#### Настройка токена (для HTTPS)
**На GitHub:**
1. Settings → Developer settings → Personal access tokens → Tokens (classic)
2. Generate new token
3. Выберите scope: `repo` (полный доступ к репозиториям)
4. Скопируйте токен
**В hook файле:**
```bash
GITHUB_REPO="https://ghp_YOUR_TOKEN_HERE@github.com/username/configure_nginx_manager.git"
```
#### Тестирование
```bash
## Сделайте тестовый commit в Gitea
cd /tmp
git clone http://gitea.example.com/username/configure_nginx_manager.git
cd configure_nginx_manager
echo "test" >> README.md
git add README.md
git commit -m "Test sync to GitHub"
git push
## Проверьте лог
tail -f /var/log/gitea/github-sync.log
## Проверьте GitHub - изменения должны появиться
```
---
### 🔄 Метод 2: GitHub Actions
#### Установка
**1. Создайте workflow в GitHub репозитории:**
Файл уже создан: `.github/workflows/sync-from-gitea.yml`
**2. Настройте секреты в GitHub:**
GitHub Repository → Settings → Secrets and variables → Actions → New repository secret
Добавьте:
- **Name**: `GITEA_URL`
- **Value**: `https://gitea.example.com/username/configure_nginx_manager.git`
- **Name**: `GITEA_TOKEN`
- **Value**: Токен доступа Gitea
#### Получение токена Gitea
**В Gitea:**
1. Settings → Applications → Generate New Token
2. Token Name: "GitHub Sync"
3. Select permissions: `read:repository`
4. Generate Token
5. Скопируйте токен
#### Запуск синхронизации
**Автоматически (по расписанию):**
- Каждый час проверяет изменения
**Вручную:**
1. GitHub → Actions
2. Выберите workflow "Sync from Gitea"
3. Run workflow
**Через webhook от Gitea:**
В Gitea репозитории:
1. Settings → Webhooks → Add Webhook → Gitea
2. Target URL: `https://api.github.com/repos/USERNAME/configure_nginx_manager/dispatches`
3. HTTP Method: `POST`
4. POST Content Type: `application/json`
5. Secret: оставьте пустым или используйте
6. Trigger On: `Push events`
7. Body:
```json
{
"event_type": "gitea-push"
}
```
---
### 🪞 Метод 3: Gitea Mirror (Встроенная функция)
#### Настройка
**В Gitea репозитории:**
1. Settings → Repository
2. Прокрутите до "Mirror Settings"
3. Нажмите "Add Push Mirror"
4. Заполните:
- **Git Remote Repository URL**: `https://github.com/username/configure_nginx_manager.git`
- **Username**: ваш GitHub username
- **Password**: GitHub Personal Access Token
- **Sync Interval**: `8h` (каждые 8 часов) или `0` (только вручную)
5. Save
#### Ручная синхронизация
Settings → Repository → Mirror Settings → Sync Now
#### Преимущества
- ✅ Встроенная функция
-Не требует скриптов
- ✅ Управление через веб-интерфейс
#### Недостатки
- ⚠️ Работает по расписанию (не мгновенно)
- ⚠️ Доступно не во всех версиях Gitea
---
### 🔀 Метод 4: Двойной Remote
#### Для локальной работы
**Настройка:**
```bash
## В вашем локальном репозитории
cd configure_nginx_manager
## Добавьте GitHub как второй remote
git remote add github git@github.com:username/configure_nginx_manager.git
## Или настройте push в оба репозитория одновременно
git remote set-url --add --push origin git@github.com:username/configure_nginx_manager.git
## Проверьте
git remote -v
```
**Использование:**
```bash
## Обычный push (только в Gitea)
git push origin main
## Push в GitHub
git push github main
## Push в оба репозитория
git push origin main
git push github main
## Или создайте alias
git config alias.pushall '!git push origin main && git push github main'
git pushall
```
---
### 🔍 Проверка синхронизации
#### Проверка через Git
```bash
## Сравнить коммиты
git ls-remote git@gitea.example.com:username/configure_nginx_manager.git
git ls-remote git@github.com:username/configure_nginx_manager.git
## Должны быть одинаковые SHA
```
#### Проверка логов (Метод 1 - Hooks)
```bash
## На сервере Gitea
tail -f /var/log/gitea/github-sync.log
```
#### Проверка GitHub Actions (Метод 2)
1. GitHub Repository → Actions
2. Смотрите последние запуски
3. Проверьте логи выполнения
---
### ⚙️ Рекомендованная конфигурация
Для максимальной надежности используйте **комбинацию методов**:
1. **Git Hook** (основной) - мгновенная синхронизация
2. **GitHub Actions** (резервный) - проверка каждый час на случай сбоя hook
#### Установка обоих методов
```bash
## 1. Установите Git Hook на сервере Gitea
## (см. Метод 1)
## 2. Настройте GitHub Actions
## (см. Метод 2)
## 3. GitHub Actions будет подхватывать пропущенные изменения
```
---
### 🐛 Устранение проблем
#### Проблема: Hook не срабатывает
**Проверка:**
```bash
## На сервере Gitea
ls -la /path/to/repo.git/hooks/post-receive
## Должно быть -rwxr-xr-x
## Проверьте права
chmod +x /path/to/repo.git/hooks/post-receive
chown git:git /path/to/repo.git/hooks/post-receive
## Проверьте лог ошибок Gitea
tail -f /var/log/gitea/gitea.log
```
#### Проблема: Permission denied (SSH)
**Решение:**
```bash
## Убедитесь что SSH ключ добавлен в GitHub
ssh -T git@github.com
## Проверьте права на .ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
```
#### Проблема: Authentication failed (HTTPS)
**Решение:**
- Проверьте токен GitHub (должен иметь scope `repo`)
- Токен не истёк
- Правильный формат URL: `https://TOKEN@github.com/user/repo.git`
#### Проблема: GitHub Actions не запускается
**Решение:**
1. Проверьте секреты в Settings → Secrets
2. Проверьте формат webhook от Gitea
3. Запустите вручную для теста
---
### 📊 Сравнение методов
#### Скорость синхронизации
- **Git Hooks**: ⚡ < 1 секунды
- **GitHub Actions (webhook)**: ⏱️ 10-30 секунд
- **GitHub Actions (schedule)**: ⏱️ до 1 часа
- **Gitea Mirror**: ⏱️ по расписанию
#### Надежность
- **Git Hooks**: ⭐⭐⭐⭐⭐ (при правильной настройке)
- **GitHub Actions**: ⭐⭐⭐⭐⭐ (очень надежно)
- **Gitea Mirror**: ⭐⭐⭐ (зависит от версии Gitea)
- **Двойной Remote**: ⭐⭐ (требует ручного действия)
---
### 🎯 Итоговая рекомендация
Для проекта `configure_nginx_manager`:
**1. Основной метод: Git Hook**
- Быстро
- Надежно
- Автоматически
**2. Резервный метод: GitHub Actions**
- Проверка каждый час
- Подхватит пропущенные изменения
- Можно запустить вручную
**3. Мониторинг:**
```bash
## Еженедельная проверка
git ls-remote origin | head -1
git ls-remote github | head -1
## SHA должны совпадать
```
---
### 📝 Быстрая установка
```bash
## На сервере Gitea
sudo su - git
cd /path/to/gitea-repositories/username/configure_nginx_manager.git/hooks/
## Скачайте hook
wget https://raw.githubusercontent.com/username/configure_nginx_manager/main/gitea-hooks/post-receive
## Настройте
nano post-receive
## Измените GITHUB_REPO
## Права
chmod +x post-receive
## Тест
echo "test" | ./post-receive
```
Готово! 🎉
# Синхронизация Gitea → GitHub
Проект описывает несколько способов синхронизировать репозиторий из Gitea в GitHub после push.
## Варианты
1) Git Hooks (рекомендуется) — мгновенно
2) GitHub Actions — 15 минут, гибко
3) Gitea Mirror — просто, но по расписанию
4) Два remote — локальный рабочий процесс
## Рекомендуемый способ: Git Hooks
Идея: на сервере Gitea в `hooks/post-receive` выполнить `git push` в GitHub.
Ключевые шаги:
- найти путь к bare репозиторию на сервере Gitea
- установить `post-receive` из `gitea-hooks/post-receive`
- настроить аутентификацию (SSH ключ или HTTPS token)
- вести лог (например `/var/log/gitea/github-sync.log`)
## Вариант: GitHub Actions
- настроить секреты (`GITEA_URL`, `GITEA_TOKEN`)
- workflow по расписанию/ручному триггеру
- опционально webhook из Gitea
Подробные пошаговые инструкции — см. Appendix ниже.
---
## Appendix (migrated from docs/GITEA_SYNC.md)
<!-- MIGRATED_FROM_DOCS:GITEA_SYNC.md -->
## 🔄 Синхронизация Gitea → GitHub
Автоматическая синхронизация репозитория из Gitea в GitHub после каждого push.
---
### 📋 Доступные методы
| Метод | Сложность | Скорость | Надежность | Рекомендация |
|-------|-----------|----------|------------|--------------|
| **1. Git Hooks** | ⭐⭐ | ⚡ Мгновенно | ✅ Высокая | Рекомендуется |
| **2. GitHub Actions** | ⭐⭐⭐ | ⏱️ 1-5 мин | ✅ Высокая | Для сложных сценариев |
| **3. Gitea Mirror** | ⭐ | ⏱️ По расписанию | ⭐⭐ Средняя | Самый простой |
| **4. Двойной Remote** | ⭐ | ⚡ Мгновенно | ⭐⭐ Средняя | Локальная работа |
---
### 🚀 Метод 1: Git Hooks (Рекомендуется)
#### Установка
**1. На сервере Gitea найдите путь к репозиторию:**
```bash
## Обычно это:
/var/lib/gitea/data/gitea-repositories/username/configure_nginx_manager.git
## Или
/home/git/gitea-repositories/username/configure_nginx_manager.git
```
**2. Создайте post-receive hook:**
```bash
cd /path/to/gitea/repos/username/configure_nginx_manager.git/hooks/
nano post-receive
```
**3. Вставьте содержимое** из файла `gitea-hooks/post-receive` (в этом репозитории)
**4. Настройте параметры:**
```bash
## В файле post-receive измените:
GITHUB_REPO="git@github.com:YOUR_USERNAME/configure_nginx_manager.git"
## Или для HTTPS с токеном:
GITHUB_REPO="https://YOUR_TOKEN@github.com/YOUR_USERNAME/configure_nginx_manager.git"
```
**5. Сделайте скрипт исполняемым:**
```bash
chmod +x post-receive
```
**6. Создайте директорию для логов:**
```bash
mkdir -p /var/log/gitea
chown git:git /var/log/gitea
```
#### Настройка SSH ключей (для git@github.com)
**На сервере Gitea:**
**Шаг 1: Определите пользователя Gitea**
```bash
## Проверьте под каким пользователем запущен Gitea
ps aux | grep gitea | grep -v grep
## Обычно это один из:
## - git (стандартная установка)
## - gitea (установка через Docker/LXC)
```
**Шаг 2: Переключитесь на этого пользователя**
```bash
## Попробуйте git:
sudo su - git
## Если не работает, попробуйте gitea:
sudo su - gitea
## Проверьте текущего пользователя
whoami # Должно быть: git или gitea
```
**Шаг 3: Создайте SSH ключ**
```bash
## Создайте SSH ключ (если его ещё нет)
ssh-keygen -t ed25519 -C "gitea-to-github-sync" -f ~/.ssh/id_ed25519 -N ""
## Скопируйте публичный ключ
cat ~/.ssh/id_ed25519.pub
```
**На GitHub:**
1. Settings → SSH and GPG keys
2. New SSH key
3. Вставьте публичный ключ
4. Save
**⚠️ ВАЖНО: Добавьте GitHub в known_hosts:**
```bash
## От того же пользователя (git или gitea)
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
## Проверьте что ключ добавлен
cat ~/.ssh/known_hosts | grep github.com
```
**Проверка подключения:**
```bash
ssh -T git@github.com
## Должно вывести: Hi username! You've successfully authenticated...
```
#### Настройка токена (для HTTPS)
**На GitHub:**
1. Settings → Developer settings → Personal access tokens → Tokens (classic)
2. Generate new token
3. Выберите scope: `repo` (полный доступ к репозиториям)
4. Скопируйте токен
**В hook файле:**
```bash
GITHUB_REPO="https://ghp_YOUR_TOKEN_HERE@github.com/username/configure_nginx_manager.git"
```
#### Тестирование
```bash
## Сделайте тестовый commit в Gitea
cd /tmp
git clone http://gitea.example.com/username/configure_nginx_manager.git
cd configure_nginx_manager
echo "test" >> README.md
git add README.md
git commit -m "Test sync to GitHub"
git push
## Проверьте лог
tail -f /var/log/gitea/github-sync.log
## Проверьте GitHub - изменения должны появиться
```
---
### 🔄 Метод 2: GitHub Actions
#### Установка
**1. Создайте workflow в GitHub репозитории:**
Файл уже создан: `.github/workflows/sync-from-gitea.yml`
**2. Настройте секреты в GitHub:**
GitHub Repository → Settings → Secrets and variables → Actions → New repository secret
Добавьте:
- **Name**: `GITEA_URL`
- **Value**: `https://gitea.example.com/username/configure_nginx_manager.git`
- **Name**: `GITEA_TOKEN`
- **Value**: Токен доступа Gitea
#### Получение токена Gitea
**В Gitea:**
1. Settings → Applications → Generate New Token
2. Token Name: "GitHub Sync"
3. Select permissions: `read:repository`
4. Generate Token
5. Скопируйте токен
#### Запуск синхронизации
**Автоматически (по расписанию):**
- Каждый час проверяет изменения
**Вручную:**
1. GitHub → Actions
2. Выберите workflow "Sync from Gitea"
3. Run workflow
**Через webhook от Gitea:**
В Gitea репозитории:
1. Settings → Webhooks → Add Webhook → Gitea
2. Target URL: `https://api.github.com/repos/USERNAME/configure_nginx_manager/dispatches`
3. HTTP Method: `POST`
4. POST Content Type: `application/json`
5. Secret: оставьте пустым или используйте
6. Trigger On: `Push events`
7. Body:
```json
{
"event_type": "gitea-push"
}
```
---
### 🪞 Метод 3: Gitea Mirror (Встроенная функция)
#### Настройка
**В Gitea репозитории:**
1. Settings → Repository
2. Прокрутите до "Mirror Settings"
3. Нажмите "Add Push Mirror"
4. Заполните:
- **Git Remote Repository URL**: `https://github.com/username/configure_nginx_manager.git`
- **Username**: ваш GitHub username
- **Password**: GitHub Personal Access Token
- **Sync Interval**: `8h` (каждые 8 часов) или `0` (только вручную)
5. Save
#### Ручная синхронизация
Settings → Repository → Mirror Settings → Sync Now
#### Преимущества
- ✅ Встроенная функция
-Не требует скриптов
- ✅ Управление через веб-интерфейс
#### Недостатки
- ⚠️ Работает по расписанию (не мгновенно)
- ⚠️ Доступно не во всех версиях Gitea
---
### 🔀 Метод 4: Двойной Remote
#### Для локальной работы
**Настройка:**
```bash
## В вашем локальном репозитории
cd configure_nginx_manager
## Добавьте GitHub как второй remote
git remote add github git@github.com:username/configure_nginx_manager.git
## Или настройте push в оба репозитория одновременно
git remote set-url --add --push origin git@github.com:username/configure_nginx_manager.git
## Проверьте
git remote -v
```
**Использование:**
```bash
## Обычный push (только в Gitea)
git push origin main
## Push в GitHub
git push github main
## Push в оба репозитория
git push origin main
git push github main
## Или создайте alias
git config alias.pushall '!git push origin main && git push github main'
git pushall
```
---
### 🔍 Проверка синхронизации
#### Проверка через Git
```bash
## Сравнить коммиты
git ls-remote git@gitea.example.com:username/configure_nginx_manager.git
git ls-remote git@github.com:username/configure_nginx_manager.git
## Должны быть одинаковые SHA
```
#### Проверка логов (Метод 1 - Hooks)
```bash
## На сервере Gitea
tail -f /var/log/gitea/github-sync.log
```
#### Проверка GitHub Actions (Метод 2)
1. GitHub Repository → Actions
2. Смотрите последние запуски
3. Проверьте логи выполнения
---
### ⚙️ Рекомендованная конфигурация
Для максимальной надежности используйте **комбинацию методов**:
1. **Git Hook** (основной) - мгновенная синхронизация
2. **GitHub Actions** (резервный) - проверка каждый час на случай сбоя hook
#### Установка обоих методов
```bash
## 1. Установите Git Hook на сервере Gitea
## (см. Метод 1)
## 2. Настройте GitHub Actions
## (см. Метод 2)
## 3. GitHub Actions будет подхватывать пропущенные изменения
```
---
### 🐛 Устранение проблем
#### Проблема: Hook не срабатывает
**Проверка:**
```bash
## На сервере Gitea
ls -la /path/to/repo.git/hooks/post-receive
## Должно быть -rwxr-xr-x
## Проверьте права
chmod +x /path/to/repo.git/hooks/post-receive
chown git:git /path/to/repo.git/hooks/post-receive
## Проверьте лог ошибок Gitea
tail -f /var/log/gitea/gitea.log
```
#### Проблема: Permission denied (SSH)
**Решение:**
```bash
## Убедитесь что SSH ключ добавлен в GitHub
ssh -T git@github.com
## Проверьте права на .ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
```
#### Проблема: Authentication failed (HTTPS)
**Решение:**
- Проверьте токен GitHub (должен иметь scope `repo`)
- Токен не истёк
- Правильный формат URL: `https://TOKEN@github.com/user/repo.git`
#### Проблема: GitHub Actions не запускается
**Решение:**
1. Проверьте секреты в Settings → Secrets
2. Проверьте формат webhook от Gitea
3. Запустите вручную для теста
---
### 📊 Сравнение методов
#### Скорость синхронизации
- **Git Hooks**: ⚡ < 1 секунды
- **GitHub Actions (webhook)**: ⏱️ 10-30 секунд
- **GitHub Actions (schedule)**: ⏱️ до 1 часа
- **Gitea Mirror**: ⏱️ по расписанию
#### Надежность
- **Git Hooks**: ⭐⭐⭐⭐⭐ (при правильной настройке)
- **GitHub Actions**: ⭐⭐⭐⭐⭐ (очень надежно)
- **Gitea Mirror**: ⭐⭐⭐ (зависит от версии Gitea)
- **Двойной Remote**: ⭐⭐ (требует ручного действия)
---
### 🎯 Итоговая рекомендация
Для проекта `configure_nginx_manager`:
**1. Основной метод: Git Hook**
- Быстро
- Надежно
- Автоматически
**2. Резервный метод: GitHub Actions**
- Проверка каждый час
- Подхватит пропущенные изменения
- Можно запустить вручную
**3. Мониторинг:**
```bash
## Еженедельная проверка
git ls-remote origin | head -1
git ls-remote github | head -1
## SHA должны совпадать
```
---
### 📝 Быстрая установка
```bash
## На сервере Gitea
sudo su - git
cd /path/to/gitea-repositories/username/configure_nginx_manager.git/hooks/
## Скачайте hook
wget https://raw.githubusercontent.com/username/configure_nginx_manager/main/gitea-hooks/post-receive
## Настройте
nano post-receive
## Измените GITHUB_REPO
## Права
chmod +x post-receive
## Тест
echo "test" | ./post-receive
```
Готово! 🎉
+379 -379
View File
@@ -1,379 +1,379 @@
# SSL Certificate Manager (Let's Encrypt + reg.ru) — Wiki (RU)
Это Wiki проекта **configure_nginx_manager**: автоматическое получение и продление SSL сертификатов Let's Encrypt через **DNS-01** (API **reg.ru**) с опциональной синхронизацией сертификатов в **Nginx Proxy Manager (NPM)**.
## Что умеет проект
- Получение **production** сертификатов Let's Encrypt (DNS-01) для доменов reg.ru
- Поддержка **wildcard** (например, `*.example.com`)
- Автопроверка и автопродление (cron/systemd)
- Диагностика: `--test-api`, `--test-dns`
- Тестовые самоподписанные сертификаты для разработки: `--test-cert` (без лимитов LE)
- (Опционально) Автозагрузка/обновление сертификатов в NPM по API
- **Мультидоменный режим**: один конфиг → несколько доменов (`domains[]`)
## Быстрый старт
1) Установка
- См. страницу: [Installation](Installation.md)
2) Конфигурация
- См. страницу: [Configuration](Configuration.md)
3) Проверка доступа к API и DNS
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
4) Тестирование без лимитов
- `letsencrypt-regru --test-cert`
5) Production сертификат
- `letsencrypt-regru --obtain`
6) Автопродление
- `letsencrypt-regru --auto` (обычно запускается systemd timer'ом)
## Навигация
- [Installation](Installation.md)
- [Configuration](Configuration.md)
- [Commands](Commands.md)
- [LetsEncrypt Workflow](LetsEncrypt_Workflow.md)
- [Nginx Proxy Manager](Nginx_Proxy_Manager.md)
- [Testing](Testing.md)
- [Reg.ru API Troubleshooting](RegRu_API_Troubleshooting.md)
- [Build & Release](Build_and_Release.md)
- [Deploy и Secrets](Deploy_Actions_Secrets.md)
- [Project Structure](Project_Structure.md)
- [Gitea → GitHub Sync](Gitea_Sync.md)
- [Changelog](Changelog.md)
## Примечания по лимитам Let's Encrypt
- Production: обычно **до 5 сертификатов/неделю на домен**
- Для отладки автоматизации используйте:
- `--staging` (LE staging, без лимитов)
- `--test-cert` (самоподписанный, мгновенно)
---
Источник: страницы Wiki этого репозитория и актуальное поведение CLI.
---
## Appendix (migrated from docs/DESCRIPTION.md)
<!-- MIGRATED_FROM_DOCS:DESCRIPTION.md -->
## 🔒 SSL Certificate Manager для Let's Encrypt + reg.ru
**Автоматическое управление SSL сертификатами Let's Encrypt с DNS валидацией через API reg.ru и интеграцией с Nginx Proxy Manager**
### 📖 Описание
Комплексное решение для автоматизации создания, обновления и управления SSL сертификатами Let's Encrypt для доменов, зарегистрированных на reg.ru. Поддерживает DNS-01 валидацию, wildcard сертификаты, автоматическую загрузку в Nginx Proxy Manager и генерацию тестовых сертификатов для разработки.
#### ✨ Основные возможности
- 🔐 **Автоматическое получение SSL сертификатов** через Let's Encrypt
- 🌐 **DNS-01 валидация** через API reg.ru (поддержка wildcard доменов)
- 🔄 **Автоматическое обновление** сертификатов с настраиваемым порогом
- 📦 **Интеграция с Nginx Proxy Manager** - автоматическая загрузка и обновление
- 🧪 **Тестовые сертификаты** - обход лимитов Let's Encrypt (5 в неделю)
- ⚙️ **Полная автоматизация** через systemd/cron
- 🔀 **Синхронизация репозиториев** - автоматическая синхронизация Gitea → GitHub
#### 🚀 Быстрый старт
```bash
## Установка через Makefile
sudo make install
## Настройка конфигурации
sudo nano /etc/letsencrypt/regru_config.json
## Создание тестового сертификата (без лимитов)
sudo make test-cert
## Получение production сертификата
sudo make obtain
```
#### 📋 Требования
- **ОС**: Linux (Ubuntu/Debian/CentOS)
- **Python**: 3.6+
- **Зависимости**: certbot, requests, cryptography
- **API**: reg.ru (доступ к DNS управлению)
- **Опционально**: Nginx Proxy Manager
#### 🎯 Сценарии использования
- ✅ Автоматизация SSL сертификатов для web серверов
- ✅ Централизованное управление через Nginx Proxy Manager
- ✅ Тестирование и разработка с самоподписанными сертификатами
- ✅ CI/CD интеграция
- ✅ Мультидоменные конфигурации с wildcard
#### 📚 Документация
- [README.md](README.md) - Полное руководство (1400+ строк)
- [TESTING_GUIDE.md](Testing.md) - Руководство по тестированию
- [GITEA_SYNC.md](Gitea_Sync.md) - Синхронизация Gitea → GitHub
- [CHEATSHEET.md](Commands.md) - Быстрая шпаргалка
---
### 📖 Description (English)
**Automated Let's Encrypt SSL Certificate Manager with DNS validation via reg.ru API and Nginx Proxy Manager integration**
Comprehensive solution for automating the creation, renewal, and management of Let's Encrypt SSL certificates for domains registered with reg.ru. Supports DNS-01 validation, wildcard certificates, automatic upload to Nginx Proxy Manager, and test certificate generation for development.
#### ✨ Key Features
- 🔐 **Automatic SSL certificate** issuance via Let's Encrypt
- 🌐 **DNS-01 validation** via reg.ru API (wildcard domain support)
- 🔄 **Automatic renewal** with configurable threshold
- 📦 **Nginx Proxy Manager integration** - automatic upload and update
- 🧪 **Test certificates** - bypass Let's Encrypt rate limits (5 per week)
- ⚙️ **Full automation** via systemd/cron
- 🔀 **Repository sync** - automatic Gitea → GitHub synchronization
#### 🚀 Quick Start
```bash
## Install via Makefile
sudo make install
## Configure
sudo nano /etc/letsencrypt/regru_config.json
## Create test certificate (no limits)
sudo make test-cert
## Get production certificate
sudo make obtain
```
#### 📋 Requirements
- **OS**: Linux (Ubuntu/Debian/CentOS)
- **Python**: 3.6+
- **Dependencies**: certbot, requests, cryptography
- **API**: reg.ru (DNS management access)
- **Optional**: Nginx Proxy Manager
#### 🎯 Use Cases
- ✅ SSL certificate automation for web servers
- ✅ Centralized management via Nginx Proxy Manager
- ✅ Development and testing with self-signed certificates
- ✅ CI/CD integration
- ✅ Multi-domain configurations with wildcards
#### 📚 Documentation
- [README.md](README.md) - Complete guide (1400+ lines)
- [TESTING_GUIDE.md](Testing.md) - Testing guide
- [GITEA_SYNC.md](Gitea_Sync.md) - Gitea → GitHub sync
- [CHEATSHEET.md](Commands.md) - Quick reference
---
### 👤 Автор / Author
**Фофанов Дмитрий** @ 2025
### 📄 Лицензия / License
Open Source - Free to use
### 🤝 Вклад / Contributing
Pull requests приветствуются / Pull requests are welcome!
### 🔗 Ссылки / Links
- **Документация reg.ru API**: https://www.reg.ru/support/api
- **Let's Encrypt**: https://letsencrypt.org/
- **Nginx Proxy Manager**: https://nginxproxymanager.com/
---
## Appendix (migrated from docs/SSL_SCRIPTS_README.md)
<!-- MIGRATED_FROM_DOCS:SSL_SCRIPTS_README.md -->
## Автоматизация SSL сертификатов Let's Encrypt для reg.ru
Набор скриптов для автоматического создания и обновления SSL сертификатов Let's Encrypt с использованием DNS валидации через API reg.ru.
### 📁 Содержимое проекта
- **letsencrypt_regru_dns.sh** - Bash скрипт (Linux) с certbot-dns-regru
- **letsencrypt_regru_api.py** - Python скрипт с прямым API интеграцией
- **letsencrypt_regru.ps1** - PowerShell скрипт (Windows)
- **config.json.example** - Пример файла конфигурации
- **USAGE.md** - Подробная инструкция по использованию
### 🚀 Быстрый старт
#### Linux (Bash)
```bash
## 1. Отредактируйте конфигурацию в скрипте
nano letsencrypt_regru_dns.sh
## 2. Установите права
chmod +x letsencrypt_regru_dns.sh
## 3. Запустите
sudo ./letsencrypt_regru_dns.sh
```
#### Linux (Python)
```bash
## 1. Создайте конфигурацию
sudo python3 letsencrypt_regru_api.py --create-config /etc/letsencrypt/regru_config.json
## 2. Отредактируйте конфигурацию
sudo nano /etc/letsencrypt/regru_config.json
## 3. Получите сертификат
sudo python3 letsencrypt_regru_api.py -c /etc/letsencrypt/regru_config.json --obtain
```
#### Windows (PowerShell)
```powershell
## 1. Создайте файл конфигурации config.json на основе config.json.example
## 2. Запустите скрипт
.\letsencrypt_regru.ps1 -ConfigFile .\config.json
```
### ⚙️ Конфигурация
Отредактируйте `config.json`:
```json
{
"regru_username": аш_логин",
"regru_password": аш_пароль",
"domain": "example.com",
"wildcard": true,
"email": "admin@example.com"
}
```
### 📋 Требования
#### Linux
- certbot
- Python 3.6+
- pip3
- requests, cryptography (Python модули)
- certbot-dns-regru (опционально)
#### Windows
- certbot
- PowerShell 5.1+
- openssl (для проверки сертификатов)
### 🔄 Автоматическое обновление
#### Через cron (Linux)
```bash
## Добавьте в crontab
sudo crontab -e
## Проверка каждый день в 3:00
0 3 * * * /usr/bin/python3 /path/to/letsencrypt_regru_api.py -c /etc/letsencrypt/regru_config.json
```
#### Через Task Scheduler (Windows)
1. Откройте Task Scheduler
2. Создайте новую задачу
3. Триггер: Ежедневно в 3:00
4. Действие: Запуск PowerShell скрипта
### 📖 Функции
✅ Создание wildcard сертификатов (*.domain.com)
✅ Автоматическая DNS валидация через API reg.ru
✅ Проверка срока действия сертификата
✅ Автоматическое обновление перед истечением
✅ Перезагрузка веб-сервера после обновления
✅ Подробное логирование всех операций
### 🔧 Использование с Nginx Proxy Manager
После получения сертификата:
1. Войдите в NPM: http://192.0.2.1:81/
2. SSL Certificates → Add SSL Certificate → Custom
3. Вставьте содержимое:
- Certificate Key: `/etc/letsencrypt/live/domain.com/privkey.pem`
- Certificate: `/etc/letsencrypt/live/domain.com/fullchain.pem`
### 📝 Логи
- Bash: `/var/log/letsencrypt_regru.log`
- Python: `/var/log/letsencrypt_regru.log`
- PowerShell: `.\letsencrypt_regru.log`
- Certbot: `/var/log/letsencrypt/letsencrypt.log`
### 🆘 Устранение неполадок
#### Ошибка аутентификации API
- Проверьте учетные данные reg.ru
- Убедитесь, что домен под вашим управлением
#### DNS запись не распространяется
- Увеличьте `dns_propagation_wait` до 120 секунд
- Проверьте DNS: `nslookup -type=TXT _acme-challenge.domain.com`
#### Certbot не найден
```bash
## Ubuntu/Debian
sudo apt-get install certbot
## Или через snap
sudo snap install --classic certbot
```
### 📚 Документация
Подробная документация в файле [USAGE.md](USAGE.md)
### 🔐 Безопасность
- Храните учетные данные в безопасности
- Используйте `chmod 600` для конфигурационных файлов
- Регулярно обновляйте пароли
### ⚠️ Важно
- Let's Encrypt сертификаты действительны 90 дней
- Рекомендуется настроить автоматическое обновление
- Для wildcard сертификатов требуется DNS валидация
### 📞 Поддержка
- [Документация reg.ru API](https://www.reg.ru/support/api)
- [Документация Let's Encrypt](https://letsencrypt.org/docs/)
- [Certbot Documentation](https://certbot.eff.org/docs/)
### 📄 Лицензия
Скрипты предоставляются "как есть" для свободного использования.
---
**Успешной автоматизации! 🔒**
# SSL Certificate Manager (Let's Encrypt + reg.ru) — Wiki (RU)
Это Wiki проекта **configure_nginx_manager**: автоматическое получение и продление SSL сертификатов Let's Encrypt через **DNS-01** (API **reg.ru**) с опциональной синхронизацией сертификатов в **Nginx Proxy Manager (NPM)**.
## Что умеет проект
- Получение **production** сертификатов Let's Encrypt (DNS-01) для доменов reg.ru
- Поддержка **wildcard** (например, `*.example.com`)
- Автопроверка и автопродление (cron/systemd)
- Диагностика: `--test-api`, `--test-dns`
- Тестовые самоподписанные сертификаты для разработки: `--test-cert` (без лимитов LE)
- (Опционально) Автозагрузка/обновление сертификатов в NPM по API
- **Мультидоменный режим**: один конфиг → несколько доменов (`domains[]`)
## Быстрый старт
1) Установка
- См. страницу: [Installation](Installation.md)
2) Конфигурация
- См. страницу: [Configuration](Configuration.md)
3) Проверка доступа к API и DNS
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
4) Тестирование без лимитов
- `letsencrypt-regru --test-cert`
5) Production сертификат
- `letsencrypt-regru --obtain`
6) Автопродление
- `letsencrypt-regru --auto` (обычно запускается systemd timer'ом)
## Навигация
- [Installation](Installation.md)
- [Configuration](Configuration.md)
- [Commands](Commands.md)
- [LetsEncrypt Workflow](LetsEncrypt_Workflow.md)
- [Nginx Proxy Manager](Nginx_Proxy_Manager.md)
- [Testing](Testing.md)
- [Reg.ru API Troubleshooting](RegRu_API_Troubleshooting.md)
- [Build & Release](Build_and_Release.md)
- [Deploy и Secrets](Deploy_Actions_Secrets.md)
- [Project Structure](Project_Structure.md)
- [Gitea → GitHub Sync](Gitea_Sync.md)
- [Changelog](Changelog.md)
## Примечания по лимитам Let's Encrypt
- Production: обычно **до 5 сертификатов/неделю на домен**
- Для отладки автоматизации используйте:
- `--staging` (LE staging, без лимитов)
- `--test-cert` (самоподписанный, мгновенно)
---
Источник: страницы Wiki этого репозитория и актуальное поведение CLI.
---
## Appendix (migrated from docs/DESCRIPTION.md)
<!-- MIGRATED_FROM_DOCS:DESCRIPTION.md -->
## 🔒 SSL Certificate Manager для Let's Encrypt + reg.ru
**Автоматическое управление SSL сертификатами Let's Encrypt с DNS валидацией через API reg.ru и интеграцией с Nginx Proxy Manager**
### 📖 Описание
Комплексное решение для автоматизации создания, обновления и управления SSL сертификатами Let's Encrypt для доменов, зарегистрированных на reg.ru. Поддерживает DNS-01 валидацию, wildcard сертификаты, автоматическую загрузку в Nginx Proxy Manager и генерацию тестовых сертификатов для разработки.
#### ✨ Основные возможности
- 🔐 **Автоматическое получение SSL сертификатов** через Let's Encrypt
- 🌐 **DNS-01 валидация** через API reg.ru (поддержка wildcard доменов)
- 🔄 **Автоматическое обновление** сертификатов с настраиваемым порогом
- 📦 **Интеграция с Nginx Proxy Manager** - автоматическая загрузка и обновление
- 🧪 **Тестовые сертификаты** - обход лимитов Let's Encrypt (5 в неделю)
- ⚙️ **Полная автоматизация** через systemd/cron
- 🔀 **Синхронизация репозиториев** - автоматическая синхронизация Gitea → GitHub
#### 🚀 Быстрый старт
```bash
## Установка через Makefile
sudo make install
## Настройка конфигурации
sudo nano /etc/letsencrypt/regru_config.json
## Создание тестового сертификата (без лимитов)
sudo make test-cert
## Получение production сертификата
sudo make obtain
```
#### 📋 Требования
- **ОС**: Linux (Ubuntu/Debian/CentOS)
- **Python**: 3.6+
- **Зависимости**: certbot, requests, cryptography
- **API**: reg.ru (доступ к DNS управлению)
- **Опционально**: Nginx Proxy Manager
#### 🎯 Сценарии использования
- ✅ Автоматизация SSL сертификатов для web серверов
- ✅ Централизованное управление через Nginx Proxy Manager
- ✅ Тестирование и разработка с самоподписанными сертификатами
- ✅ CI/CD интеграция
- ✅ Мультидоменные конфигурации с wildcard
#### 📚 Документация
- [README.md](README.md) - Полное руководство (1400+ строк)
- [TESTING_GUIDE.md](Testing.md) - Руководство по тестированию
- [GITEA_SYNC.md](Gitea_Sync.md) - Синхронизация Gitea → GitHub
- [CHEATSHEET.md](Commands.md) - Быстрая шпаргалка
---
### 📖 Description (English)
**Automated Let's Encrypt SSL Certificate Manager with DNS validation via reg.ru API and Nginx Proxy Manager integration**
Comprehensive solution for automating the creation, renewal, and management of Let's Encrypt SSL certificates for domains registered with reg.ru. Supports DNS-01 validation, wildcard certificates, automatic upload to Nginx Proxy Manager, and test certificate generation for development.
#### ✨ Key Features
- 🔐 **Automatic SSL certificate** issuance via Let's Encrypt
- 🌐 **DNS-01 validation** via reg.ru API (wildcard domain support)
- 🔄 **Automatic renewal** with configurable threshold
- 📦 **Nginx Proxy Manager integration** - automatic upload and update
- 🧪 **Test certificates** - bypass Let's Encrypt rate limits (5 per week)
- ⚙️ **Full automation** via systemd/cron
- 🔀 **Repository sync** - automatic Gitea → GitHub synchronization
#### 🚀 Quick Start
```bash
## Install via Makefile
sudo make install
## Configure
sudo nano /etc/letsencrypt/regru_config.json
## Create test certificate (no limits)
sudo make test-cert
## Get production certificate
sudo make obtain
```
#### 📋 Requirements
- **OS**: Linux (Ubuntu/Debian/CentOS)
- **Python**: 3.6+
- **Dependencies**: certbot, requests, cryptography
- **API**: reg.ru (DNS management access)
- **Optional**: Nginx Proxy Manager
#### 🎯 Use Cases
- ✅ SSL certificate automation for web servers
- ✅ Centralized management via Nginx Proxy Manager
- ✅ Development and testing with self-signed certificates
- ✅ CI/CD integration
- ✅ Multi-domain configurations with wildcards
#### 📚 Documentation
- [README.md](README.md) - Complete guide (1400+ lines)
- [TESTING_GUIDE.md](Testing.md) - Testing guide
- [GITEA_SYNC.md](Gitea_Sync.md) - Gitea → GitHub sync
- [CHEATSHEET.md](Commands.md) - Quick reference
---
### 👤 Автор / Author
**Фофанов Дмитрий** @ 2025
### 📄 Лицензия / License
Open Source - Free to use
### 🤝 Вклад / Contributing
Pull requests приветствуются / Pull requests are welcome!
### 🔗 Ссылки / Links
- **Документация reg.ru API**: https://www.reg.ru/support/api
- **Let's Encrypt**: https://letsencrypt.org/
- **Nginx Proxy Manager**: https://nginxproxymanager.com/
---
## Appendix (migrated from docs/SSL_SCRIPTS_README.md)
<!-- MIGRATED_FROM_DOCS:SSL_SCRIPTS_README.md -->
## Автоматизация SSL сертификатов Let's Encrypt для reg.ru
Набор скриптов для автоматического создания и обновления SSL сертификатов Let's Encrypt с использованием DNS валидации через API reg.ru.
### 📁 Содержимое проекта
- **letsencrypt_regru_dns.sh** - Bash скрипт (Linux) с certbot-dns-regru
- **letsencrypt_regru_api.py** - Python скрипт с прямым API интеграцией
- **letsencrypt_regru.ps1** - PowerShell скрипт (Windows)
- **config.json.example** - Пример файла конфигурации
- **USAGE.md** - Подробная инструкция по использованию
### 🚀 Быстрый старт
#### Linux (Bash)
```bash
## 1. Отредактируйте конфигурацию в скрипте
nano letsencrypt_regru_dns.sh
## 2. Установите права
chmod +x letsencrypt_regru_dns.sh
## 3. Запустите
sudo ./letsencrypt_regru_dns.sh
```
#### Linux (Python)
```bash
## 1. Создайте конфигурацию
sudo python3 letsencrypt_regru_api.py --create-config /etc/letsencrypt/regru_config.json
## 2. Отредактируйте конфигурацию
sudo nano /etc/letsencrypt/regru_config.json
## 3. Получите сертификат
sudo python3 letsencrypt_regru_api.py -c /etc/letsencrypt/regru_config.json --obtain
```
#### Windows (PowerShell)
```powershell
## 1. Создайте файл конфигурации config.json на основе config.json.example
## 2. Запустите скрипт
.\letsencrypt_regru.ps1 -ConfigFile .\config.json
```
### ⚙️ Конфигурация
Отредактируйте `config.json`:
```json
{
"regru_username": аш_логин",
"regru_password": аш_пароль",
"domain": "example.com",
"wildcard": true,
"email": "admin@example.com"
}
```
### 📋 Требования
#### Linux
- certbot
- Python 3.6+
- pip3
- requests, cryptography (Python модули)
- certbot-dns-regru (опционально)
#### Windows
- certbot
- PowerShell 5.1+
- openssl (для проверки сертификатов)
### 🔄 Автоматическое обновление
#### Через cron (Linux)
```bash
## Добавьте в crontab
sudo crontab -e
## Проверка каждый день в 3:00
0 3 * * * /usr/bin/python3 /path/to/letsencrypt_regru_api.py -c /etc/letsencrypt/regru_config.json
```
#### Через Task Scheduler (Windows)
1. Откройте Task Scheduler
2. Создайте новую задачу
3. Триггер: Ежедневно в 3:00
4. Действие: Запуск PowerShell скрипта
### 📖 Функции
✅ Создание wildcard сертификатов (*.domain.com)
✅ Автоматическая DNS валидация через API reg.ru
✅ Проверка срока действия сертификата
✅ Автоматическое обновление перед истечением
✅ Перезагрузка веб-сервера после обновления
✅ Подробное логирование всех операций
### 🔧 Использование с Nginx Proxy Manager
После получения сертификата:
1. Войдите в NPM: http://192.0.2.1:81/
2. SSL Certificates → Add SSL Certificate → Custom
3. Вставьте содержимое:
- Certificate Key: `/etc/letsencrypt/live/domain.com/privkey.pem`
- Certificate: `/etc/letsencrypt/live/domain.com/fullchain.pem`
### 📝 Логи
- Bash: `/var/log/letsencrypt_regru.log`
- Python: `/var/log/letsencrypt_regru.log`
- PowerShell: `.\letsencrypt_regru.log`
- Certbot: `/var/log/letsencrypt/letsencrypt.log`
### 🆘 Устранение неполадок
#### Ошибка аутентификации API
- Проверьте учетные данные reg.ru
- Убедитесь, что домен под вашим управлением
#### DNS запись не распространяется
- Увеличьте `dns_propagation_wait` до 120 секунд
- Проверьте DNS: `nslookup -type=TXT _acme-challenge.domain.com`
#### Certbot не найден
```bash
## Ubuntu/Debian
sudo apt-get install certbot
## Или через snap
sudo snap install --classic certbot
```
### 📚 Документация
Подробная документация в файле [USAGE.md](USAGE.md)
### 🔐 Безопасность
- Храните учетные данные в безопасности
- Используйте `chmod 600` для конфигурационных файлов
- Регулярно обновляйте пароли
### ⚠️ Важно
- Let's Encrypt сертификаты действительны 90 дней
- Рекомендуется настроить автоматическое обновление
- Для wildcard сертификатов требуется DNS валидация
### 📞 Поддержка
- [Документация reg.ru API](https://www.reg.ru/support/api)
- [Документация Let's Encrypt](https://letsencrypt.org/docs/)
- [Certbot Documentation](https://certbot.eff.org/docs/)
### 📄 Лицензия
Скрипты предоставляются "как есть" для свободного использования.
---
**Успешной автоматизации! 🔒**
+482 -482
View File
@@ -1,482 +1,482 @@
# Установка
Есть два основных пути установки:
1) Автоустановщик `letsencrypt_regru.sh` (самый простой)
2) Установка через `Makefile` (контролируемый сценарий)
## Требования
- Linux (Debian/Ubuntu/CentOS/RHEL/Fedora)
- Root (запуск через `sudo`)
- Python 3.6+ (для исходников) или готовый бинарник
- certbot (системный)
- Доступ к API reg.ru (разрешённый IP, корректные учётные данные)
## Вариант A — автоустановщик (рекомендуется)
### Установка одной командой
- Через `curl`:
`sudo bash -c "$(curl -fsSL https://github.com/DFofanov/configure_nginx_manager/raw/refs/heads/master/letsencrypt_regru.sh)"`
### Что делает установщик
- Ставит зависимости
- Создаёт виртуальное окружение
- Помогает интерактивно собрать конфиг
- Настраивает systemd service/timer
- Добавляет глобальную команду `letsencrypt-regru`
## Вариант B — через Makefile
Типовой сценарий:
- `sudo make install`
- отредактировать конфиг (см. [Configuration](Configuration.md))
- `sudo make test-cert` (проверка без лимитов)
- `sudo make obtain` (production сертификат)
Полный список команд: [Commands](Commands.md).
## Где лежат файлы после установки
(типовая структура, может отличаться от ваших путей)
- Приложение: `/opt/letsencrypt-regru/`
- Конфиг: `/etc/letsencrypt/regru_config.json` (или `/etc/letsencrypt-regru/config.json` — зависит от сценария)
- Сертификаты: `/etc/letsencrypt/live/<domain>/`
- Логи: `/var/log/letsencrypt_regru.log` (или `/var/log/letsencrypt-regru/letsencrypt_regru.log`)
- systemd units: `/etc/systemd/system/letsencrypt-regru.service` и `.timer`
## Проверка после установки
- `letsencrypt-regru --help`
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
Если ловите ошибку `Access to API from this IP denied`, см. [RegRu_API_Troubleshooting](RegRu_API_Troubleshooting.md).
---
## Appendix (migrated from docs/INSTALL_GUIDE.md)
<!-- MIGRATED_FROM_DOCS:INSTALL_GUIDE.md -->
## Руководство по использованию letsencrypt_regru.sh
**Автор:** Фофанов Дмитрий
**Дата:** 28.10.2025
### Описание
`letsencrypt_regru.sh` - это автоматический установщик для Let's Encrypt Manager с интеграцией reg.ru и Nginx Proxy Manager.
Скрипт автоматизирует:
- Установку всех системных зависимостей
- Создание виртуального окружения Python
- Установку Python библиотек (requests, cryptography, certbot)
- Интерактивную настройку конфигурации
- Создание и настройку systemd сервисов
- Настройку автоматического обновления сертификатов
### Требования
- Linux (Debian/Ubuntu, CentOS/RHEL/Fedora)
- Root доступ (sudo)
- Минимум 512MB RAM
- Минимум 1GB свободного места на диске
- Интернет соединение
### Быстрая установка
**Способ 1: Автоматическая установка (рекомендуется)**
Самый быстрый способ - запустить установку напрямую с GitHub:
```bash
sudo bash -c "$(curl -fsSL https://github.com/DFofanov/configure_nginx_manager/raw/refs/heads/master/letsencrypt_regru.sh)"
```
Эта команда:
- Автоматически скачает установочный скрипт
- Запустит его с правами root
- Проведет через интерактивную настройку
**Способ 2: Через клонирование репозитория**
Если вы хотите изучить код перед установкой:
```bash
## 1. Скачайте репозиторий
git clone https://github.com/DFofanov/configure_nginx_manager.git
cd configure_nginx_manager
## 2. Дайте права на выполнение
chmod +x letsencrypt_regru.sh
## 3. Запустите установку
sudo ./letsencrypt_regru.sh
```
### Интерактивная настройка
Во время установки скрипт спросит:
1. **Домен** - ваш основной домен (например, `example.com`)
2. **Email** - для уведомлений Let's Encrypt
3. **Учетные данные reg.ru:**
- Имя пользователя
- Пароль
4. **Wildcard сертификат** - создавать ли `*.example.com` (рекомендуется: Да)
5. **Интеграция с NPM** (опционально):
- Адрес NPM (например, `http://10.10.10.14:81`)
- Email для входа в NPM
- Пароль NPM
### Структура после установки
```
/opt/letsencrypt-regru/ # Приложение
├── letsencrypt_regru_api.py # Основной скрипт
├── venv/ # Виртуальное окружение Python
└── (docs) # Документация — см. Wiki/README репозитория
/etc/letsencrypt-regru/ # Конфигурация
└── config.json # Настройки (credentials, домен, NPM)
/var/log/letsencrypt-regru/ # Логи
└── letsencrypt_regru.log
/etc/letsencrypt/live/ # Сертификаты Let's Encrypt
└── example.com/
├── privkey.pem
├── cert.pem
├── chain.pem
└── fullchain.pem
/etc/systemd/system/ # Systemd сервисы
├── letsencrypt-regru.service # Сервис обновления
└── letsencrypt-regru.timer # Таймер (каждые 12 часов)
/usr/local/bin/
└── letsencrypt-regru # Глобальная команда
```
### Использование команды letsencrypt-regru
После установки доступна удобная глобальная команда с множеством функций:
#### 🔧 Основные команды
```bash
## Проверить срок действия текущего сертификата
letsencrypt-regru --check
## Получить новый сертификат Let's Encrypt
letsencrypt-regru --obtain
## Обновить существующий сертификат
letsencrypt-regru --renew
## Автоматически проверить и обновить при необходимости
letsencrypt-regru --auto
## Создать тестовый самоподписанный сертификат
letsencrypt-regru --test-cert
```
#### 🧪 Команды диагностики и тестирования
```bash
## Проверить доступ к API reg.ru
## - Показывает текущий IP
## - Тестирует подключение к API
## - Отображает баланс аккаунта
letsencrypt-regru --test-api
## Тестовое создание DNS записи TXT
## - Полная симуляция процесса SSL сертификации
## - Создает временную TXT запись _acme-challenge
## - Ожидает распространения DNS (60 секунд)
## - Проверяет через публичные DNS серверы
## - Автоматически удаляет тестовую запись
letsencrypt-regru --test-dns
## Показать справку по всем командам
letsencrypt-regru --help
## Включить подробный вывод (verbose mode)
letsencrypt-regru --obtain -v
letsencrypt-regru --check -v
```
#### ⚙️ Служебные команды (внутреннее использование)
```bash
## Certbot authentication hook (используется certbot автоматически)
letsencrypt-regru --auth-hook
## Certbot cleanup hook (используется certbot автоматически)
letsencrypt-regru --cleanup-hook
```
#### 📋 Описание команд
| Команда | Описание | Использование |
|---------|----------|---------------|
| `--check` | Проверяет срок действия сертификата | Регулярная проверка |
| `--obtain` | Получает новый сертификат от Let's Encrypt | Первое создание |
| `--renew` | Обновляет существующий сертификат | Продление срока |
| `--auto` | Автоматическая проверка и обновление | Для cron/systemd |
| `--test-cert` | Создает тестовый самоподписанный сертификат | Разработка/тестирование |
| `--test-api` | Проверяет доступ к API reg.ru | Диагностика подключения |
| `--test-dns` | Тестирует создание DNS записи | Проверка перед SSL |
| `--auth-hook` | Hook для certbot (создание DNS) | Внутреннее |
| `--cleanup-hook` | Hook для certbot (удаление DNS) | Внутреннее |
| `--help` | Показывает справку | Помощь |
| `-v` | Подробный вывод | Отладка |
### Автоматическое обновление
Установщик настраивает systemd timer для автоматической проверки:
```bash
## Проверить статус таймера
systemctl status letsencrypt-regru.timer
## Когда следующий запуск
systemctl list-timers letsencrypt-regru.timer
## Посмотреть историю запусков
journalctl -u letsencrypt-regru
## Следить за логами в реальном времени
journalctl -u letsencrypt-regru -f
```
#### Настройки таймера
По умолчанию:
- Первый запуск: через 15 минут после загрузки системы
- Периодичность: каждые 12 часов
- Случайная задержка: до 1 часа (чтобы не создавать нагрузку)
Изменить можно в `/etc/systemd/system/letsencrypt-regru.timer`.
### Редактирование конфигурации
```bash
## Открыть конфигурацию в редакторе
sudo nano /etc/letsencrypt-regru/config.json
## После изменений перезапустите таймер
sudo systemctl restart letsencrypt-regru.timer
```
#### Пример config.json
```json
{
"regru_username": "your_username",
"regru_password": "your_password",
"domain": "example.com",
"wildcard": true,
"email": "admin@example.com",
"cert_dir": "/etc/letsencrypt/live",
"log_file": "/var/log/letsencrypt-regru/letsencrypt_regru.log",
"dns_propagation_wait": 180,
"dns_check_attempts": 20,
"dns_check_interval": 15,
"renewal_days": 30,
"npm_enabled": true,
"npm_host": "http://10.10.10.14:81",
"npm_email": "admin@npm.local",
"npm_password": "secure_password"
}
```
### Обновление приложения
```bash
## Скачайте последнюю версию
cd configure_nginx_manager
git pull
## Запустите обновление
sudo ./letsencrypt_regru.sh update
```
Обновление:
- Остановит таймер
- Обновит скрипт
- Обновит Python зависимости
- Перезапустит таймер
### Удаление
```bash
## Полное удаление приложения
sudo ./letsencrypt_regru.sh uninstall
```
Скрипт удалит:
- Приложение из `/opt/letsencrypt-regru/`
- Systemd сервисы
- Глобальную команду
Сертификаты в `/etc/letsencrypt/live/` сохраняются!
Опционально можно удалить:
- Конфигурацию `/etc/letsencrypt-regru/`
- Логи `/var/log/letsencrypt-regru/`
### Просмотр логов
```bash
## Логи systemd (рекомендуется)
journalctl -u letsencrypt-regru -f
## Файл лога
tail -f /var/log/letsencrypt-regru/letsencrypt_regru.log
## Последние 100 строк
tail -n 100 /var/log/letsencrypt-regru/letsencrypt_regru.log
```
### Устранение проблем
#### Проверка установки
```bash
## Проверить наличие команды
which letsencrypt-regru
## Проверить Python окружение
ls -la /opt/letsencrypt-regru/venv/
## Проверить systemd сервисы
systemctl list-unit-files | grep letsencrypt-regru
```
#### Ошибки при установке
**Ошибка: "Permission denied"**
```bash
## Запустите с sudo
sudo ./letsencrypt_regru.sh
```
**Ошибка: "Package not found"**
```bash
## Обновите списки пакетов
sudo apt-get update # Debian/Ubuntu
sudo yum update # CentOS/RHEL
```
**Ошибка: "Python module not found"**
```bash
## Переустановите виртуальное окружение
sudo rm -rf /opt/letsencrypt-regru/venv
sudo ./letsencrypt_regru.sh
```
#### Проблемы с сертификатами
**Сертификат не создается**
```bash
## Проверьте логи
tail -n 50 /var/log/letsencrypt-regru/letsencrypt_regru.log
## Проверьте конфигурацию
cat /etc/letsencrypt-regru/config.json
## Попробуйте вручную
letsencrypt-regru --obtain -v
```
**DNS не обновляется**
```bash
## Увеличьте время ожидания в config.json
"dns_propagation_wait": 180,
"dns_check_attempts": 20
```
#### Проблемы с NPM
**Не загружается в NPM**
```bash
## Проверьте доступность NPM
curl http://192.0.2.1:81
## Проверьте учетные данные в config.json
## Попробуйте вручную
letsencrypt-regru --test-cert -v
```
### Поддерживаемые ОС
✅ Debian 10, 11, 12
✅ Ubuntu 20.04, 22.04, 24.04
✅ CentOS 7, 8
✅ RHEL 7, 8, 9
✅ Fedora 35+
### Дополнительные возможности
#### Тестовый сертификат
Для тестирования без лимитов Let's Encrypt:
```bash
letsencrypt-regru --test-cert
```
Создаст самоподписанный сертификат на 90 дней.
#### Ручной запуск обновления
```bash
## Запустить сервис вручную
sudo systemctl start letsencrypt-regru.service
## Посмотреть статус
systemctl status letsencrypt-regru.service
```
#### Изменить периодичность проверки
Отредактируйте `/etc/systemd/system/letsencrypt-regru.timer`:
```ini
[Timer]
## Каждые 6 часов вместо 12
OnUnitActiveSec=6h
```
Затем:
```bash
sudo systemctl daemon-reload
sudo systemctl restart letsencrypt-regru.timer
```
### Безопасность
- Конфигурация с паролями имеет права `600` (только root)
- Приватные ключи сертификатов имеют права `600`
- Все операции выполняются от root
- Логи доступны только root
### Поддержка
- GitHub Issues: https://github.com/YOUR_USERNAME/configure_nginx_manager/issues
- Документация: Wiki/README в этом репозитории
- Email: admin@example.com
---
**Разработано:** Фофанов Дмитрий
**Дата:** 28.10.2025
**Версия:** 2.0
# Установка
Есть два основных пути установки:
1) Автоустановщик `letsencrypt_regru.sh` (самый простой)
2) Установка через `Makefile` (контролируемый сценарий)
## Требования
- Linux (Debian/Ubuntu/CentOS/RHEL/Fedora)
- Root (запуск через `sudo`)
- Python 3.6+ (для исходников) или готовый бинарник
- certbot (системный)
- Доступ к API reg.ru (разрешённый IP, корректные учётные данные)
## Вариант A — автоустановщик (рекомендуется)
### Установка одной командой
- Через `curl`:
`sudo bash -c "$(curl -fsSL https://github.com/DFofanov/configure_nginx_manager/raw/refs/heads/master/letsencrypt_regru.sh)"`
### Что делает установщик
- Ставит зависимости
- Создаёт виртуальное окружение
- Помогает интерактивно собрать конфиг
- Настраивает systemd service/timer
- Добавляет глобальную команду `letsencrypt-regru`
## Вариант B — через Makefile
Типовой сценарий:
- `sudo make install`
- отредактировать конфиг (см. [Configuration](Configuration.md))
- `sudo make test-cert` (проверка без лимитов)
- `sudo make obtain` (production сертификат)
Полный список команд: [Commands](Commands.md).
## Где лежат файлы после установки
(типовая структура, может отличаться от ваших путей)
- Приложение: `/opt/letsencrypt-regru/`
- Конфиг: `/etc/letsencrypt/regru_config.json` (или `/etc/letsencrypt-regru/config.json` — зависит от сценария)
- Сертификаты: `/etc/letsencrypt/live/<domain>/`
- Логи: `/var/log/letsencrypt_regru.log` (или `/var/log/letsencrypt-regru/letsencrypt_regru.log`)
- systemd units: `/etc/systemd/system/letsencrypt-regru.service` и `.timer`
## Проверка после установки
- `letsencrypt-regru --help`
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
Если ловите ошибку `Access to API from this IP denied`, см. [RegRu_API_Troubleshooting](RegRu_API_Troubleshooting.md).
---
## Appendix (migrated from docs/INSTALL_GUIDE.md)
<!-- MIGRATED_FROM_DOCS:INSTALL_GUIDE.md -->
## Руководство по использованию letsencrypt_regru.sh
**Автор:** Фофанов Дмитрий
**Дата:** 28.10.2025
### Описание
`letsencrypt_regru.sh` - это автоматический установщик для Let's Encrypt Manager с интеграцией reg.ru и Nginx Proxy Manager.
Скрипт автоматизирует:
- Установку всех системных зависимостей
- Создание виртуального окружения Python
- Установку Python библиотек (requests, cryptography, certbot)
- Интерактивную настройку конфигурации
- Создание и настройку systemd сервисов
- Настройку автоматического обновления сертификатов
### Требования
- Linux (Debian/Ubuntu, CentOS/RHEL/Fedora)
- Root доступ (sudo)
- Минимум 512MB RAM
- Минимум 1GB свободного места на диске
- Интернет соединение
### Быстрая установка
**Способ 1: Автоматическая установка (рекомендуется)**
Самый быстрый способ - запустить установку напрямую с GitHub:
```bash
sudo bash -c "$(curl -fsSL https://github.com/DFofanov/configure_nginx_manager/raw/refs/heads/master/letsencrypt_regru.sh)"
```
Эта команда:
- Автоматически скачает установочный скрипт
- Запустит его с правами root
- Проведет через интерактивную настройку
**Способ 2: Через клонирование репозитория**
Если вы хотите изучить код перед установкой:
```bash
## 1. Скачайте репозиторий
git clone https://github.com/DFofanov/configure_nginx_manager.git
cd configure_nginx_manager
## 2. Дайте права на выполнение
chmod +x letsencrypt_regru.sh
## 3. Запустите установку
sudo ./letsencrypt_regru.sh
```
### Интерактивная настройка
Во время установки скрипт спросит:
1. **Домен** - ваш основной домен (например, `example.com`)
2. **Email** - для уведомлений Let's Encrypt
3. **Учетные данные reg.ru:**
- Имя пользователя
- Пароль
4. **Wildcard сертификат** - создавать ли `*.example.com` (рекомендуется: Да)
5. **Интеграция с NPM** (опционально):
- Адрес NPM (например, `http://10.10.10.14:81`)
- Email для входа в NPM
- Пароль NPM
### Структура после установки
```
/opt/letsencrypt-regru/ # Приложение
├── letsencrypt_regru_api.py # Основной скрипт
├── venv/ # Виртуальное окружение Python
└── (docs) # Документация — см. Wiki/README репозитория
/etc/letsencrypt-regru/ # Конфигурация
└── config.json # Настройки (credentials, домен, NPM)
/var/log/letsencrypt-regru/ # Логи
└── letsencrypt_regru.log
/etc/letsencrypt/live/ # Сертификаты Let's Encrypt
└── example.com/
├── privkey.pem
├── cert.pem
├── chain.pem
└── fullchain.pem
/etc/systemd/system/ # Systemd сервисы
├── letsencrypt-regru.service # Сервис обновления
└── letsencrypt-regru.timer # Таймер (каждые 12 часов)
/usr/local/bin/
└── letsencrypt-regru # Глобальная команда
```
### Использование команды letsencrypt-regru
После установки доступна удобная глобальная команда с множеством функций:
#### 🔧 Основные команды
```bash
## Проверить срок действия текущего сертификата
letsencrypt-regru --check
## Получить новый сертификат Let's Encrypt
letsencrypt-regru --obtain
## Обновить существующий сертификат
letsencrypt-regru --renew
## Автоматически проверить и обновить при необходимости
letsencrypt-regru --auto
## Создать тестовый самоподписанный сертификат
letsencrypt-regru --test-cert
```
#### 🧪 Команды диагностики и тестирования
```bash
## Проверить доступ к API reg.ru
## - Показывает текущий IP
## - Тестирует подключение к API
## - Отображает баланс аккаунта
letsencrypt-regru --test-api
## Тестовое создание DNS записи TXT
## - Полная симуляция процесса SSL сертификации
## - Создает временную TXT запись _acme-challenge
## - Ожидает распространения DNS (60 секунд)
## - Проверяет через публичные DNS серверы
## - Автоматически удаляет тестовую запись
letsencrypt-regru --test-dns
## Показать справку по всем командам
letsencrypt-regru --help
## Включить подробный вывод (verbose mode)
letsencrypt-regru --obtain -v
letsencrypt-regru --check -v
```
#### ⚙️ Служебные команды (внутреннее использование)
```bash
## Certbot authentication hook (используется certbot автоматически)
letsencrypt-regru --auth-hook
## Certbot cleanup hook (используется certbot автоматически)
letsencrypt-regru --cleanup-hook
```
#### 📋 Описание команд
| Команда | Описание | Использование |
|---------|----------|---------------|
| `--check` | Проверяет срок действия сертификата | Регулярная проверка |
| `--obtain` | Получает новый сертификат от Let's Encrypt | Первое создание |
| `--renew` | Обновляет существующий сертификат | Продление срока |
| `--auto` | Автоматическая проверка и обновление | Для cron/systemd |
| `--test-cert` | Создает тестовый самоподписанный сертификат | Разработка/тестирование |
| `--test-api` | Проверяет доступ к API reg.ru | Диагностика подключения |
| `--test-dns` | Тестирует создание DNS записи | Проверка перед SSL |
| `--auth-hook` | Hook для certbot (создание DNS) | Внутреннее |
| `--cleanup-hook` | Hook для certbot (удаление DNS) | Внутреннее |
| `--help` | Показывает справку | Помощь |
| `-v` | Подробный вывод | Отладка |
### Автоматическое обновление
Установщик настраивает systemd timer для автоматической проверки:
```bash
## Проверить статус таймера
systemctl status letsencrypt-regru.timer
## Когда следующий запуск
systemctl list-timers letsencrypt-regru.timer
## Посмотреть историю запусков
journalctl -u letsencrypt-regru
## Следить за логами в реальном времени
journalctl -u letsencrypt-regru -f
```
#### Настройки таймера
По умолчанию:
- Первый запуск: через 15 минут после загрузки системы
- Периодичность: каждые 12 часов
- Случайная задержка: до 1 часа (чтобы не создавать нагрузку)
Изменить можно в `/etc/systemd/system/letsencrypt-regru.timer`.
### Редактирование конфигурации
```bash
## Открыть конфигурацию в редакторе
sudo nano /etc/letsencrypt-regru/config.json
## После изменений перезапустите таймер
sudo systemctl restart letsencrypt-regru.timer
```
#### Пример config.json
```json
{
"regru_username": "your_username",
"regru_password": "your_password",
"domain": "example.com",
"wildcard": true,
"email": "admin@example.com",
"cert_dir": "/etc/letsencrypt/live",
"log_file": "/var/log/letsencrypt-regru/letsencrypt_regru.log",
"dns_propagation_wait": 180,
"dns_check_attempts": 20,
"dns_check_interval": 15,
"renewal_days": 30,
"npm_enabled": true,
"npm_host": "http://10.10.10.14:81",
"npm_email": "admin@npm.local",
"npm_password": "secure_password"
}
```
### Обновление приложения
```bash
## Скачайте последнюю версию
cd configure_nginx_manager
git pull
## Запустите обновление
sudo ./letsencrypt_regru.sh update
```
Обновление:
- Остановит таймер
- Обновит скрипт
- Обновит Python зависимости
- Перезапустит таймер
### Удаление
```bash
## Полное удаление приложения
sudo ./letsencrypt_regru.sh uninstall
```
Скрипт удалит:
- Приложение из `/opt/letsencrypt-regru/`
- Systemd сервисы
- Глобальную команду
Сертификаты в `/etc/letsencrypt/live/` сохраняются!
Опционально можно удалить:
- Конфигурацию `/etc/letsencrypt-regru/`
- Логи `/var/log/letsencrypt-regru/`
### Просмотр логов
```bash
## Логи systemd (рекомендуется)
journalctl -u letsencrypt-regru -f
## Файл лога
tail -f /var/log/letsencrypt-regru/letsencrypt_regru.log
## Последние 100 строк
tail -n 100 /var/log/letsencrypt-regru/letsencrypt_regru.log
```
### Устранение проблем
#### Проверка установки
```bash
## Проверить наличие команды
which letsencrypt-regru
## Проверить Python окружение
ls -la /opt/letsencrypt-regru/venv/
## Проверить systemd сервисы
systemctl list-unit-files | grep letsencrypt-regru
```
#### Ошибки при установке
**Ошибка: "Permission denied"**
```bash
## Запустите с sudo
sudo ./letsencrypt_regru.sh
```
**Ошибка: "Package not found"**
```bash
## Обновите списки пакетов
sudo apt-get update # Debian/Ubuntu
sudo yum update # CentOS/RHEL
```
**Ошибка: "Python module not found"**
```bash
## Переустановите виртуальное окружение
sudo rm -rf /opt/letsencrypt-regru/venv
sudo ./letsencrypt_regru.sh
```
#### Проблемы с сертификатами
**Сертификат не создается**
```bash
## Проверьте логи
tail -n 50 /var/log/letsencrypt-regru/letsencrypt_regru.log
## Проверьте конфигурацию
cat /etc/letsencrypt-regru/config.json
## Попробуйте вручную
letsencrypt-regru --obtain -v
```
**DNS не обновляется**
```bash
## Увеличьте время ожидания в config.json
"dns_propagation_wait": 180,
"dns_check_attempts": 20
```
#### Проблемы с NPM
**Не загружается в NPM**
```bash
## Проверьте доступность NPM
curl http://192.0.2.1:81
## Проверьте учетные данные в config.json
## Попробуйте вручную
letsencrypt-regru --test-cert -v
```
### Поддерживаемые ОС
✅ Debian 10, 11, 12
✅ Ubuntu 20.04, 22.04, 24.04
✅ CentOS 7, 8
✅ RHEL 7, 8, 9
✅ Fedora 35+
### Дополнительные возможности
#### Тестовый сертификат
Для тестирования без лимитов Let's Encrypt:
```bash
letsencrypt-regru --test-cert
```
Создаст самоподписанный сертификат на 90 дней.
#### Ручной запуск обновления
```bash
## Запустить сервис вручную
sudo systemctl start letsencrypt-regru.service
## Посмотреть статус
systemctl status letsencrypt-regru.service
```
#### Изменить периодичность проверки
Отредактируйте `/etc/systemd/system/letsencrypt-regru.timer`:
```ini
[Timer]
## Каждые 6 часов вместо 12
OnUnitActiveSec=6h
```
Затем:
```bash
sudo systemctl daemon-reload
sudo systemctl restart letsencrypt-regru.timer
```
### Безопасность
- Конфигурация с паролями имеет права `600` (только root)
- Приватные ключи сертификатов имеют права `600`
- Все операции выполняются от root
- Логи доступны только root
### Поддержка
- GitHub Issues: https://github.com/YOUR_USERNAME/configure_nginx_manager/issues
- Документация: Wiki/README в этом репозитории
- Email: admin@example.com
---
**Разработано:** Фофанов Дмитрий
**Дата:** 28.10.2025
**Версия:** 2.0
+207 -207
View File
@@ -1,67 +1,67 @@
# Алгоритм получения и продления сертификата
Эта страница описывает реальный алгоритм работы скрипта (по документации и текущему коду).
## Получение сертификата (production / staging)
Команды:
- production: `--obtain`
- staging: `--staging`
Шаги:
1) Проверка наличия certbot
2) Формирование списка доменов для certbot:
- всегда: `<domain>`
- если `wildcard=true`: `*.<domain>`
3) Запуск `certbot certonly --manual --preferred-challenges dns`
4) Certbot вызывает hook'и:
- auth-hook: добавляет TXT запись `_acme-challenge` через API reg.ru
- cleanup-hook: удаляет TXT запись
5) После успеха сертификаты появляются в `cert_dir/<domain>/`:
- `privkey.pem`, `cert.pem`, `chain.pem`, `fullchain.pem`
6) (опционально) синхронизация в NPM
7) (опционально) перезагрузка веб-сервиса (nginx/apache)
### Про TXT для поддоменов
Если вы выпускаете сертификат для поддомена вида `pages.github.example.com`, TXT должен создаваться в зоне зарегистрированного домена `example.com` как:
- `_acme-challenge.pages.github.example.com`
Скрипт учитывает это, выбирая зарегистрированный домен по списку доменов в конфиге.
## Продление сертификата
Команда:
- `--renew`
Скрипт запускает `certbot renew` для конкретного `--cert-name <domain>` и использует те же hook'и (auth/cleanup) с корректным `--config`.
## Авто-режим
Команда:
- `--auto`
Логика по каждому домену из конфига:
- если сертификата нет → получить новый
- если срок меньше `renewal_days` → продлить
- иначе → ничего не делать (опционально проверить наличие в NPM)
Возврат кода:
- `0` — всё успешно
- `1` — были ошибки
## Где смотреть логи
- Логи скрипта: путь `log_file` из конфига
- Логи certbot: обычно `/var/log/letsencrypt/letsencrypt.log`
- systemd: `journalctl -u letsencrypt-regru -f`
# Алгоритм получения и продления сертификата
Эта страница описывает реальный алгоритм работы скрипта (по документации и текущему коду).
## Получение сертификата (production / staging)
Команды:
- production: `--obtain`
- staging: `--staging`
Шаги:
1) Проверка наличия certbot
2) Формирование списка доменов для certbot:
- всегда: `<domain>`
- если `wildcard=true`: `*.<domain>`
3) Запуск `certbot certonly --manual --preferred-challenges dns`
4) Certbot вызывает hook'и:
- auth-hook: добавляет TXT запись `_acme-challenge` через API reg.ru
- cleanup-hook: удаляет TXT запись
5) После успеха сертификаты появляются в `cert_dir/<domain>/`:
- `privkey.pem`, `cert.pem`, `chain.pem`, `fullchain.pem`
6) (опционально) синхронизация в NPM
7) (опционально) перезагрузка веб-сервиса (nginx/apache)
### Про TXT для поддоменов
Если вы выпускаете сертификат для поддомена вида `pages.github.example.com`, TXT должен создаваться в зоне зарегистрированного домена `example.com` как:
- `_acme-challenge.pages.github.example.com`
Скрипт учитывает это, выбирая зарегистрированный домен по списку доменов в конфиге.
## Продление сертификата
Команда:
- `--renew`
Скрипт запускает `certbot renew` для конкретного `--cert-name <domain>` и использует те же hook'и (auth/cleanup) с корректным `--config`.
## Авто-режим
Команда:
- `--auto`
Логика по каждому домену из конфига:
- если сертификата нет → получить новый
- если срок меньше `renewal_days` → продлить
- иначе → ничего не делать (опционально проверить наличие в NPM)
Возврат кода:
- `0` — всё успешно
- `1` — были ошибки
## Где смотреть логи
- Логи скрипта: путь `log_file` из конфига
- Логи certbot: обычно `/var/log/letsencrypt/letsencrypt.log`
- systemd: `journalctl -u letsencrypt-regru -f`
---
@@ -69,92 +69,92 @@
## Appendix (migrated from: Создание и продление SSL сертификата)
<!-- MIGRATED_FROM_DOCS: Создание и продление SSL сертификата -->
## Инструкция по созданию wildcard сертификата *.example.com в Nginx Proxy Manager и настройке автоматического продления SSL
---
### Шаг 1. Подготовка
- Убедитесь, что Nginx Proxy Manager (NPM) установлен и доступен по адресу http://192.0.2.1:81/
- У вас есть доступ к DNS записям домена example.com в панели управления reg.ru или у другого регистратора
---
### Шаг 2. Создание Wildcard SSL сертификата в Nginx Proxy Manager
1. Войдите в админку Nginx Proxy Manager по адресу http://192.0.2.1:81/
2. Перейдите в раздел **SSL Certificates** → нажмите кнопку **Add SSL Certificate**
3. Выберите пункт **Let's Encrypt**
4. Заполните поля:
- **Domain Names:**
Введите `*.example.com` — для wildcard сертификата
Также рекомендуется добавить основной домен `example.com` (через запятую или в новом поле)
- **Email Address:**
Укажите ваш Email для уведомлений от Let's Encrypt (обязательно)
- **HTTP Challenge:**
Оставьте проверку HTTP, если NPM доступен из интернета по порту 80 и 443, или настройте DNS Challenge если поддерживается вашим DNS
5. Отметьте галочку "Agree to the Let's Encrypt Terms of Service"
6. Нажмите **Save**
- NPM начнёт процесс получения сертификата с проверкой домена.
- При успешном запросе сертификата вы увидите новый сертификат в списке.
---
### Шаг 3. Настройка автоматического продления
- Nginx Proxy Manager автоматически заботится о продлении сертификатов Let's Encrypt.
- Для этого сервер должен быть доступен из интернета по портам 80 и 443, и DNS записи правильно указывать на ваш сервер.
- NPM периодически (обычно за 30 дней до окончания) запрашивает обновление сертификата.
- В случае использования DNS Challenge необходимо чтобы в NPM была настроена интеграция с DNS провайдером (если поддерживается).
---
### Шаг 4. Использование wildcard сертификата в Proxy Hosts
1. Перейдите в **Proxy Hosts** → Создайте или отредактируйте запись прокси
2. В поле **Domain Names** укажите нужный поддомен из example.com, например:
`api.example.com` или `www.example.com`
3. В разделе **SSL** выберите ваш wildcard сертификат `*.example.com`, который вы получили на шаге 2
4. Включите опции:
- Use SSL
- Force SSL
- HSTS (при необходимости)
5. Сохраните изменения.
---
### Шаг 5. Проверка
1. Проверьте, что для всех поддоменов используется единый сертификат
2. Посетите https://api.example.com или другие поддомены из браузера
3. Убедитесь, что сертификат валиден, не просрочен и выдан на *.example.com
4. Проверяйте в разделе SSL Certificates статус продления сертификата
---
### Дополнительно
- Если Let's Encrypt не может выполнить HTTP Challenge из-за закрытого порта, настройте DNS Challenge (может потребоваться ключ API DNS провайдера)
- Для безопасности и уведомлений держите Email в актуальном состоянии
- Проверяйте логи Nginx Proxy Manager для выявления ошибок продления
---
## Итог
Nginx Proxy Manager позволяет легко получать и автоматически обновлять wildcard SSL сертификаты для домена *.example.com с помощью Let's Encrypt.
Главное — правильно настроить DNS записи и обеспечить интернет доступ на HTTP/HTTPS порты.
Далее используйте один глобальный сертификат для всех ваших поддоменов через настройки Proxy Hosts.
## Инструкция по созданию wildcard сертификата *.example.com в Nginx Proxy Manager и настройке автоматического продления SSL
---
### Шаг 1. Подготовка
- Убедитесь, что Nginx Proxy Manager (NPM) установлен и доступен по адресу http://192.0.2.1:81/
- У вас есть доступ к DNS записям домена example.com в панели управления reg.ru или у другого регистратора
---
### Шаг 2. Создание Wildcard SSL сертификата в Nginx Proxy Manager
1. Войдите в админку Nginx Proxy Manager по адресу http://192.0.2.1:81/
2. Перейдите в раздел **SSL Certificates** → нажмите кнопку **Add SSL Certificate**
3. Выберите пункт **Let's Encrypt**
4. Заполните поля:
- **Domain Names:**
Введите `*.example.com` — для wildcard сертификата
Также рекомендуется добавить основной домен `example.com` (через запятую или в новом поле)
- **Email Address:**
Укажите ваш Email для уведомлений от Let's Encrypt (обязательно)
- **HTTP Challenge:**
Оставьте проверку HTTP, если NPM доступен из интернета по порту 80 и 443, или настройте DNS Challenge если поддерживается вашим DNS
5. Отметьте галочку "Agree to the Let's Encrypt Terms of Service"
6. Нажмите **Save**
- NPM начнёт процесс получения сертификата с проверкой домена.
- При успешном запросе сертификата вы увидите новый сертификат в списке.
---
### Шаг 3. Настройка автоматического продления
- Nginx Proxy Manager автоматически заботится о продлении сертификатов Let's Encrypt.
- Для этого сервер должен быть доступен из интернета по портам 80 и 443, и DNS записи правильно указывать на ваш сервер.
- NPM периодически (обычно за 30 дней до окончания) запрашивает обновление сертификата.
- В случае использования DNS Challenge необходимо чтобы в NPM была настроена интеграция с DNS провайдером (если поддерживается).
---
### Шаг 4. Использование wildcard сертификата в Proxy Hosts
1. Перейдите в **Proxy Hosts** → Создайте или отредактируйте запись прокси
2. В поле **Domain Names** укажите нужный поддомен из example.com, например:
`api.example.com` или `www.example.com`
3. В разделе **SSL** выберите ваш wildcard сертификат `*.example.com`, который вы получили на шаге 2
4. Включите опции:
- Use SSL
- Force SSL
- HSTS (при необходимости)
5. Сохраните изменения.
---
### Шаг 5. Проверка
1. Проверьте, что для всех поддоменов используется единый сертификат
2. Посетите https://api.example.com или другие поддомены из браузера
3. Убедитесь, что сертификат валиден, не просрочен и выдан на *.example.com
4. Проверяйте в разделе SSL Certificates статус продления сертификата
---
### Дополнительно
- Если Let's Encrypt не может выполнить HTTP Challenge из-за закрытого порта, настройте DNS Challenge (может потребоваться ключ API DNS провайдера)
- Для безопасности и уведомлений держите Email в актуальном состоянии
- Проверяйте логи Nginx Proxy Manager для выявления ошибок продления
---
## Итог
Nginx Proxy Manager позволяет легко получать и автоматически обновлять wildcard SSL сертификаты для домена *.example.com с помощью Let's Encrypt.
Главное — правильно настроить DNS записи и обеспечить интернет доступ на HTTP/HTTPS порты.
Далее используйте один глобальный сертификат для всех ваших поддоменов через настройки Proxy Hosts.
---
@@ -162,60 +162,60 @@ Nginx Proxy Manager позволяет легко получать и автом
## Appendix (migrated from docs/Add Let's Encrypt Certificate для провайдера reg.ru.md)
<!-- MIGRATED_FROM_DOCS:Add Let's Encrypt Certificate для провайдера reg.ru.md -->
## Инструкция по созданию Let's Encrypt сертификата с DNS Challenge для провайдера reg.ru в Nginx Proxy Manager
---
### Предпосылки
- Доступ к Nginx Proxy Manager (NPM)
- Доступ к аккаунту reg.ru с правами управления DNS записями
- API ключ для управления DNS в reg.ru (если есть автоматическая интеграция)
- Нужно получить сертификат для `*.example.com` (wildcard сертификат)
---
### Шаг 1. Получение API ключа для reg.ru
1. Войдите в панель управления reg.ru
2. Перейдите в раздел управления API (если поддерживается)
3. Создайте или найдите API ключ с правом редактирования DNS записей
4. Сохраните API ключ и секрет (Client ID и API Token)
---
### Шаг 2. Настройка Nginx Proxy Manager для использования DNS Challenge reg.ru
1. В админке NPM перейдите в **SSL Certificates → Add SSL Certificate**
2. Выберите **Let's Encrypt** -> **DNS Challenge**
3. В поле **Provider** выберите `reg_ru` или `custom` (если провайдера нет, потребуется писать скрипт)
4. В поля API впишите необходимые параметры:
- Client ID
- API Token
5. В поле **Domain Names** укажите:
`*.example.com` (для wildcard сертификата)
и основной домен `example.com`
6. Включите остальные опции (Terms of Service, Email)
7. Нажмите **Save** для запроса сертификата
8. NPM автоматически добавит DNS TXT записи для подтверждения владения доменом через API reg.ru
---
### Шаг 3. Проверка и автоматическое продление
- После успешного создания сертификата NPM будет автоматически обновлять его через DNS Challenge.
- Для успешного продления важно, чтобы API ключ был действующим, а NPM имел доступ к DNS управлению.
---
### Если в NPM нет готовой интеграции с reg.ru
- Используйте внешний скрипт для обновления TXT записей DNS в reg.ru, настраиваемый в NPM через **Custom DNS Provider**.
- Нужна настройка curl запросов к API reg.ru для добавления/удаления TXT записей.
---
## Итог
Для wildcard сертификатов Let's Encrypt у reg.ru необходимо использовать DNS Challenge, используя API провайдера для автоматического управления DNS записями.
В Nginx Proxy Manager настройте DNS Challenge с учётом особенностей reg.ru для бесшовного получения и продления сертификатов.
## Инструкция по созданию Let's Encrypt сертификата с DNS Challenge для провайдера reg.ru в Nginx Proxy Manager
---
### Предпосылки
- Доступ к Nginx Proxy Manager (NPM)
- Доступ к аккаунту reg.ru с правами управления DNS записями
- API ключ для управления DNS в reg.ru (если есть автоматическая интеграция)
- Нужно получить сертификат для `*.example.com` (wildcard сертификат)
---
### Шаг 1. Получение API ключа для reg.ru
1. Войдите в панель управления reg.ru
2. Перейдите в раздел управления API (если поддерживается)
3. Создайте или найдите API ключ с правом редактирования DNS записей
4. Сохраните API ключ и секрет (Client ID и API Token)
---
### Шаг 2. Настройка Nginx Proxy Manager для использования DNS Challenge reg.ru
1. В админке NPM перейдите в **SSL Certificates → Add SSL Certificate**
2. Выберите **Let's Encrypt** -> **DNS Challenge**
3. В поле **Provider** выберите `reg_ru` или `custom` (если провайдера нет, потребуется писать скрипт)
4. В поля API впишите необходимые параметры:
- Client ID
- API Token
5. В поле **Domain Names** укажите:
`*.example.com` (для wildcard сертификата)
и основной домен `example.com`
6. Включите остальные опции (Terms of Service, Email)
7. Нажмите **Save** для запроса сертификата
8. NPM автоматически добавит DNS TXT записи для подтверждения владения доменом через API reg.ru
---
### Шаг 3. Проверка и автоматическое продление
- После успешного создания сертификата NPM будет автоматически обновлять его через DNS Challenge.
- Для успешного продления важно, чтобы API ключ был действующим, а NPM имел доступ к DNS управлению.
---
### Если в NPM нет готовой интеграции с reg.ru
- Используйте внешний скрипт для обновления TXT записей DNS в reg.ru, настраиваемый в NPM через **Custom DNS Provider**.
- Нужна настройка curl запросов к API reg.ru для добавления/удаления TXT записей.
---
## Итог
Для wildcard сертификатов Let's Encrypt у reg.ru необходимо использовать DNS Challenge, используя API провайдера для автоматического управления DNS записями.
В Nginx Proxy Manager настройте DNS Challenge с учётом особенностей reg.ru для бесшовного получения и продления сертификатов.
+199 -199
View File
@@ -1,199 +1,199 @@
# Интеграция с Nginx Proxy Manager (NPM)
Проект умеет автоматически загружать (или обновлять) сертификаты в NPM через его API.
## Включение
В конфиге:
- `npm_enabled: true`
- `npm_host`: например `http://192.0.2.1:81`
- `npm_email`, `npm_password`
После этого:
- `--obtain`, `--renew`, `--auto`, `--test-cert` будут пытаться синхронизировать сертификат в NPM.
## Как работает синхронизация
1) Скрипт логинится в NPM (`/api/tokens`)
2) Получает список сертификатов
3) Ищет сертификат по домену (учитывает `<domain>` и `*.<domain>`)
4) Если найден — обновляет, иначе — загружает новый
### Про “дубликаты” сертификатов
Иногда NPM сразу после загрузки ещё не распарсил домены (поле `domain_names` пустое). Скрипт дополнительно пытается сопоставлять по `nice_name`, чтобы не плодить дубли.
Команда для диагностики:
- `--list-npm` — показывает сертификаты и подсвечивает дубликаты
- `--delete-npm <ID>` — удаляет сертификат по ID
## Ручная загрузка существующего сертификата
- `--upload-npm <DOMAIN>`
Скрипт возьмёт `fullchain.pem` и `privkey.pem` из `cert_dir/<DOMAIN>/` и загрузит/обновит сертификат в NPM.
## Один wildcard сертификат на много поддоменов
Практический сценарий:
- Получить сертификат на `example.com` + `*.example.com`
- В NPM импортировать/использовать этот сертификат для всех Proxy Hosts
Обратите внимание:
- для wildcard Lets Encrypt нужен DNS-01 challenge
- в NPM можно использовать либо встроенный Lets Encrypt, либо этот проект как внешний менеджер и синхронизатор
## Пошагово: использовать один wildcard сертификат для всех Proxy Hosts
Ниже — практический сценарий, когда вам нужен один сертификат (например, `*.example.com`) и вы хотите назначать его на все хосты.
### Вариант A: сертификат выдаёт этот проект (рекомендуется при reg.ru DNS-01)
1) Убедитесь, что DNS API reg.ru работает:
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
2) Получите production сертификат:
- `letsencrypt-regru --obtain`
3) Если `npm_enabled=true`, сертификат автоматически появится в NPM.
4) В NPM:
- Proxy Hosts → Add/Edit Proxy Host
- SSL → выберите сертификат (обычно “Custom/Other”)
- включите нужные опции (Force SSL, HSTS по необходимости)
### Вариант B: сертификат выдаёт сам NPM
Этот вариант подходит, если NPM может сам пройти challenge.
1) SSL Certificates → Add SSL Certificate → Lets Encrypt
2) Domain Names: добавьте `example.com` и `*.example.com`
3) Выберите challenge:
- HTTP-01: требует доступности NPM из интернета по 80/443 и корректных A/AAAA записей
- DNS-01: требует поддерживаемого DNS provider в NPM
Если нужного DNS провайдера нет (или нет корректной интеграции для reg.ru), проще использовать этот проект как внешний DNS-01 менеджер.
### Вариант C: импорт уже существующего wildcard сертификата (Custom)
Если вы приобрели wildcard сертификат у CA или получили его другим способом:
1) SSL Certificates → Add SSL Certificate → Custom
2) Вставьте:
- Certificate: сертификат + intermediate chain (если отдельно — добавьте подряд)
- Key: приватный ключ
3) Сохраните и назначайте этот сертификат на Proxy Hosts.
## DNS записи для wildcard
Для проксирования поддоменов часто достаточно, чтобы DNS указывал на NPM:
- `example.com` → IP NPM
- `*.example.com` → IP NPM
Точная схема зависит от вашей инфраструктуры.
## Траблшутинг
- “не логинится” → проверьте `npm_host` (http/https), креды, доступность
- “сертификат не появился” → проверьте `npm_enabled`, логи скрипта
- staging сертификаты: не предназначены для production (браузер не доверяет)
---
## Appendix (migrated from: Настройке Nginx Manager с SSL)
<!-- MIGRATED_FROM_DOCS: Настройке Nginx Manager с SSL -->
## Подробная инструкция по настройке Nginx Proxy Manager с одним глобальным SSL сертификатом для всех доменов example.com
### Предпосылки
- Установлен и запущен [Nginx Proxy Manager](http://192.0.2.1:81/)
- Основной домен: example.com
- Хостинг и DNS записи домена находятся на reg.ru
- Нужно использовать один SSL сертификат (например, wildcard) для всех поддоменов example.com
---
### Шаг 1. Покупка и получение SSL Wildcard сертификата для example.com
1. На reg.ru или любом другом удостоверяющем центре (CA) закажите wildcard сертификат на домен вида `*.example.com`.
2. Получите файлы сертификата:
- Главный сертификат (CRT)
- Промежуточные сертификаты (CA Bundle)
- Приватный ключ (KEY)
---
### Шаг 2. Импорт вашего SSL сертификата в Nginx Proxy Manager
1. Авторизуйтесь в Nginx Proxy Manager на http://192.0.2.1:81/
2. Перейдите в раздел **SSL Certificates** → кнопку **Add SSL Certificate**
3. Выберите **Custom** (пользовательский сертификат)
4. В поля вставьте:
- **Certificate** — основной CRT + CA Bundle (если CA Bundle раздельно, склейте в один файл или вставляйте последовательно)
- **Key** — содержимое приватного ключа
- Имя сертификата задайте, например, `dfv24_wildcard`
5. Сохраните
---
### Шаг 3. Настройка прокси-хостов с использованием глобального сертификата
1. Перейдите в **Proxy Hosts****Add Proxy Host**
2. Заполните поля:
- **Domain Names**: Например, `sub1.example.com` (для первого поддомена)
- **Scheme**: http или https, в зависимости от бекенда
- **Forward Hostname / IP**: IP или DNS адрес вашего внутреннего сервиса
- **Forward Port**: порт сервиса (например, 80 или 443)
3. Включите **SSL** → Отметьте **Use a shared SSL certificate** (если такая опция доступна) или выберите ранее импортированный сертификат из списка
4. Активируйте: **Block Common Exploits**, **Websockets Support**, выставьте Redirect HTTP to HTTPS, если требуется
5. Сохраните прокси-хост
6. Повторите для всех поддоменов, указывая нужные домены и выбирая тот же wildcard SSL сертификат
---
### Шаг 4. Настройка DNS записей на reg.ru
1. Войдите в панель управления доменом на reg.ru
2. Создайте или отредактируйте DNS записи типа A:
- `example.com` → IP вашего Nginx Proxy Manager (например, 192.0.2.1)
- `*.example.com` → тот же IP или конкретные поддомены, если есть специальные
3. Сохраните изменения
4. Дождитесь обновления DNS (от нескольких минут до 24 часов)
---
### Шаг 5. Тест и проверка работы
1. В браузере откройте любой из поддоменов `https://sub1.example.com`
2. Сертификат должен быть валидным, выданным на wildcard `*.example.com`
3. Проверьте работу прокси и корректность подстановки сертификата
4. При необходимости проверьте логи Nginx Proxy Manager и исправьте ошибки
---
### Дополнительно
- Если в Nginx Proxy Manager нет GUI опции выбора общего сертификата, можно вручную сконфигурировать конфиги через директорий `/data/nginx/proxy_host` и прописать SSL сертификат для всех хостов.
- При обновлении сертификата — повторно импортировать его в Nginx Proxy Manager.
- Можно использовать LetsEncrypt для автоматического получения wildcard сертификата с помощью DNS валидации (если поддерживается вашим DNS провайдером).
---
## Итог
Используйте один wildcard сертификат для всех поддоменов, импортируйте его как пользовательский сертификат в Nginx Proxy Manager, при создании прокси-хостов выбирайте его в настройках SSL. Управляйте DNS записями на reg.ru, направляя домен на IP Nginx Proxy Manager.
Это позволит юридически использовать единый сертификат для всех сервисов с различными поддоменами под вашим доменом example.com.
# Интеграция с Nginx Proxy Manager (NPM)
Проект умеет автоматически загружать (или обновлять) сертификаты в NPM через его API.
## Включение
В конфиге:
- `npm_enabled: true`
- `npm_host`: например `http://192.0.2.1:81`
- `npm_email`, `npm_password`
После этого:
- `--obtain`, `--renew`, `--auto`, `--test-cert` будут пытаться синхронизировать сертификат в NPM.
## Как работает синхронизация
1) Скрипт логинится в NPM (`/api/tokens`)
2) Получает список сертификатов
3) Ищет сертификат по домену (учитывает `<domain>` и `*.<domain>`)
4) Если найден — обновляет, иначе — загружает новый
### Про “дубликаты” сертификатов
Иногда NPM сразу после загрузки ещё не распарсил домены (поле `domain_names` пустое). Скрипт дополнительно пытается сопоставлять по `nice_name`, чтобы не плодить дубли.
Команда для диагностики:
- `--list-npm` — показывает сертификаты и подсвечивает дубликаты
- `--delete-npm <ID>` — удаляет сертификат по ID
## Ручная загрузка существующего сертификата
- `--upload-npm <DOMAIN>`
Скрипт возьмёт `fullchain.pem` и `privkey.pem` из `cert_dir/<DOMAIN>/` и загрузит/обновит сертификат в NPM.
## Один wildcard сертификат на много поддоменов
Практический сценарий:
- Получить сертификат на `example.com` + `*.example.com`
- В NPM импортировать/использовать этот сертификат для всех Proxy Hosts
Обратите внимание:
- для wildcard Lets Encrypt нужен DNS-01 challenge
- в NPM можно использовать либо встроенный Lets Encrypt, либо этот проект как внешний менеджер и синхронизатор
## Пошагово: использовать один wildcard сертификат для всех Proxy Hosts
Ниже — практический сценарий, когда вам нужен один сертификат (например, `*.example.com`) и вы хотите назначать его на все хосты.
### Вариант A: сертификат выдаёт этот проект (рекомендуется при reg.ru DNS-01)
1) Убедитесь, что DNS API reg.ru работает:
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
2) Получите production сертификат:
- `letsencrypt-regru --obtain`
3) Если `npm_enabled=true`, сертификат автоматически появится в NPM.
4) В NPM:
- Proxy Hosts → Add/Edit Proxy Host
- SSL → выберите сертификат (обычно “Custom/Other”)
- включите нужные опции (Force SSL, HSTS по необходимости)
### Вариант B: сертификат выдаёт сам NPM
Этот вариант подходит, если NPM может сам пройти challenge.
1) SSL Certificates → Add SSL Certificate → Lets Encrypt
2) Domain Names: добавьте `example.com` и `*.example.com`
3) Выберите challenge:
- HTTP-01: требует доступности NPM из интернета по 80/443 и корректных A/AAAA записей
- DNS-01: требует поддерживаемого DNS provider в NPM
Если нужного DNS провайдера нет (или нет корректной интеграции для reg.ru), проще использовать этот проект как внешний DNS-01 менеджер.
### Вариант C: импорт уже существующего wildcard сертификата (Custom)
Если вы приобрели wildcard сертификат у CA или получили его другим способом:
1) SSL Certificates → Add SSL Certificate → Custom
2) Вставьте:
- Certificate: сертификат + intermediate chain (если отдельно — добавьте подряд)
- Key: приватный ключ
3) Сохраните и назначайте этот сертификат на Proxy Hosts.
## DNS записи для wildcard
Для проксирования поддоменов часто достаточно, чтобы DNS указывал на NPM:
- `example.com` → IP NPM
- `*.example.com` → IP NPM
Точная схема зависит от вашей инфраструктуры.
## Траблшутинг
- “не логинится” → проверьте `npm_host` (http/https), креды, доступность
- “сертификат не появился” → проверьте `npm_enabled`, логи скрипта
- staging сертификаты: не предназначены для production (браузер не доверяет)
---
## Appendix (migrated from: Настройке Nginx Manager с SSL)
<!-- MIGRATED_FROM_DOCS: Настройке Nginx Manager с SSL -->
## Подробная инструкция по настройке Nginx Proxy Manager с одним глобальным SSL сертификатом для всех доменов example.com
### Предпосылки
- Установлен и запущен [Nginx Proxy Manager](http://192.0.2.1:81/)
- Основной домен: example.com
- Хостинг и DNS записи домена находятся на reg.ru
- Нужно использовать один SSL сертификат (например, wildcard) для всех поддоменов example.com
---
### Шаг 1. Покупка и получение SSL Wildcard сертификата для example.com
1. На reg.ru или любом другом удостоверяющем центре (CA) закажите wildcard сертификат на домен вида `*.example.com`.
2. Получите файлы сертификата:
- Главный сертификат (CRT)
- Промежуточные сертификаты (CA Bundle)
- Приватный ключ (KEY)
---
### Шаг 2. Импорт вашего SSL сертификата в Nginx Proxy Manager
1. Авторизуйтесь в Nginx Proxy Manager на http://192.0.2.1:81/
2. Перейдите в раздел **SSL Certificates** → кнопку **Add SSL Certificate**
3. Выберите **Custom** (пользовательский сертификат)
4. В поля вставьте:
- **Certificate** — основной CRT + CA Bundle (если CA Bundle раздельно, склейте в один файл или вставляйте последовательно)
- **Key** — содержимое приватного ключа
- Имя сертификата задайте, например, `dfv24_wildcard`
5. Сохраните
---
### Шаг 3. Настройка прокси-хостов с использованием глобального сертификата
1. Перейдите в **Proxy Hosts****Add Proxy Host**
2. Заполните поля:
- **Domain Names**: Например, `sub1.example.com` (для первого поддомена)
- **Scheme**: http или https, в зависимости от бекенда
- **Forward Hostname / IP**: IP или DNS адрес вашего внутреннего сервиса
- **Forward Port**: порт сервиса (например, 80 или 443)
3. Включите **SSL** → Отметьте **Use a shared SSL certificate** (если такая опция доступна) или выберите ранее импортированный сертификат из списка
4. Активируйте: **Block Common Exploits**, **Websockets Support**, выставьте Redirect HTTP to HTTPS, если требуется
5. Сохраните прокси-хост
6. Повторите для всех поддоменов, указывая нужные домены и выбирая тот же wildcard SSL сертификат
---
### Шаг 4. Настройка DNS записей на reg.ru
1. Войдите в панель управления доменом на reg.ru
2. Создайте или отредактируйте DNS записи типа A:
- `example.com` → IP вашего Nginx Proxy Manager (например, 192.0.2.1)
- `*.example.com` → тот же IP или конкретные поддомены, если есть специальные
3. Сохраните изменения
4. Дождитесь обновления DNS (от нескольких минут до 24 часов)
---
### Шаг 5. Тест и проверка работы
1. В браузере откройте любой из поддоменов `https://sub1.example.com`
2. Сертификат должен быть валидным, выданным на wildcard `*.example.com`
3. Проверьте работу прокси и корректность подстановки сертификата
4. При необходимости проверьте логи Nginx Proxy Manager и исправьте ошибки
---
### Дополнительно
- Если в Nginx Proxy Manager нет GUI опции выбора общего сертификата, можно вручную сконфигурировать конфиги через директорий `/data/nginx/proxy_host` и прописать SSL сертификат для всех хостов.
- При обновлении сертификата — повторно импортировать его в Nginx Proxy Manager.
- Можно использовать LetsEncrypt для автоматического получения wildcard сертификата с помощью DNS валидации (если поддерживается вашим DNS провайдером).
---
## Итог
Используйте один wildcard сертификат для всех поддоменов, импортируйте его как пользовательский сертификат в Nginx Proxy Manager, при создании прокси-хостов выбирайте его в настройках SSL. Управляйте DNS записями на reg.ru, направляя домен на IP Nginx Proxy Manager.
Это позволит юридически использовать единый сертификат для всех сервисов с различными поддоменами под вашим доменом example.com.
+292 -292
View File
@@ -1,292 +1,292 @@
# Структура проекта
Ключевые файлы:
- `letsencrypt_regru_api.py` — основной Python скрипт (API reg.ru + certbot + NPM)
- `letsencrypt_regru.sh` — установщик и менеджер установки
- `Makefile` — команды установки/обслуживания/сборки
- `config.json.example` — пример конфигурации
- `systemd/` — unit файлы для автозапуска/таймера
- `wiki/` — актуальная документация (страницы Wiki)
Скрипты:
- `letsencrypt_regru_dns.sh` — bash вариант через плагин certbot-dns-regru
- `letsencrypt_regru.ps1` — PowerShell версия
- `test_certificate.sh` — автономная генерация тестовых сертификатов через OpenSSL
Документация:
- `README.md` — основное руководство
- `wiki/*` — дополнительные гайды (тестирование, сборка, синхронизация и т.д.)
## Автоматизация
- systemd timer обычно запускает `--auto` по расписанию (по умолчанию каждые 12 часов)
- после успешного обновления может выполняться reload веб-сервиса
---
## Appendix (migrated from docs/PROJECT_STRUCTURE.md)
<!-- MIGRATED_FROM_DOCS:PROJECT_STRUCTURE.md -->
## 📁 Структура проекта configure_nginx_manager
### Основные скрипты
#### Python (Рекомендуется)
- **letsencrypt_regru_api.py** (1,411 строк)
- Полнофункциональный Python скрипт
- Прямая работа с API reg.ru
- Интеграция с Nginx Proxy Manager
- Автоматическая проверка и обновление сертификатов
- Генерация тестовых самоподписанных сертификатов
- Поддержка wildcard доменов
#### Bash
- **letsencrypt_regru_dns.sh**
- Bash скрипт с certbot-dns-regru плагином
- Простота использования
- Минимальные зависимости
#### PowerShell
- **letsencrypt_regru.ps1**
- Windows версия
- Аналогична Bash скрипту
#### Тестирование
- **test_certificate.sh**
- Быстрое создание тестовых сертификатов через OpenSSL
- Автономная работа без Python
- Поддержка wildcard доменов
### Автоматизация
#### Makefile
- **Makefile** (415 строк)
- `make install` - Полная установка и настройка
- `make uninstall` - Чистое удаление
- `make status` - Проверка состояния
- `make test-cert` - Создание тестового сертификата
- `make obtain` - Получение Let's Encrypt сертификата
- `make renew` - Обновление сертификата
- `make logs` - Просмотр логов
- `make check-config` - Валидация конфигурации
### Конфигурация
#### config.json.example
Пример конфигурации со всеми параметрами:
- Учетные данные reg.ru API
- Настройки домена и email
- Параметры обновления (renewal_days)
- Настройки Nginx Proxy Manager
- Пути к директориям и логам
### Документация
#### README.md (1,420+ строк)
Основная документация:
- Введение и возможности
- Быстрый старт
- Установка через Makefile
- Создание тестовых сертификатов
- Требования и установка зависимостей
- Настройка и использование
- Интеграция с NPM
- Автоматическая проверка и обновление
- Автоматизация через cron/systemd
- Устранение неполадок
#### TESTING_GUIDE.md (370+ строк)
Руководство по тестированию:
- Зачем нужны тестовые сертификаты
- Обход лимитов Let's Encrypt (5 в неделю)
- Быстрый старт с тестовыми сертификатами
- Сравнение методов создания
- Использование в разработке
- Автоматизация тестирования
- Переход с тестовых на production
- Частые вопросы
- Примеры для CI/CD и Docker
#### GITEA_SYNC.md
Синхронизация Gitea → GitHub:
- 4 метода синхронизации (Git Hooks, GitHub Actions, Gitea Mirror, Double Remote)
- Пошаговые инструкции установки
- Настройка SSH и токенов
- Webhook интеграция
- Устранение проблем
- Сравнение методов
#### CHEATSHEET.md
Быстрая шпаргалка:
- Основные команды
- Workflow разработки
- Сценарии использования
- Частые ошибки и решения
- Проверка и отладка
#### PROJECT_STRUCTURE.md (этот файл)
- Описание всех файлов проекта
- Краткая характеристика каждого компонента
#### CHANGELOG.md
История изменений:
- Версии и обновления
- Новые возможности
- Исправления
- Roadmap
### Интеграция с Git
#### .github/workflows/sync-from-gitea.yml
GitHub Actions для синхронизации:
- Автоматическая проверка каждый час
- Webhook триггер от Gitea
- Ручной запуск
- Merge изменений из Gitea
- Push в GitHub
#### gitea-hooks/
Git hooks для Gitea сервера:
**post-receive**
- Автоматический push в GitHub после commit
- Мгновенная синхронизация (< 1 секунды)
- Логирование операций
- Синхронизация тегов
- Поддержка SSH и HTTPS
**README.md**
- Инструкции по установке hook
- Настройка аутентификации
- Устранение проблем
### Вспомогательные файлы
#### Markdown документы
- **Add Let's Encrypt Certificate для провайдера reg.ru.md**
- Первоначальные инструкции
- **Создание и продление SSL сертификата (md)**
- Дополнительная информация о процессе
### Возможности
#### ✅ Основные
- [x] Создание Let's Encrypt сертификатов через reg.ru DNS API
- [x] Wildcard сертификаты (*.domain.com)
- [x] Автоматическое обновление сертификатов
- [x] DNS-01 валидация
- [x] Интеграция с Nginx Proxy Manager
- [x] Автоматическая загрузка/обновление в NPM
#### ✅ Продвинутые
- [x] Автоматическая проверка срока действия
- [x] Настраиваемый порог обновления (renewal_days)
- [x] Systemd service + timer
- [x] Cron автоматизация
- [x] Подробное логирование
- [x] Валидация конфигурации
#### 🆕 Тестирование
- [x] Генерация самоподписанных тестовых сертификатов
- [x] Обход лимитов Let's Encrypt (5/неделю)
- [x] Мгновенное создание без DNS
- [x] Интеграция тестовых сертификатов с NPM
- [x] Полная совместимость структуры с Let's Encrypt
#### 🔄 Синхронизация репозиториев
- [x] Автоматическая синхронизация Gitea → GitHub
- [x] Git Hooks (мгновенная синхронизация)
- [x] GitHub Actions (проверка каждый час)
- [x] Webhook интеграция
- [x] SSH и HTTPS аутентификация
### Установка
#### Быстрая установка
```bash
sudo make install
sudo nano /etc/letsencrypt/regru_config.json
sudo make test-cert # Для тестирования
sudo make obtain # Для production
```
#### Структура после установки
```
/opt/letsencrypt-regru/
├── letsencrypt_regru_api.py
/etc/letsencrypt/
├── regru_config.json
└── live/
└── example.com/
├── privkey.pem
├── cert.pem
├── fullchain.pem
└── chain.pem
/etc/systemd/system/
├── letsencrypt-regru.service
└── letsencrypt-regru.timer
/var/log/letsencrypt/
└── letsencrypt_regru.log
```
### Использование
#### Тестирование (без лимитов)
```bash
sudo make test-cert # Создать тестовый сертификат
sudo make status # Проверить статус
```
#### Production
```bash
sudo make obtain # Получить Let's Encrypt сертификат
sudo make renew # Обновить сертификат
sudo make run # Автоматический режим
```
#### Мониторинг
```bash
sudo make logs # Просмотр логов
sudo make status # Статус служб
sudo make check-config # Проверка конфигурации
```
### Технологии
- **Python 3.6+** - Основной язык
- **Certbot** - Let's Encrypt клиент
- **requests** - HTTP запросы к API
- **cryptography** - Генерация тестовых сертификатов
- **systemd** - Автоматизация запуска
- **cron** - Альтернативная автоматизация
- **Make** - Управление установкой
- **OpenSSL** - Альтернативная генерация сертификатов
### Лицензия
Open Source - свободное использование
### Автор
Фофанов Дмитрий @ 2025
### Поддержка
См. документацию:
- [README.md](README.md) - Основное руководство
- [TESTING_GUIDE.md](Testing.md) - Руководство по тестированию
---
**Версия**: 2.1
**Дата**: 27 октября 2025
**Статус**: ✅ Production Ready
# Структура проекта
Ключевые файлы:
- `letsencrypt_regru_api.py` — основной Python скрипт (API reg.ru + certbot + NPM)
- `letsencrypt_regru.sh` — установщик и менеджер установки
- `Makefile` — команды установки/обслуживания/сборки
- `config.json.example` — пример конфигурации
- `systemd/` — unit файлы для автозапуска/таймера
- `wiki/` — актуальная документация (страницы Wiki)
Скрипты:
- `letsencrypt_regru_dns.sh` — bash вариант через плагин certbot-dns-regru
- `letsencrypt_regru.ps1` — PowerShell версия
- `test_certificate.sh` — автономная генерация тестовых сертификатов через OpenSSL
Документация:
- `README.md` — основное руководство
- `wiki/*` — дополнительные гайды (тестирование, сборка, синхронизация и т.д.)
## Автоматизация
- systemd timer обычно запускает `--auto` по расписанию (по умолчанию каждые 12 часов)
- после успешного обновления может выполняться reload веб-сервиса
---
## Appendix (migrated from docs/PROJECT_STRUCTURE.md)
<!-- MIGRATED_FROM_DOCS:PROJECT_STRUCTURE.md -->
## 📁 Структура проекта configure_nginx_manager
### Основные скрипты
#### Python (Рекомендуется)
- **letsencrypt_regru_api.py** (1,411 строк)
- Полнофункциональный Python скрипт
- Прямая работа с API reg.ru
- Интеграция с Nginx Proxy Manager
- Автоматическая проверка и обновление сертификатов
- Генерация тестовых самоподписанных сертификатов
- Поддержка wildcard доменов
#### Bash
- **letsencrypt_regru_dns.sh**
- Bash скрипт с certbot-dns-regru плагином
- Простота использования
- Минимальные зависимости
#### PowerShell
- **letsencrypt_regru.ps1**
- Windows версия
- Аналогична Bash скрипту
#### Тестирование
- **test_certificate.sh**
- Быстрое создание тестовых сертификатов через OpenSSL
- Автономная работа без Python
- Поддержка wildcard доменов
### Автоматизация
#### Makefile
- **Makefile** (415 строк)
- `make install` - Полная установка и настройка
- `make uninstall` - Чистое удаление
- `make status` - Проверка состояния
- `make test-cert` - Создание тестового сертификата
- `make obtain` - Получение Let's Encrypt сертификата
- `make renew` - Обновление сертификата
- `make logs` - Просмотр логов
- `make check-config` - Валидация конфигурации
### Конфигурация
#### config.json.example
Пример конфигурации со всеми параметрами:
- Учетные данные reg.ru API
- Настройки домена и email
- Параметры обновления (renewal_days)
- Настройки Nginx Proxy Manager
- Пути к директориям и логам
### Документация
#### README.md (1,420+ строк)
Основная документация:
- Введение и возможности
- Быстрый старт
- Установка через Makefile
- Создание тестовых сертификатов
- Требования и установка зависимостей
- Настройка и использование
- Интеграция с NPM
- Автоматическая проверка и обновление
- Автоматизация через cron/systemd
- Устранение неполадок
#### TESTING_GUIDE.md (370+ строк)
Руководство по тестированию:
- Зачем нужны тестовые сертификаты
- Обход лимитов Let's Encrypt (5 в неделю)
- Быстрый старт с тестовыми сертификатами
- Сравнение методов создания
- Использование в разработке
- Автоматизация тестирования
- Переход с тестовых на production
- Частые вопросы
- Примеры для CI/CD и Docker
#### GITEA_SYNC.md
Синхронизация Gitea → GitHub:
- 4 метода синхронизации (Git Hooks, GitHub Actions, Gitea Mirror, Double Remote)
- Пошаговые инструкции установки
- Настройка SSH и токенов
- Webhook интеграция
- Устранение проблем
- Сравнение методов
#### CHEATSHEET.md
Быстрая шпаргалка:
- Основные команды
- Workflow разработки
- Сценарии использования
- Частые ошибки и решения
- Проверка и отладка
#### PROJECT_STRUCTURE.md (этот файл)
- Описание всех файлов проекта
- Краткая характеристика каждого компонента
#### CHANGELOG.md
История изменений:
- Версии и обновления
- Новые возможности
- Исправления
- Roadmap
### Интеграция с Git
#### .github/workflows/sync-from-gitea.yml
GitHub Actions для синхронизации:
- Автоматическая проверка каждый час
- Webhook триггер от Gitea
- Ручной запуск
- Merge изменений из Gitea
- Push в GitHub
#### gitea-hooks/
Git hooks для Gitea сервера:
**post-receive**
- Автоматический push в GitHub после commit
- Мгновенная синхронизация (< 1 секунды)
- Логирование операций
- Синхронизация тегов
- Поддержка SSH и HTTPS
**README.md**
- Инструкции по установке hook
- Настройка аутентификации
- Устранение проблем
### Вспомогательные файлы
#### Markdown документы
- **Add Let's Encrypt Certificate для провайдера reg.ru.md**
- Первоначальные инструкции
- **Создание и продление SSL сертификата (md)**
- Дополнительная информация о процессе
### Возможности
#### ✅ Основные
- [x] Создание Let's Encrypt сертификатов через reg.ru DNS API
- [x] Wildcard сертификаты (*.domain.com)
- [x] Автоматическое обновление сертификатов
- [x] DNS-01 валидация
- [x] Интеграция с Nginx Proxy Manager
- [x] Автоматическая загрузка/обновление в NPM
#### ✅ Продвинутые
- [x] Автоматическая проверка срока действия
- [x] Настраиваемый порог обновления (renewal_days)
- [x] Systemd service + timer
- [x] Cron автоматизация
- [x] Подробное логирование
- [x] Валидация конфигурации
#### 🆕 Тестирование
- [x] Генерация самоподписанных тестовых сертификатов
- [x] Обход лимитов Let's Encrypt (5/неделю)
- [x] Мгновенное создание без DNS
- [x] Интеграция тестовых сертификатов с NPM
- [x] Полная совместимость структуры с Let's Encrypt
#### 🔄 Синхронизация репозиториев
- [x] Автоматическая синхронизация Gitea → GitHub
- [x] Git Hooks (мгновенная синхронизация)
- [x] GitHub Actions (проверка каждый час)
- [x] Webhook интеграция
- [x] SSH и HTTPS аутентификация
### Установка
#### Быстрая установка
```bash
sudo make install
sudo nano /etc/letsencrypt/regru_config.json
sudo make test-cert # Для тестирования
sudo make obtain # Для production
```
#### Структура после установки
```
/opt/letsencrypt-regru/
├── letsencrypt_regru_api.py
/etc/letsencrypt/
├── regru_config.json
└── live/
└── example.com/
├── privkey.pem
├── cert.pem
├── fullchain.pem
└── chain.pem
/etc/systemd/system/
├── letsencrypt-regru.service
└── letsencrypt-regru.timer
/var/log/letsencrypt/
└── letsencrypt_regru.log
```
### Использование
#### Тестирование (без лимитов)
```bash
sudo make test-cert # Создать тестовый сертификат
sudo make status # Проверить статус
```
#### Production
```bash
sudo make obtain # Получить Let's Encrypt сертификат
sudo make renew # Обновить сертификат
sudo make run # Автоматический режим
```
#### Мониторинг
```bash
sudo make logs # Просмотр логов
sudo make status # Статус служб
sudo make check-config # Проверка конфигурации
```
### Технологии
- **Python 3.6+** - Основной язык
- **Certbot** - Let's Encrypt клиент
- **requests** - HTTP запросы к API
- **cryptography** - Генерация тестовых сертификатов
- **systemd** - Автоматизация запуска
- **cron** - Альтернативная автоматизация
- **Make** - Управление установкой
- **OpenSSL** - Альтернативная генерация сертификатов
### Лицензия
Open Source - свободное использование
### Автор
Фофанов Дмитрий @ 2025
### Поддержка
См. документацию:
- [README.md](README.md) - Основное руководство
- [TESTING_GUIDE.md](Testing.md) - Руководство по тестированию
---
**Версия**: 2.1
**Дата**: 27 октября 2025
**Статус**: ✅ Production Ready
+260 -260
View File
@@ -1,57 +1,57 @@
# Проблемы API reg.ru (DNS)
## Ошибка: “Access to API from this IP denied”
Причина: ваш текущий IP не разрешён в настройках API reg.ru.
### Диагностика
- `letsencrypt-regru --test-api`
- или `curl -s https://ipinfo.io/ip`
### Решение (рекомендуется)
1) Личный кабинет reg.ru
2) Настройки → Безопасность → API
3) Добавить текущий IP в белый список
4) Повторить `--test-api`
### Альтернатива
Отключить ограничения по IP (менее безопасно).
## Ошибка: “Invalid username or password”
- проверьте `regru_username`/`regru_password` в конфиге
- проверьте права доступа к файлу конфига (600)
## Ошибка: “IP exceeded allowed connection rate”
API ограничивает частоту запросов.
Решения:
- подождать 510 минут
- не запускать `--test-api` слишком часто
- для мониторинга чаще используйте `--check`
## Таймауты
- проверьте интернет
- проверьте firewall/proxy
## Логи для диагностики
- `log_file` из конфигурации
- `/var/log/letsencrypt/letsencrypt.log` (certbot)
## Когда обращаться в поддержку reg.ru
Приготовьте:
- ваш IP
- точный текст ошибки
- фрагмент логов (без паролей)
# Проблемы API reg.ru (DNS)
## Ошибка: “Access to API from this IP denied”
Причина: ваш текущий IP не разрешён в настройках API reg.ru.
### Диагностика
- `letsencrypt-regru --test-api`
- или `curl -s https://ipinfo.io/ip`
### Решение (рекомендуется)
1) Личный кабинет reg.ru
2) Настройки → Безопасность → API
3) Добавить текущий IP в белый список
4) Повторить `--test-api`
### Альтернатива
Отключить ограничения по IP (менее безопасно).
## Ошибка: “Invalid username or password”
- проверьте `regru_username`/`regru_password` в конфиге
- проверьте права доступа к файлу конфига (600)
## Ошибка: “IP exceeded allowed connection rate”
API ограничивает частоту запросов.
Решения:
- подождать 510 минут
- не запускать `--test-api` слишком часто
- для мониторинга чаще используйте `--check`
## Таймауты
- проверьте интернет
- проверьте firewall/proxy
## Логи для диагностики
- `log_file` из конфигурации
- `/var/log/letsencrypt/letsencrypt.log` (certbot)
## Когда обращаться в поддержку reg.ru
Приготовьте:
- ваш IP
- точный текст ошибки
- фрагмент логов (без паролей)
---
@@ -59,209 +59,209 @@ API ограничивает частоту запросов.
## Appendix (migrated from docs/API_TROUBLESHOOTING.md)
<!-- MIGRATED_FROM_DOCS:API_TROUBLESHOOTING.md -->
## 🔧 Решение проблем с API reg.ru
### ❌ Проблема: "Access to API from this IP denied"
Эта ошибка возникает, когда API reg.ru заблокирован для вашего IP адреса из соображений безопасности.
#### 🔍 Диагностика
Сначала определите ваш текущий IP адрес:
```bash
## Способ 1: Через встроенную функцию скрипта
sudo letsencrypt-regru --test-api
## Способ 2: Через curl
curl -s https://ipinfo.io/ip
## Способ 3: Через веб-сайт
## Откройте https://whatismyipaddress.com/
```
#### ✅ Решение
##### Метод 1: Добавить IP в белый список (рекомендуется)
1. **Войдите в личный кабинет reg.ru**
- Откройте https://www.reg.ru/
- Войдите в личный кабинет
2. **Перейдите в настройки API**
- Меню → "Настройки"
- Раздел "Безопасность"
- Подраздел "API"
3. **Настройте доступ по IP**
- Найдите раздел "Ограничения по IP"
- Нажмите "Добавить IP адрес"
- Введите ваш текущий IP адрес
- Сохраните настройки
4. **Проверьте настройки**
```bash
sudo letsencrypt-regru --test-api
```
##### Метод 2: Отключить ограничения по IP (менее безопасно)
⚠️ **ВНИМАНИЕ**: Это снижает безопасность вашего аккаунта!
1. В настройках API reg.ru найдите "Ограничения по IP"
2. Отключите опцию "Разрешить доступ только с указанных IP"
3. Сохраните настройки
#### 🔒 Рекомендации по безопасности
1. **Используйте статический IP**
- Если у вас динамический IP, рассмотрите покупку статического
- Или регулярно обновляйте список разрешенных IP
2. **Ограничьте доступ к API**
- Добавляйте только необходимые IP адреса
- Регулярно проверяйте и очищайте список
3. **Используйте сильные пароли**
- Сложный пароль для аккаунта reg.ru
- Двухфакторная аутентификация если доступна
### ❌ Проблема: "Invalid username or password"
#### ✅ Решение
1. **Проверьте учетные данные**
```bash
sudo nano /etc/letsencrypt-regru/config.json
```
Убедитесь что указаны правильные:
- `regru_username` - логин от reg.ru
- `regru_password` - пароль от reg.ru
2. **Проверьте права на файл**
```bash
sudo chmod 600 /etc/letsencrypt-regru/config.json
sudo chown root:root /etc/letsencrypt-regru/config.json
```
3. **Протестируйте подключение**
```bash
sudo letsencrypt-regru --test-api
```
### ❌ Проблема: "IP exceeded allowed connection rate"
#### Причина
API reg.ru ограничивает частоту запросов с одного IP (обычно 10-20 запросов в минуту).
#### ✅ Решение
1. **Подождите 5-10 минут**
```bash
# Подождите перед следующей попыткой
sleep 600 # 10 минут
sudo letsencrypt-regru --obtain
```
2. **Настройте автоматизацию правильно**
```bash
# Проверка сертификатов 1 раз в день
sudo systemctl enable letsencrypt-regru.timer
sudo systemctl start letsencrypt-regru.timer
# Проверить расписание
sudo systemctl cat letsencrypt-regru.timer
```
3. **Рекомендации по частоте запросов**
- ✅ Автоматическая проверка: **1 раз в день**
- ✅ Ручная проверка: **не чаще 1 раза в час**
- ❌ Избегайте частых тестов `--test-api`
- ❌ Не создавайте cron с частым запуском
4. **Используйте --check вместо --obtain**
```bash
# Проверка без создания сертификата
sudo letsencrypt-regru --check
```
### ❌ Проблема: Таймаут подключения
#### ✅ Решение
1. **Проверьте интернет соединение**
```bash
ping -c 4 api.reg.ru
curl -I https://api.reg.ru/api/regru2
```
2. **Проверьте брандмауэр**
```bash
# Временно отключите firewall для теста
sudo ufw status
sudo iptables -L
```
3. **Проверьте прокси настройки**
- Убедитесь что переменные окружения `HTTP_PROXY`, `HTTPS_PROXY` не мешают
### 🧪 Тестирование API
Всегда тестируйте API перед использованием:
```bash
## Полный тест API
sudo letsencrypt-regru --test-api
## Тест с подробным выводом
sudo letsencrypt-regru --test-api -v
## Проверка конфигурации
sudo letsencrypt-regru --check
```
### 📞 Получение помощи
#### Техподдержка reg.ru
- **Email**: support@reg.ru
- **Телефон**: 8 (495) 580-11-11
- **Онлайн чат**: на сайте reg.ru
#### Документация
- **API reg.ru**: https://www.reg.ru/support/api
- **Примеры использования**: https://www.reg.ru/support/api/examples
- **FAQ по API**: https://www.reg.ru/support/api/faq
#### Логи для диагностики
Всегда включайте логи при обращении в поддержку:
```bash
## Включить подробные логи
sudo letsencrypt-regru --test-api -v
## Посмотреть последние логи
sudo tail -n 50 /var/log/letsencrypt-regru/letsencrypt_regru.log
## Логи certbot
sudo tail -n 50 /var/log/letsencrypt/letsencrypt.log
```
### 🔄 Альтернативные DNS провайдеры
Если проблемы с reg.ru API критичны, рассмотрите альтернативы:
1. **Cloudflare** - отличный API, бесплатный DNS
2. **Route53** (AWS) - мощный, но платный
3. **DigitalOcean DNS** - простой и надежный
4. **Google Cloud DNS** - интеграция с GCP
Для них потребуется модификация скрипта или использование других плагинов certbot.
---
**Дата обновления**: 29.10.2025
**Версия документа**: 1.0
## 🔧 Решение проблем с API reg.ru
### ❌ Проблема: "Access to API from this IP denied"
Эта ошибка возникает, когда API reg.ru заблокирован для вашего IP адреса из соображений безопасности.
#### 🔍 Диагностика
Сначала определите ваш текущий IP адрес:
```bash
## Способ 1: Через встроенную функцию скрипта
sudo letsencrypt-regru --test-api
## Способ 2: Через curl
curl -s https://ipinfo.io/ip
## Способ 3: Через веб-сайт
## Откройте https://whatismyipaddress.com/
```
#### ✅ Решение
##### Метод 1: Добавить IP в белый список (рекомендуется)
1. **Войдите в личный кабинет reg.ru**
- Откройте https://www.reg.ru/
- Войдите в личный кабинет
2. **Перейдите в настройки API**
- Меню → "Настройки"
- Раздел "Безопасность"
- Подраздел "API"
3. **Настройте доступ по IP**
- Найдите раздел "Ограничения по IP"
- Нажмите "Добавить IP адрес"
- Введите ваш текущий IP адрес
- Сохраните настройки
4. **Проверьте настройки**
```bash
sudo letsencrypt-regru --test-api
```
##### Метод 2: Отключить ограничения по IP (менее безопасно)
⚠️ **ВНИМАНИЕ**: Это снижает безопасность вашего аккаунта!
1. В настройках API reg.ru найдите "Ограничения по IP"
2. Отключите опцию "Разрешить доступ только с указанных IP"
3. Сохраните настройки
#### 🔒 Рекомендации по безопасности
1. **Используйте статический IP**
- Если у вас динамический IP, рассмотрите покупку статического
- Или регулярно обновляйте список разрешенных IP
2. **Ограничьте доступ к API**
- Добавляйте только необходимые IP адреса
- Регулярно проверяйте и очищайте список
3. **Используйте сильные пароли**
- Сложный пароль для аккаунта reg.ru
- Двухфакторная аутентификация если доступна
### ❌ Проблема: "Invalid username or password"
#### ✅ Решение
1. **Проверьте учетные данные**
```bash
sudo nano /etc/letsencrypt-regru/config.json
```
Убедитесь что указаны правильные:
- `regru_username` - логин от reg.ru
- `regru_password` - пароль от reg.ru
2. **Проверьте права на файл**
```bash
sudo chmod 600 /etc/letsencrypt-regru/config.json
sudo chown root:root /etc/letsencrypt-regru/config.json
```
3. **Протестируйте подключение**
```bash
sudo letsencrypt-regru --test-api
```
### ❌ Проблема: "IP exceeded allowed connection rate"
#### Причина
API reg.ru ограничивает частоту запросов с одного IP (обычно 10-20 запросов в минуту).
#### ✅ Решение
1. **Подождите 5-10 минут**
```bash
# Подождите перед следующей попыткой
sleep 600 # 10 минут
sudo letsencrypt-regru --obtain
```
2. **Настройте автоматизацию правильно**
```bash
# Проверка сертификатов 1 раз в день
sudo systemctl enable letsencrypt-regru.timer
sudo systemctl start letsencrypt-regru.timer
# Проверить расписание
sudo systemctl cat letsencrypt-regru.timer
```
3. **Рекомендации по частоте запросов**
- ✅ Автоматическая проверка: **1 раз в день**
- ✅ Ручная проверка: **не чаще 1 раза в час**
- ❌ Избегайте частых тестов `--test-api`
- ❌ Не создавайте cron с частым запуском
4. **Используйте --check вместо --obtain**
```bash
# Проверка без создания сертификата
sudo letsencrypt-regru --check
```
### ❌ Проблема: Таймаут подключения
#### ✅ Решение
1. **Проверьте интернет соединение**
```bash
ping -c 4 api.reg.ru
curl -I https://api.reg.ru/api/regru2
```
2. **Проверьте брандмауэр**
```bash
# Временно отключите firewall для теста
sudo ufw status
sudo iptables -L
```
3. **Проверьте прокси настройки**
- Убедитесь что переменные окружения `HTTP_PROXY`, `HTTPS_PROXY` не мешают
### 🧪 Тестирование API
Всегда тестируйте API перед использованием:
```bash
## Полный тест API
sudo letsencrypt-regru --test-api
## Тест с подробным выводом
sudo letsencrypt-regru --test-api -v
## Проверка конфигурации
sudo letsencrypt-regru --check
```
### 📞 Получение помощи
#### Техподдержка reg.ru
- **Email**: support@reg.ru
- **Телефон**: 8 (495) 580-11-11
- **Онлайн чат**: на сайте reg.ru
#### Документация
- **API reg.ru**: https://www.reg.ru/support/api
- **Примеры использования**: https://www.reg.ru/support/api/examples
- **FAQ по API**: https://www.reg.ru/support/api/faq
#### Логи для диагностики
Всегда включайте логи при обращении в поддержку:
```bash
## Включить подробные логи
sudo letsencrypt-regru --test-api -v
## Посмотреть последние логи
sudo tail -n 50 /var/log/letsencrypt-regru/letsencrypt_regru.log
## Логи certbot
sudo tail -n 50 /var/log/letsencrypt/letsencrypt.log
```
### 🔄 Альтернативные DNS провайдеры
Если проблемы с reg.ru API критичны, рассмотрите альтернативы:
1. **Cloudflare** - отличный API, бесплатный DNS
2. **Route53** (AWS) - мощный, но платный
3. **DigitalOcean DNS** - простой и надежный
4. **Google Cloud DNS** - интеграция с GCP
Для них потребуется модификация скрипта или использование других плагинов certbot.
---
**Дата обновления**: 29.10.2025
**Версия документа**: 1.0
+436 -436
View File
@@ -1,56 +1,56 @@
# Тестирование
Главная цель тестовых режимов — не упереться в лимиты Lets Encrypt и быстро проверять интеграции.
## Лимиты Lets Encrypt
- production: обычно 5 сертификатов/неделю на домен
- при частых ошибках можно быстро исчерпать лимит
## Варианты тестирования
### 1) Самоподписанный сертификат (рекомендуется для разработки)
- `letsencrypt-regru --test-cert`
Плюсы:
- мгновенно (12 секунды)
- без интернета
- без DNS
- структура файлов совпадает с Lets Encrypt (`cert.pem`, `fullchain.pem`, …)
Минусы:
- браузер не доверяет сертификату
### 2) Lets Encrypt staging
- `letsencrypt-regru --staging`
Плюсы:
- полностью реальный процесс ACME
- нет лимитов
- проверяет DNS хуки и certbot
Минусы:
- staging сертификаты не доверяются браузером
### 3) Диагностика API и DNS
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
Рекомендуется прогонять перед production получением.
## Переход тест → production
1) убедиться что всё работает на `--staging` или `--test-cert`
2) затем выполнить `--obtain`
Если ранее создавался тестовый сертификат и вы хотите «чисто» перейти на production, иногда удобно удалить старую папку сертификата для домена в `cert_dir/<domain>/` (аккуратно).
# Тестирование
Главная цель тестовых режимов — не упереться в лимиты Lets Encrypt и быстро проверять интеграции.
## Лимиты Lets Encrypt
- production: обычно 5 сертификатов/неделю на домен
- при частых ошибках можно быстро исчерпать лимит
## Варианты тестирования
### 1) Самоподписанный сертификат (рекомендуется для разработки)
- `letsencrypt-regru --test-cert`
Плюсы:
- мгновенно (12 секунды)
- без интернета
- без DNS
- структура файлов совпадает с Lets Encrypt (`cert.pem`, `fullchain.pem`, …)
Минусы:
- браузер не доверяет сертификату
### 2) Lets Encrypt staging
- `letsencrypt-regru --staging`
Плюсы:
- полностью реальный процесс ACME
- нет лимитов
- проверяет DNS хуки и certbot
Минусы:
- staging сертификаты не доверяются браузером
### 3) Диагностика API и DNS
- `letsencrypt-regru --test-api -v`
- `letsencrypt-regru --test-dns -v`
Рекомендуется прогонять перед production получением.
## Переход тест → production
1) убедиться что всё работает на `--staging` или `--test-cert`
2) затем выполнить `--obtain`
Если ранее создавался тестовый сертификат и вы хотите «чисто» перейти на production, иногда удобно удалить старую папку сертификата для домена в `cert_dir/<domain>/` (аккуратно).
---
@@ -58,386 +58,386 @@
## Appendix (migrated from docs/TESTING_GUIDE.md)
<!-- MIGRATED_FROM_DOCS:TESTING_GUIDE.md -->
## 🧪 Руководство по тестированию SSL сертификатов
### Зачем нужны тестовые сертификаты?
Let's Encrypt имеет **строгие ограничения**:
- ⚠️ Максимум **5 сертификатов в неделю** на один домен
- ⚠️ Максимум **50 сертификатов в неделю** на аккаунт
- ⚠️ **Бан на 1 неделю** при превышении лимита
**Решение**: Используйте самоподписанные тестовые сертификаты для разработки!
---
### Быстрый старт
#### Вариант 1: Через Makefile (рекомендуется)
```bash
## После установки скрипта (make install)
sudo make test-cert
```
**Результат**: Создан сертификат в `/etc/letsencrypt/live/your-domain/`
#### Вариант 2: Через Python скрипт
```bash
sudo python3 letsencrypt_regru_api.py \
--config /etc/letsencrypt/regru_config.json \
--test-cert -v
```
#### Вариант 3: Через Bash скрипт (автономный)
```bash
## Простой домен
sudo ./test_certificate.sh example.com no
## С wildcard
sudo ./test_certificate.sh example.com yes
```
---
### Сравнение методов
| Метод | Скорость | Требования | NPM интеграция | Лимиты |
|-------|----------|------------|----------------|--------|
| **Let's Encrypt** | 2-5 минут | Internet, DNS | ✅ Да | ⚠️ 5/неделю |
| **Тестовый (Python)** | 1-2 секунды | Только Python | ✅ Да | ✅ Нет |
| **Тестовый (Bash)** | 1-2 секунды | Только OpenSSL | ❌ Ручная | ✅ Нет |
---
### Детальная инструкция
#### 1. Подготовка конфигурации
```bash
## Создать конфигурацию
sudo nano /etc/letsencrypt/regru_config.json
```
```json
{
"domain": "test.example.com",
"wildcard": true,
"cert_dir": "/etc/letsencrypt/live",
"npm_enabled": true,
"npm_host": "https://npm.example.com",
"npm_email": "admin@example.com",
"npm_password": "your_password"
}
```
#### 2. Создание тестового сертификата
```bash
sudo make test-cert
```
#### 3. Проверка созданных файлов
```bash
ls -la /etc/letsencrypt/live/test.example.com/
## Должны быть:
## - privkey.pem (приватный ключ)
## - cert.pem (сертификат)
## - fullchain.pem (полная цепочка)
## - chain.pem (CA цепочка)
```
#### 4. Просмотр информации о сертификате
```bash
openssl x509 -in /etc/letsencrypt/live/test.example.com/cert.pem -text -noout
```
---
### Использование в Nginx
#### Прямое использование
```nginx
server {
listen 443 ssl;
server_name test.example.com;
ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem;
# ... остальная конфигурация
}
```
#### Через Nginx Proxy Manager
Если `npm_enabled: true` в конфигурации, сертификат автоматически загрузится в NPM.
**Проверка в NPM:**
1. Откройте веб-интерфейс NPM
2. Перейдите в **SSL Certificates**
3. Найдите ваш домен в списке
4. ⚠️ Будет помечен как "Custom" (не Let's Encrypt)
---
### Автоматизация тестирования
#### Скрипт для CI/CD
```bash
#!/bin/bash
## test_ssl_integration.sh
set -e
echo "🧪 Тестирование SSL интеграции..."
## 1. Создать тестовый сертификат
sudo python3 letsencrypt_regru_api.py \
--config test_config.json \
--test-cert
## 2. Проверить файлы
if [ ! -f "/etc/letsencrypt/live/test.example.com/fullchain.pem" ]; then
echo "❌ Сертификат не создан"
exit 1
fi
## 3. Проверить валидность
openssl x509 -in /etc/letsencrypt/live/test.example.com/cert.pem -noout -checkend 0
if [ $? -eq 0 ]; then
echo "✅ Сертификат валиден"
else
echo "❌ Сертификат невалиден"
exit 1
fi
## 4. Проверить загрузку в NPM (опционально)
## ... ваша проверка через API NPM
echo "✅ Все тесты пройдены"
```
#### Makefile для тестирования
```makefile
.PHONY: test-ssl test-npm test-all
test-ssl:
@echo "Создание тестового сертификата..."
sudo make test-cert
@echo "Проверка файлов..."
test -f /etc/letsencrypt/live/$(DOMAIN)/fullchain.pem
@echo "✅ SSL тест пройден"
test-npm:
@echo "Проверка интеграции с NPM..."
# Ваши проверки API NPM
@echo "✅ NPM тест пройден"
test-all: test-ssl test-npm
@echo "✅ Все тесты пройдены"
```
---
### Переход на production
#### Шаг 1: Тестирование
```bash
## 1. Создать тестовый сертификат
sudo make test-cert
## 2. Проверить работу с NPM
## Открыть https://your-domain и проверить
## 3. Убедиться что все работает
```
#### Шаг 2: Переключение на Let's Encrypt
```bash
## 1. Удалить тестовый сертификат
sudo rm -rf /etc/letsencrypt/live/your-domain/
## 2. Получить настоящий сертификат
sudo make obtain
## 3. Проверить обновление в NPM
sudo make status
```
---
### Частые вопросы
#### Q: Почему браузер показывает предупреждение?
**A:** Самоподписанные сертификаты не доверяются браузерами. Это нормально для тестирования.
Чтобы избежать предупреждения в браузере (только для локального тестирования):
1. Chrome: `chrome://flags/#allow-insecure-localhost`
2. Firefox: Нажмите "Advanced" → "Accept the Risk"
#### Q: Можно ли использовать для production?
**A:****НЕТ!** Тестовые сертификаты только для разработки и тестирования.
#### Q: Как часто можно создавать тестовые сертификаты?
**A:** ✅ Неограниченно! Нет никаких лимитов.
#### Q: Загружаются ли в NPM автоматически?
**A:** ✅ Да, если `npm_enabled: true` в конфигурации.
#### Q: Работают ли с wildcard доменами?
**A:** ✅ Да! Просто установите `"wildcard": true` в конфигурации.
#### Q: Как проверить срок действия?
```bash
openssl x509 -in /etc/letsencrypt/live/your-domain/cert.pem -noout -dates
```
#### Q: Как изменить срок действия?
Отредактируйте `validity_days` в функции `generate_self_signed_certificate()`:
```python
validity_days: int = 365 # Изменить на нужное количество дней
```
---
### Устранение проблем
#### Ошибка: Permission denied
```bash
## Запускайте с sudo
sudo make test-cert
```
#### Ошибка: Module 'cryptography' not found
```bash
## Установите зависимости
sudo pip3 install cryptography
```
#### NPM не показывает сертификат
1. Проверьте настройки NPM в конфигурации
2. Проверьте логи: `sudo make logs`
3. Попробуйте загрузить вручную через веб-интерфейс NPM
#### Сертификат не создается
```bash
## Проверьте права
ls -la /etc/letsencrypt/live/
## Создайте директорию вручную
sudo mkdir -p /etc/letsencrypt/live/
## Проверьте конфигурацию
sudo make check-config
```
---
### Примеры использования
#### Разработка с Docker
```dockerfile
FROM nginx:alpine
## Копировать тестовый сертификат
COPY test-certs/ /etc/nginx/ssl/
## Конфигурация nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 443
```
#### Локальное тестирование
```bash
## Создать сертификат для localhost
sudo python3 letsencrypt_regru_api.py --test-cert
## Добавить в /etc/hosts
echo "127.0.0.1 test.example.com" | sudo tee -a /etc/hosts
## Запустить nginx
sudo nginx -t && sudo nginx -s reload
## Открыть в браузере
open https://test.example.com
```
#### Автоматическое тестирование перед deployment
```bash
#!/bin/bash
## pre-deploy.sh
## Тестовая проверка SSL
sudo make test-cert
if [ $? -eq 0 ]; then
echo "✅ Тестовый сертификат создан успешно"
echo "✅ Готово к созданию production сертификата"
sudo make obtain
else
echo "❌ Ошибка при создании тестового сертификата"
exit 1
fi
```
---
### Дополнительные ресурсы
- 📘 [Let's Encrypt Rate Limits](https://letsencrypt.org/docs/rate-limits/)
- 📘 [OpenSSL Documentation](https://www.openssl.org/docs/)
- 📘 [Nginx Proxy Manager Docs](https://nginxproxymanager.com/guide/)
---
### Итоговая шпаргалка
```bash
## Установка
sudo make install
## Конфигурация
sudo nano /etc/letsencrypt/regru_config.json
## Создать тестовый сертификат
sudo make test-cert
## Проверить
sudo make check-config
sudo make status
## Переход на production
sudo rm -rf /etc/letsencrypt/live/your-domain/
sudo make obtain
## Автоматическое обновление
sudo make run
```
**Готово!** 🎉 Теперь вы можете тестировать SSL сертификаты без ограничений!
## 🧪 Руководство по тестированию SSL сертификатов
### Зачем нужны тестовые сертификаты?
Let's Encrypt имеет **строгие ограничения**:
- ⚠️ Максимум **5 сертификатов в неделю** на один домен
- ⚠️ Максимум **50 сертификатов в неделю** на аккаунт
- ⚠️ **Бан на 1 неделю** при превышении лимита
**Решение**: Используйте самоподписанные тестовые сертификаты для разработки!
---
### Быстрый старт
#### Вариант 1: Через Makefile (рекомендуется)
```bash
## После установки скрипта (make install)
sudo make test-cert
```
**Результат**: Создан сертификат в `/etc/letsencrypt/live/your-domain/`
#### Вариант 2: Через Python скрипт
```bash
sudo python3 letsencrypt_regru_api.py \
--config /etc/letsencrypt/regru_config.json \
--test-cert -v
```
#### Вариант 3: Через Bash скрипт (автономный)
```bash
## Простой домен
sudo ./test_certificate.sh example.com no
## С wildcard
sudo ./test_certificate.sh example.com yes
```
---
### Сравнение методов
| Метод | Скорость | Требования | NPM интеграция | Лимиты |
|-------|----------|------------|----------------|--------|
| **Let's Encrypt** | 2-5 минут | Internet, DNS | ✅ Да | ⚠️ 5/неделю |
| **Тестовый (Python)** | 1-2 секунды | Только Python | ✅ Да | ✅ Нет |
| **Тестовый (Bash)** | 1-2 секунды | Только OpenSSL | ❌ Ручная | ✅ Нет |
---
### Детальная инструкция
#### 1. Подготовка конфигурации
```bash
## Создать конфигурацию
sudo nano /etc/letsencrypt/regru_config.json
```
```json
{
"domain": "test.example.com",
"wildcard": true,
"cert_dir": "/etc/letsencrypt/live",
"npm_enabled": true,
"npm_host": "https://npm.example.com",
"npm_email": "admin@example.com",
"npm_password": "your_password"
}
```
#### 2. Создание тестового сертификата
```bash
sudo make test-cert
```
#### 3. Проверка созданных файлов
```bash
ls -la /etc/letsencrypt/live/test.example.com/
## Должны быть:
## - privkey.pem (приватный ключ)
## - cert.pem (сертификат)
## - fullchain.pem (полная цепочка)
## - chain.pem (CA цепочка)
```
#### 4. Просмотр информации о сертификате
```bash
openssl x509 -in /etc/letsencrypt/live/test.example.com/cert.pem -text -noout
```
---
### Использование в Nginx
#### Прямое использование
```nginx
server {
listen 443 ssl;
server_name test.example.com;
ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem;
# ... остальная конфигурация
}
```
#### Через Nginx Proxy Manager
Если `npm_enabled: true` в конфигурации, сертификат автоматически загрузится в NPM.
**Проверка в NPM:**
1. Откройте веб-интерфейс NPM
2. Перейдите в **SSL Certificates**
3. Найдите ваш домен в списке
4. ⚠️ Будет помечен как "Custom" (не Let's Encrypt)
---
### Автоматизация тестирования
#### Скрипт для CI/CD
```bash
#!/bin/bash
## test_ssl_integration.sh
set -e
echo "🧪 Тестирование SSL интеграции..."
## 1. Создать тестовый сертификат
sudo python3 letsencrypt_regru_api.py \
--config test_config.json \
--test-cert
## 2. Проверить файлы
if [ ! -f "/etc/letsencrypt/live/test.example.com/fullchain.pem" ]; then
echo "❌ Сертификат не создан"
exit 1
fi
## 3. Проверить валидность
openssl x509 -in /etc/letsencrypt/live/test.example.com/cert.pem -noout -checkend 0
if [ $? -eq 0 ]; then
echo "✅ Сертификат валиден"
else
echo "❌ Сертификат невалиден"
exit 1
fi
## 4. Проверить загрузку в NPM (опционально)
## ... ваша проверка через API NPM
echo "✅ Все тесты пройдены"
```
#### Makefile для тестирования
```makefile
.PHONY: test-ssl test-npm test-all
test-ssl:
@echo "Создание тестового сертификата..."
sudo make test-cert
@echo "Проверка файлов..."
test -f /etc/letsencrypt/live/$(DOMAIN)/fullchain.pem
@echo "✅ SSL тест пройден"
test-npm:
@echo "Проверка интеграции с NPM..."
# Ваши проверки API NPM
@echo "✅ NPM тест пройден"
test-all: test-ssl test-npm
@echo "✅ Все тесты пройдены"
```
---
### Переход на production
#### Шаг 1: Тестирование
```bash
## 1. Создать тестовый сертификат
sudo make test-cert
## 2. Проверить работу с NPM
## Открыть https://your-domain и проверить
## 3. Убедиться что все работает
```
#### Шаг 2: Переключение на Let's Encrypt
```bash
## 1. Удалить тестовый сертификат
sudo rm -rf /etc/letsencrypt/live/your-domain/
## 2. Получить настоящий сертификат
sudo make obtain
## 3. Проверить обновление в NPM
sudo make status
```
---
### Частые вопросы
#### Q: Почему браузер показывает предупреждение?
**A:** Самоподписанные сертификаты не доверяются браузерами. Это нормально для тестирования.
Чтобы избежать предупреждения в браузере (только для локального тестирования):
1. Chrome: `chrome://flags/#allow-insecure-localhost`
2. Firefox: Нажмите "Advanced" → "Accept the Risk"
#### Q: Можно ли использовать для production?
**A:****НЕТ!** Тестовые сертификаты только для разработки и тестирования.
#### Q: Как часто можно создавать тестовые сертификаты?
**A:** ✅ Неограниченно! Нет никаких лимитов.
#### Q: Загружаются ли в NPM автоматически?
**A:** ✅ Да, если `npm_enabled: true` в конфигурации.
#### Q: Работают ли с wildcard доменами?
**A:** ✅ Да! Просто установите `"wildcard": true` в конфигурации.
#### Q: Как проверить срок действия?
```bash
openssl x509 -in /etc/letsencrypt/live/your-domain/cert.pem -noout -dates
```
#### Q: Как изменить срок действия?
Отредактируйте `validity_days` в функции `generate_self_signed_certificate()`:
```python
validity_days: int = 365 # Изменить на нужное количество дней
```
---
### Устранение проблем
#### Ошибка: Permission denied
```bash
## Запускайте с sudo
sudo make test-cert
```
#### Ошибка: Module 'cryptography' not found
```bash
## Установите зависимости
sudo pip3 install cryptography
```
#### NPM не показывает сертификат
1. Проверьте настройки NPM в конфигурации
2. Проверьте логи: `sudo make logs`
3. Попробуйте загрузить вручную через веб-интерфейс NPM
#### Сертификат не создается
```bash
## Проверьте права
ls -la /etc/letsencrypt/live/
## Создайте директорию вручную
sudo mkdir -p /etc/letsencrypt/live/
## Проверьте конфигурацию
sudo make check-config
```
---
### Примеры использования
#### Разработка с Docker
```dockerfile
FROM nginx:alpine
## Копировать тестовый сертификат
COPY test-certs/ /etc/nginx/ssl/
## Конфигурация nginx
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 443
```
#### Локальное тестирование
```bash
## Создать сертификат для localhost
sudo python3 letsencrypt_regru_api.py --test-cert
## Добавить в /etc/hosts
echo "127.0.0.1 test.example.com" | sudo tee -a /etc/hosts
## Запустить nginx
sudo nginx -t && sudo nginx -s reload
## Открыть в браузере
open https://test.example.com
```
#### Автоматическое тестирование перед deployment
```bash
#!/bin/bash
## pre-deploy.sh
## Тестовая проверка SSL
sudo make test-cert
if [ $? -eq 0 ]; then
echo "✅ Тестовый сертификат создан успешно"
echo "✅ Готово к созданию production сертификата"
sudo make obtain
else
echo "❌ Ошибка при создании тестового сертификата"
exit 1
fi
```
---
### Дополнительные ресурсы
- 📘 [Let's Encrypt Rate Limits](https://letsencrypt.org/docs/rate-limits/)
- 📘 [OpenSSL Documentation](https://www.openssl.org/docs/)
- 📘 [Nginx Proxy Manager Docs](https://nginxproxymanager.com/guide/)
---
### Итоговая шпаргалка
```bash
## Установка
sudo make install
## Конфигурация
sudo nano /etc/letsencrypt/regru_config.json
## Создать тестовый сертификат
sudo make test-cert
## Проверить
sudo make check-config
sudo make status
## Переход на production
sudo rm -rf /etc/letsencrypt/live/your-domain/
sudo make obtain
## Автоматическое обновление
sudo make run
```
**Готово!** 🎉 Теперь вы можете тестировать SSL сертификаты без ограничений!
+15 -15
View File
@@ -1,15 +1,15 @@
# Навигация
- [Home](Home.md)
- [Установка](Installation.md)
- [Конфигурация](Configuration.md)
- [Команды](Commands.md)
- [Алгоритм получения/продления](LetsEncrypt_Workflow.md)
- [Интеграция с NPM](Nginx_Proxy_Manager.md)
- [Тестирование](Testing.md)
- [Проблемы API reg.ru](RegRu_API_Troubleshooting.md)
- [Сборка и релизы](Build_and_Release.md)
- [Deploy и Secrets](Deploy_Actions_Secrets.md)
- [Структура проекта](Project_Structure.md)
- [Синхронизация Gitea → GitHub](Gitea_Sync.md)
- [Changelog](Changelog.md)
# Навигация
- [Home](Home.md)
- [Установка](Installation.md)
- [Конфигурация](Configuration.md)
- [Команды](Commands.md)
- [Алгоритм получения/продления](LetsEncrypt_Workflow.md)
- [Интеграция с NPM](Nginx_Proxy_Manager.md)
- [Тестирование](Testing.md)
- [Проблемы API reg.ru](RegRu_API_Troubleshooting.md)
- [Сборка и релизы](Build_and_Release.md)
- [Deploy и Secrets](Deploy_Actions_Secrets.md)
- [Структура проекта](Project_Structure.md)
- [Синхронизация Gitea → GitHub](Gitea_Sync.md)
- [Changelog](Changelog.md)