REST con ssl

Hola Roberto,

Es a partir del certificado del cliente, ya que se usa para matchearlo.

servidor.ini
autenticacion = ssl

virtualhost sw.unpa.edu.ar.conf


<VirtualHost 192.168.10.241:443>

    ServerName sw.unpa.edu.ar
    Include /home/roberto/toba_2.7.2/vendor/siu-toba/framework/instalacion/toba.conf
 
    SSLEngine on


     SSLVerifyClient require
    SSLOptions +StdEnvVars +ExportCertData   

    
    SSLCertificateFile /home/roberto/certificados/CA/certificados/hubservicios.crt
    SSLCertificateKeyFile /home/roberto/certificados/CA/privado/hubservicios.key
    SSLCertificateChainFile /home/roberto/certificados/CA/certificados/ca.crt
    
</VirtualHost> 

En la aplicación cliente que consume los web service tenemos los siguiente

cliente.ini


[conexion]
;;Recuerde dejar una barra (/) al finalizar la URL
to = "https://sw.unpa.edu.ar/hub_servicios/1.0/rest/"
auth_tipo = "ssl"
cert_file = "/home/roberto/certificados/CA/certificados/hubservicios.crt"
key_file = "/home/roberto/certificados/CA/privado/hubservicios.key"
ca_cert= "/home/roberto/certificados/CA/certificados/ca.crt"

Pregunta: los certificados que hay que referenciar aquí son los del servidor de servicios web?
NO, el cliente.ini lo tenes en tu maquina cliente...si vas a llamar un WS de Banelco por ejemplo, tenes que mandarle tus certificados... no poner los de ellos, dicho sea de paso.. no creo que consigas la PK de Banelco ni a punta de pistola, ese es un buen parametro para saber que tenes que poner.
virtualhost tarjeta.unpa.edu.ar.conf

<VirtualHost 192.168.10.241:443>
    ServerName tarjeta.unpa.edu.ar
    Include /home/roberto/toba_2.7.2/vendor/siu-toba/framework/instalacion/toba.conf

    SSLEngine on
    SSLCertificateFile /home/roberto/certificados/CA/certificados/cliente.crt
    SSLCertificateKeyFile /home/roberto/certificados/CA/privado/cliente.key
    SSLCertificateChainFile /home/roberto/certificados/CA/certificados/ca.crt

</VirtualHost> 

Este servidor a que corresponderia?, hay cruzamiento de WS entre ellos?.
Los certificados estamos seguros que funcionan, hemos hecho las siguientes pruebas para corroborar que permiten verificar la identidad de cada uno: curl --cacert /home/roberto/certificados/CA/certificados/ca.crt -E /home/roberto/certificados/CA/cliente.pem https://tarjeta.unpa.edu.ar curl -v --cacert /home/roberto/certificados/CA/certificados/ca.crt https://tarjeta.unpa.edu.ar
De la configuracion anterior, pareciera que le estas enviando al servidor sus propios certificados.. esto es asi?.
Estos comandos los hemos ejecutado para cada servidor. Con el sitio cliente tarjeta.unpa.edu.ar, los comando retornaron resultado satisfactorio. Sin embargo para el caso del servidor sw.unpa.edu.ar, con las variables: SSLVerifyClient y SSLOptions, seteadas, los comandos fallan. Cuando las quitamos, los comandos de verificación retornan resultado satisfactorio.
Cuando las quitas, no se esta verficando nada.. porque Apache no esta esperando recibir ningun certificado desde el cliente.. por lo que da lo mismo.
Algo similar ocurre al ejecutar la aplicación cliente. Cuando invocamos un web services desde el cliente, y el servidor posee las variables SSLVerifyClient y SSLOptions seteadas, retorna el siguiente error:

* Hostname was NOT found in DNS cache
*   Trying 192.168.10.241...
* Connected to sw.unpa.edu.ar (192.168.10.241) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /home/roberto/certificados/CA/certificados/ca.crt
  CApath: /etc/ssl/certs
* error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
* Closing connection 0
PHP Fatal error:  Uncaught exception 'GuzzleHttp\Ring\Exception\ConnectException' with message 'cURL error 35: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca' in /home/roberto/toba_2.7.2/vendor/guzzlehttp/ringphp/src/Client/CurlFactory.php:126

Esta perfecto el error, salvo que tu CA este dentro de las que CURL conoce o confia.
Cuando quitamos las variables de la configuración del virtualhost del servidor, la verificación de certificados entendemos que funciona, pero lanza una excepción de acceso no autorizado:

* Hostname was NOT found in DNS cache
*   Trying 192.168.10.241...
* Connected to sw.unpa.edu.ar (192.168.10.241) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /home/roberto/certificados/CA/certificados/ca.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*        subject: C=AR; ST=SANTA CRUZ; L=RIO GALLEGOS; O=UNPA; OU=PSTI; CN=sw.unpa.edu.ar; emailAddress=huelemu@unpa.edu.ar
*        start date: 2017-03-15 19:42:53 GMT
*        expire date: 2018-03-15 19:42:53 GMT
*        common name: sw.unpa.edu.ar (matched)
*        issuer: C=AR; ST=SANTA CRUZ; L=RIO GALLEGOS; O=UNPA; OU=PSTI; CN=www.unpa.edu.ar; emailAddress=huelemu@unpa.edu.ar
*        SSL certificate verify ok.
> GET /hub_servicios/1.0/rest/mapuche/agentes/29058990 HTTP/1.1
Host: sw.unpa.edu.ar
User-Agent: Guzzle/5.1.0 curl/7.38.0 PHP/5.6.24-0+deb8u1

< HTTP/1.1 401 Unauthorized
< Date: Thu, 16 Mar 2017 16:24:59 GMT
* Server Apache/2.4.10 (Debian) is not blacklisted
< Server: Apache/2.4.10 (Debian)
< API-Version: 1.0.0
< Content-Length: 85
< Content-Type: application/json
< 
* Connection #0 to host sw.unpa.edu.ar left intact
PHP Fatal error:  Uncaught exception 'GuzzleHttp\Exception\ClientException' with message 'Client error response [url] https://sw.unpa.edu.ar/hub_servicios/1.0/rest/mapuche/agentes/29058990 [status code] 401 [reason phrase] Unauthorized'

De acuerdo a la documentación de wiki, dichas variables son obligatorias para permitir el intercambio de certificados. Quizás nos estemos pasando por alto un paso para que funcione, pero no hemos podido encontrarle la vuelta


Si sacas las variables esas, Apache no verifica nada, no le devuelve a la libreria REST la informacion del certificado y por tanto no puede saber a que cliente pertenece la conexion, ergo te devuelve un 401. No es bueno que pruebes este tipo de cosas en la misma maquina, salvo que tengas bien diferenciado cada lado, incluso asi… no alcanzas a notar cuestiones sobre la confiabilidad de la CA. Si podes usar Docker para correr esto de manera aislada mejor y que cada contenedor tenga su certificado y CA propia si podes.

Para mi lo que te falta es separar mejor cada rol, ahi vas a ver bien que configuracion de certificados va de que lado. Y por otra parte, como estas trabajando con CAs autofirmadas tenes que registrarlas para que CURL confie en ellas, en linux via el comando update-ca-certificates.

Saludos