Estou tentando configurar o stunnel
para fornecer um wrapper TLS para um serviço HTTP que não suporta originalmente o TLS. Eu tenho isso funcionando bem sem usar certificados de cliente TLS.
Ao adicionar a configuração do certificado de cliente:
CAfile = /path/to/trusted.crt
verify = 4
Não consigo me conectar usando openssl s_client
. (Observe que estou trapaceando um pouco - usando também o certificado do meu servidor TLS como o certificado do cliente, mas o certificado diz que tem uma extensão para X509v3 Extended Key Usage: TLS Web Client Authentication, TLS Web Server Authentication
, então acho que isso deve funcionar.)
$ openssl s_client -state -connect [my-host-name]:[port] -cert [my-host-name].crt -key [my-host-name].key-nopass
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 C = IL, O = StartCom Ltd., OU = Secure Digital Certificate Signing, CN = StartCom Certification Authority
verify return:1
depth=1 C = IL, O = StartCom Ltd., OU = StartCom Certification Authority, CN = StartCom Class 1 DV Server CA
verify return:1
depth=0 CN = [my-hostname]
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:unknown CA
SSL_connect:failed in SSLv3 read server session ticket A
140391435724640:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1293:SSL alert number 48
140391435724640:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:
---
Certificate chain
0 s:/CN=[my-host-name]
i:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
1 s:/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
2 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=/CN=[my-host-name]
issuer=/C=IL/O=StartCom Ltd./OU=StartCom Certification Authority/CN=StartCom Class 1 DV Server CA
---
Acceptable client certificate CA names
/C=[the actual client cert I'd like to use]
/CN=[my-host-name] (for testing)
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 5620 bytes and written 1937 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 3072 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : ECDHE-RSA-AES256-SHA
Session-ID:
Session-ID-ctx:
Master-Key: [...]
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1465393332
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
(A conexão está fechada neste momento.)
Se eu definir verify = 0
na configuração do stunnel, a conexão será bem-sucedida e eu posso fazer uma solicitação. Se eu definir verify = 1
na configuração stunnel
, a conexão será cancelada se eu fornecer um certificado de cliente, mas aceito se eu não fornecer um.
Portanto, parece que algo está errado com o próprio certificado (para testes, é o mesmo certificado usado para o servidor TLS, portanto, não acho que haja algo errado com ele) ou minha configuração de como verificar o certificado.
Gostaria de verificar apenas os certificados que realmente aparecem no meu arquivo trusted.crts
. Essas linhas de depuração me levam a acreditar que eu especifiquei os certificados corretamente (isso é resultado do cliente):
Acceptable client certificate CA names
/C=[the actual client cert I'd like to use]
/CN=[my-host-name] (for testing)
Como o meu certificado para testes aparece nessa lista, espero que seja bem aceitável.
Não tenho certeza do que sinto falta.
Em /var/log/secure
, stunnel
está registrando:
Jun 8 13:58:59 ip-10-0-0-176 stunnel: LOG5[17497:139964729063168]: Service [mysvc] accepted connection from 52.203.5.20:57224
Jun 8 13:58:59 ip-10-0-0-176 stunnel: LOG4[17497:139964729063168]: CERT: Verification error: unable to get local issuer certificate
Jun 8 13:58:59 ip-10-0-0-176 stunnel: LOG4[17497:139964729063168]: Certificate check failed: depth=0, /CN=[my-host-name]
Jun 8 13:58:59 ip-10-0-0-176 stunnel: LOG3[17497:139964729063168]: SSL_accept: 140890B2: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
Jun 8 13:58:59 ip-10-0-0-176 stunnel: LOG5[17497:139964729063168]: Connection reset: 0 byte(s) sent to SSL, 0 byte(s) sent to socket
Parece que stunnel
está tentando verificar o certificado em relação a uma CA, em vez de confiar diretamente no certificado que está no meu arquivo trusted.crts
.
Alguma sugestão?
UPDATE
Se eu deixar verify = 4
no arquivo de configuração stunnel
, mas colocar o certificado pai do certificado de cliente (o da StartCom) no arquivo trusted.crts
, posso conectar usando meu certificado de teste. Se eu mudar para usar verify = 3
com o certificado de teste e seu signatário no arquivo trusted.crts
, novamente não consigo me conectar.
Existe uma maneira de dar ao stunnel
o (s) certificado (s) exato (s) que estou disposto a aceitar dos clientes? A documentação sugere que usar verify = 3
ou verify = 4
é a maneira de fazer isso, mas não consigo fazer isso funcionar da maneira que acho que deveria ser possível.
Tags tls ssl-certificate stunnel