Project

General

Profile

Actions

Feature #3006

open

ACME Protocol Support

Added by Viacheslav Anzhiganov 28 days ago. Updated 19 days ago.

Status:
In Progress
Priority:
Normal
Target version:
Start date:
11/09/2025
Due date:
% Done:

0%

Estimated time:
(Total: 0:00 h)

Description

Реализовать получение SSL-сертификатов по протоколу ACME для получения SSL-сертификатов Let'a Encrypt - ACME Protocol Support

Based on perplexity promt: https://www.perplexity.ai/search/napishi-programmu-na-python-ko-Ak_4QyRdS0OpFM1reQ6dRg

Условия

  • На сервере ACME LetsEncrypt есть лимиты по запросам с одного IP
  • Необходимо стремиться к минимальному количеству неуспешных запросов к Acme серверу
  • перед отправкой запорса к ACME-серверу Необходимо убедиться в том, что хост, для которого запрашивается SSL-сертификат был прописан на сервера ProCDN

Схема работы службы Cert для получения Lets encrytp SSL

Программа на Python для получения SSL-сертификата Let's Encrypt по ACME и сохранения в БД

Ниже приведён пример программы, которая:

  • Использует библиотеку acme для взаимодействия с Let's Encrypt по протоколу ACME.
  • Проходит HTTP-01 challenge для валидации домена.
  • Получает SSL-сертификат.
  • Сохраняет сертификат и приватный ключ в базу данных PostgreSQL в формате PEM.

Основные зависимости

  • acme (часть certbot): для работы с ACME-протоколом.
  • cryptography: для генерации ключей и создания CSR.
  • psycopg2 или asyncpg: для работы с PostgreSQL.

Пример кода

python

import time
import psycopg2
from acme import client, messages, challenges
from acme import crypto_util
from josepy import JWKRSA
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend

# Константы
DIRECTORY_URL = 'https://acme-v02.api.letsencrypt.org/directory'
DOMAIN = 'example.com'
EMAIL = 'admin@example.com'

# 1. Генерируем ключ пользователя
user_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)
jwk = JWKRSA(key=user_key)

# 2. Создаём клиента ACME
net = client.ClientNetwork(jwk)
directory = client.ClientV2.get_directory(DIRECTORY_URL, net)
acme_client = client.ClientV2(directory, net=net)

# 3. Регистрируем аккаунт
account = acme_client.new_account(
    messages.NewRegistration.from_data(
	    email=EMAIL,
	    terms_of_service_agreed=True
	)
)

# 4. Запрашиваем авторизацию для домена
order = acme_client.new_order(
	csr_pem=None,
	identifiers=[
		messages.Identifier(
			typ=messages.IDENTIFIER_FQDN,
			value=DOMAIN
		)
	]
)
authz = order.authorizations[0]
challenge = next(c for c in authz.body.challenges if isinstance(c.chall, challenges.HTTP01))

# 5. Вам нужно разместить challenge token на вашем сервере по адресу /.well-known/acme-challenge/{token}
# challenge.chall.path, challenge.chall.validation(jwk)
# Этот шаг требует настройки веб-сервера!

# 6. Отвечаем на challenge
acme_client.answer_challenge(challenge, challenge.chall.response(jwk))

# 7. Ожидаем подтверждения авторизации
while True:
    authz = acme_client.poll(authz)[0]
    if authz.body.status == 'valid':
        break
    time.sleep(2)

# 8. Генерируем ключ для сертификата и CSR
cert_key = crypto_util.make_key(bits=2048)
csr_pem = crypto_util.make_csr(cert_key, [DOMAIN])

# 9. Запрашиваем выпуск сертификата
final_order = acme_client.finalize_order(order, csr_pem)
certificate_pem = acme_client.fetch_chain(final_order)[0].public_bytes().decode()

# 10. Сохраняем сертификат и ключ в PostgreSQL
conn = psycopg2.connect("dbname=yourdb user=youruser password=yourpass")
cur = conn.cursor()
cur.execute("""
    INSERT INTO certificates (domain, cert_pem, key_pem)
    VALUES (%s, %s, %s)
""", (DOMAIN, certificate_pem, cert_key.decode()))
conn.commit()
cur.close()
conn.close()

ссылки по теме


Files

ACME_protocol_schema.png (25.6 KB) ACME_protocol_schema.png Viacheslav Anzhiganov, 11/08/2025 09:17 PM

Subtasks 4 (4 open0 closed)

web-ui-console - Feature #3008: Поддержка Letsencrypt сертификатов для подключаемых доменовNew11/09/2025

Actions
api-certs - Feature #3009: Реализация поддержки SSL-сертификатов полученных через ACME протоколIn ProgressViacheslav Anzhiganov11/09/2025

Actions
api-config - Feature #3010: Реализовать конфиг-сниппет для nginx для поддер ACME-протоколаNew11/09/2025

Actions
api-certs - Feature #3015: implement celery tasks supportNew11/17/2025

Actions
Actions

Also available in: Atom PDF

Redmine Appliance - Powered by TurnKey Linux