Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как запустить HTTPS
HTTPS — это зашифрованный HTTP с использованием SSL/TLS протокола. Это критично для безопасности: передача данных шифруется, и пользователи видят, что сайт защищён. Рассмотрю несколько способов запуска HTTPS для Python приложений.
Что нужно для HTTPS
- SSL сертификат — подтверждает, что сайт принадлежит вам
- Приватный ключ — используется для расшифровки данных
- Веб-сервер, который поддерживает SSL/TLS
Способ 1: Self-signed сертификат (для разработки)
Для локальной разработки можно создать самоподписанный сертификат:
# Генерируем приватный ключ и сертификат на 365 дней
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
# При запросе информации можно нажимать Enter или вводить данные
# Country Name: RU
# State: Moscow
# Locality: Moscow
# Organization Name: MyCompany
# Common Name: localhost
Теперь у вас есть cert.pem (сертификат) и key.pem (ключ).
Способ 2: FastAPI с HTTPS локально
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/api/hello")
async def hello():
return {"message": "Это защищённый HTTPS endpoint"}
if __name__ == "__main__":
# Запуск с самоподписанным сертификатом
uvicorn.run(
app,
host="127.0.0.1",
port=8443,
ssl_keyfile="key.pem", # Путь к приватному ключу
ssl_certfile="cert.pem", # Путь к сертификату
ssl_keyfile_password=None # Если ключ не зашифрован
)
Запуск:
python app.py
# Сервер запустится на https://127.0.0.1:8443
Тестирование (проигнорируем самоподписанный сертификат):
curl -k https://127.0.0.1:8443/api/hello
# или в Python
import requests
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
response = requests.get("https://127.0.0.1:8443/api/hello", verify=False)
print(response.json())
Способ 3: Flask с HTTPS
from flask import Flask
app = Flask(__name__)
@app.route("/api/hello", methods=["GET"])
def hello():
return {"message": "Защищённый endpoint"}
if __name__ == "__main__":
# Запуск с SSL
app.run(
host="127.0.0.1",
port=8443,
ssl_context=("cert.pem", "key.pem") # (сертификат, ключ)
)
Способ 4: Let's Encrypt для продакшена
Для боевого сервера используем Let's Encrypt — бесплатные сертификаты, которые автоматически обновляются.
Установка Certbot (инструмент для Let's Encrypt):
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx # или python3-certbot-apache
Получение сертификата для домена:
sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
# Сертификаты будут в:
# /etc/letsencrypt/live/yourdomain.com/fullchain.pem (сертификат)
# /etc/letsencrypt/live/yourdomain.com/privkey.pem (ключ)
Использование в Python:
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/api/hello")
async def hello():
return {"message": "Защищённый endpoint на боевом сервере"}
if __name__ == "__main__":
uvicorn.run(
app,
host="0.0.0.0",
port=443, # Стандартный порт для HTTPS
ssl_keyfile="/etc/letsencrypt/live/yourdomain.com/privkey.pem",
ssl_certfile="/etc/letsencrypt/live/yourdomain.com/fullchain.pem"
)
Автоматическое обновление сертификата (cron):
# Добавляем в crontab
sudo crontab -e
# Добавляем строку (проверяет обновление сертификата каждый день в 3 утра)
0 3 * * * /usr/bin/certbot renew --quiet
Способ 5: Nginx как reverse proxy
Это рекомендуемый подход — Nginx обрабатывает SSL, Python работает на localhost.
1. Генерируем сертификат:
sudo certbot certonly --nginx -d yourdomain.com
2. Конфигурируем Nginx:
upstream fastapi_app {
server 127.0.0.1:8000; # Python приложение слушает локально
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Редирект с HTTP на HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# SSL сертификаты от Let's Encrypt
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# Безопасные параметры SSL
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# HSTS — принудительно использовать HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Проксируем запросы на Python приложение
location / {
proxy_pass http://fastapi_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
3. Запускаем Python приложение обычно:
uvicorn app:app --host 127.0.0.1 --port 8000
4. Перезагружаем Nginx:
sudo systemctl reload nginx
Теперь https://yourdomain.com будет работать с полной шифровацией.
Способ 6: Docker с HTTPS
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Копируем сертификаты
COPY cert.pem /app/cert.pem
COPY key.pem /app/key.pem
EXPOSE 8443
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8443", "--ssl-keyfile=/app/key.pem", "--ssl-certfile=/app/cert.pem"]
docker-compose.yml:
version: '3.9'
services:
api:
build: .
ports:
- "8443:8443"
volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro # Монтируем сертификаты от хоста
Важные правила безопасности
- Никогда не коммитьте ключи — добавьте в
.gitignore:
key.pem
privkey.pem
*.key
- Защищайте сертификаты — ограничивайте права доступа:
chmod 600 key.pem # Только владелец может читать
- Используйте сильные цифровые подписи:
# В продакшене всегда требуйте HTTPS
from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
app.add_middleware(TrustedHostMiddleware, allowed_hosts=["yourdomain.com"])
Проверка HTTPS
# Проверка сертификата
openssl s_client -connect yourdomain.com:443
# Просмотр информации о сертификате
openssl x509 -in cert.pem -text -noout
# Проверка срока действия
openssl x509 -in cert.pem -noout -dates
Вывод
- Локально: самоподписанные сертификаты + uvicorn/Flask с SSL
- Боевой сервер: Let's Encrypt + Nginx как reverse proxy
- Docker: пробрасываем сертификаты как volumes
Найпо современный и безопасный подход — использовать Nginx + Let's Encrypt. Python приложение работает на localhost без SSL, а Nginx занимается шифрованием и редиректом с HTTP на HTTPS.