Project

General

Profile

Feature #3006

Updated by Viacheslav Anzhiganov 28 days ago

Реализовать получение 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-challenge 
 - [ ] Реализова 


 # Условия 

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


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

 ![](ACME 
 [[ACME protocol schema.png) schema.svg]] 






 ## Программа на 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 

 ```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() 
 ``` 


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

 * [ ] https://github.com/torhve/lua-resty-letsencrypt 
 * [ ] https://github.com/auto-ssl/lua-resty-auto-ssl 

Back

Redmine Appliance - Powered by TurnKey Linux