rubric/modules/infosecmodules/infosec_pki.go
2026-07-21 14:52:55 +03:00

230 lines
9.7 KiB
Go
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package infosecmodules
import (
"rubric/utils"
)
var PkiModule = Module{
Key: "pki",
Aliases: []string{"pk", "tls", "ssl", "certs"},
Title: "PKI, TLS и сертификаты",
Description: "PKI, X.509, TLS/SSL, цепочки доверия, Let's Encrypt, управление сертификатами",
Run: showPki,
}
func showPki() {
utils.Header("InfoSec — PKI, TLS и сертификаты")
utils.Section("PKI — инфраструктура открытых ключей")
utils.Code(`PKI (Public Key Infrastructure) — система для управления цифровыми сертификатами.
Компоненты:
CA (Certificate Authority) — удостоверяющий центр
Root CA — корневой CA (самоподписанный, доверяем принудительно)
Intermediate CA — промежуточный CA (подписан Root CA)
Certificate — сертификат (публичный ключ + метаданные, подписанные CA)
CRL (Certificate Revocation List) — список отозванных сертификатов
OCSP (Online Certificate Status Protocol) — онлайн-проверка статуса
Цепочка доверия:
Root CA → Intermediate CA → End-Entity Certificate (ваш сайт)
Браузер доверяет Root CA (встроен в ОС/браузер).
Root CA подписал Intermediate CA.
Intermediate CA подписал ваш сертификат.
Браузер верифицирует всю цепочку.
Публичные CA:
Let's Encrypt — бесплатный, автоматический
DigiCert — коммерческий
Sectigo — коммерческий
GlobalSign — коммерческий`)
utils.Section("X.509 сертификат")
utils.Code(`X.509 — стандартный формат цифровых сертификатов.
Поля сертификата:
Version — версия (обычно 3)
Serial Number — уникальный номер
Issuer — кто выдал (CA)
Subject — для кого (CN, O, OU, C...)
Validity — срок действия (Not Before / Not After)
Public Key — публичный ключ и алгоритм
Extensions — расширения (SANs, Key Usage, EKU...)
Signature — подпись CA
Subject Alternative Names (SANs):
Поле для нескольких доменов/IP в одном сертификате.
Обязательно с 2017 года (CN игнорируется браузерами).
Пример: DNS:example.com, DNS:*.example.com, IP:1.2.3.4
Типы сертификатов:
DV (Domain Validation) — подтверждает владение доменом
OV (Organization Validation) — подтверждает организацию
EV (Extended Validation) — расширенная проверка (зелёный замок)
Wildcard *.example.com — все субдомены одного уровня
# Просмотр сертификата:
openssl x509 -in cert.pem -text -noout
openssl s_client -connect example.com:443 -showcerts
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates`)
utils.Section("TLS — протокол Transport Layer Security")
utils.Code(`TLS — криптографический протокол для защиты соединений.
HTTPS = HTTP + TLS.
История версий:
SSL 2.0 / 3.0 — СЛОМАНЫ, не использовать
TLS 1.0 / 1.1 — устарели, отключены в браузерах с 2020
TLS 1.2 — приемлемо, широко используется
TLS 1.3 — текущий стандарт, быстрее и безопаснее
TLS 1.3 улучшения:
- 1-RTT handshake (вместо 2-RTT в 1.2)
- 0-RTT resumption (возможна реплей-атака, осторожно)
- Убраны ненадёжные алгоритмы (RC4, MD5, SHA-1, RSA key exchange)
- PFS обязателен (все cipher suites используют ECDHE)
TLS 1.2 Handshake:
1. ClientHello — версии, cipher suites, random
2. ServerHello — выбор версии/cipher, сертификат
3. Key Exchange — обмен ключами (DHE/ECDHE)
4. Finished — проверка, начало передачи данных`)
utils.Println(utils.ColorBold + "Cipher Suites — наборы алгоритмов:" + utils.ColorReset)
utils.Code(`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Расшифровка:
TLS — протокол
ECDHE — обмен ключами (PFS!)
RSA — аутентификация сервера
AES_256_GCM — шифрование (AEAD)
SHA384 — HMAC / PRF
Рекомендованные (TLS 1.2):
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS 1.3 (фиксированный набор):
TLS_AES_256_GCM_SHA384
TLS_AES_128_GCM_SHA256
TLS_CHACHA20_POLY1305_SHA256`)
utils.Section("Управление сертификатами")
utils.Code(`# Генерация CSR (Certificate Signing Request):
# 1. Сгенерировать приватный ключ:
openssl genrsa -out server.key 4096
# или Ed25519:
openssl genpkey -algorithm Ed25519 -out server.key
# 2. Сгенерировать CSR:
openssl req -new -key server.key -out server.csr \
-subj "/CN=example.com/O=MyOrg/C=RU"
# 3. Добавить SAN в CSR:
openssl req -new -key server.key -out server.csr \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com,IP:1.2.3.4"
# Самоподписанный сертификат (для тестирования):
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
-days 365 -nodes \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
# Проверить CSR:
openssl req -text -noout -in server.csr
# Проверить сертификат:
openssl x509 -text -noout -in server.crt
openssl verify -CAfile ca-chain.pem server.crt
# Проверить что ключ соответствует сертификату:
openssl x509 -noout -modulus -in server.crt | md5sum
openssl rsa -noout -modulus -in server.key | md5sum`)
utils.Section("Let's Encrypt и ACME")
utils.Code(`Let's Encrypt — бесплатный автоматический CA.
ACME — протокол автоматической выдачи сертификатов.
# Certbot (стандартный клиент):
certbot --nginx -d example.com -d www.example.com # Nginx
certbot --apache -d example.com # Apache
certbot certonly --standalone -d example.com # standalone
certbot certonly --dns-cloudflare -d "*.example.com" # wildcard через DNS
# Автоообновление (systemd timer или cron):
certbot renew --dry-run # проверить
# Systemd timer создаётся автоматически certbot-ом
# Файлы сертификата:
/etc/letsencrypt/live/example.com/
cert.pem — сертификат домена
chain.pem — промежуточные CA
fullchain.pem — cert + chain (для nginx/apache)
privkey.pem — приватный ключ
# acme.sh — альтернативный клиент:
curl https://get.acme.sh | sh
acme.sh --issue -d example.com --webroot /var/www/html
acme.sh --install-cert -d example.com \
--cert-file /etc/nginx/ssl/cert.pem \
--key-file /etc/nginx/ssl/key.pem \
--fullchain-file /etc/nginx/ssl/fullchain.pem \
--reloadcmd "nginx -s reload"`)
utils.Section("Собственный CA (Internal PKI)")
utils.Code(`# Создание Root CA:
mkdir -p ca/{certs,crl,newcerts,private}
chmod 700 ca/private
touch ca/index.txt
echo 1000 > ca/serial
openssl genrsa -aes256 -out ca/private/ca.key 4096
chmod 400 ca/private/ca.key
openssl req -new -x509 -days 3650 -key ca/private/ca.key \
-out ca/certs/ca.crt \
-subj "/C=RU/O=MyOrg/CN=MyOrg Root CA"
# Подпись сертификата своим CA:
openssl x509 -req -in server.csr \
-CA ca/certs/ca.crt -CAkey ca/private/ca.key \
-CAcreateserial -out server.crt \
-days 365 -extensions v3_req
# Распространение Root CA:
# Linux: cp ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates
# Windows: Сертификаты → Доверенные корневые центры
# cert-manager (Kubernetes):
# Автоматическое управление сертификатами в K8s
# Поддерживает Let's Encrypt, Vault, собственный CA`)
utils.Section("Проверка TLS конфигурации")
utils.Code(`# SSL Labs — онлайн тест:
# https://www.ssllabs.com/ssltest/
# testssl.sh — локальный тест:
testssl.sh example.com
testssl.sh --protocols example.com # только протоколы
testssl.sh --cipher-per-proto example.com
# nmap:
nmap --script ssl-enum-ciphers -p 443 example.com
# Проверить с командной строки:
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
curl -vI https://example.com 2>&1 | grep -E "TLS|SSL|cipher"
# Проверить дату истечения:
echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -enddate
# Проверить HSTS:
curl -sI https://example.com | grep -i strict`)
utils.Footer()
}