TLS шифрует соединение и до первого байта http даёт клиенту
проверить, что сервер — тот, за кого себя выдаёт. Для этого сервер
показывает сертификат: открытый ключ, имена сайта и
срок, заверенные подписью центра сертификации.
Парный закрытый ключ лежит только на сервере.
$ openssl x509 -in site.pem -noout -subject -issuer -dates \
-ext subjectAltName
subject=CN = secure.lab.test
issuer=CN = Lab Intermediate CA
notBefore=Oct 20 10:04:50 2026 GMT
notAfter=Nov 19 10:04:50 2026 GMT
X509v3 Subject Alternative Name:
DNS:secure.lab.test
subject — кому выдан, issuer — кто подписал, notBefore/notAfter — срок,
SAN — имена, для которых сертификат годен.
Три проверки клиента
| Проверка |
Что сверяет |
Ошибка curl |
| доверие |
цепочка подписей доходит до CA из хранилища |
unable to get local issuer certificate |
| имя |
имя из адреса есть в SAN |
no alternative certificate subject name matches |
| срок |
сейчас между notBefore и notAfter |
certificate has expired |
Любая не прошла — curl выходит с кодом 60, браузер показывает страницу ошибки.
curl -k отключает все три: соединение шифруется, но с кем — неизвестно.
Цепочка и доверие
Сертификат сайта обычно подписан не корнем, а
промежуточным CA, а тот — корневым. Корень
подписан сам собой (subject = issuer), и ему
верят потому, что он лежит в хранилище доверия клиента. В
Ubuntu это /etc/ssl/certs; свой корень туда добавляет
update-ca-certificates, для одного запроса — curl --cacert ca.pem.
Клиент знает только корни. Промежуточный ему присылает сервер, вместе с
сертификатом сайта — это цепочка. Сервер отдал один
сертификат сайта — клиент не может дойти до корня и пишет
unable to get local issuer certificate, хотя корень у него есть.
Ключ, запрос, сертификат
Файлы PEM — текст между строками -----BEGIN …----- и -----END …-----,
внутри base64. По первой строке видно, что в файле:
| Первая строка |
Что это |
-----BEGIN PRIVATE KEY----- |
закрытый ключ |
-----BEGIN CERTIFICATE REQUEST----- |
запрос CSR |
-----BEGIN CERTIFICATE----- |
сертификат |
Сертификат выпускают из запроса (CSR): в нём открытый ключ и
нужные имена. CA подписывает запрос и возвращает сертификат. Новый запрос на
прежний ключ даёт новый сертификат без смены ключа.