Jenkins utilisant JNLP derrière le proxy inverse SSL nginx

0

J'aimerais utiliser JNLP pour connecter des esclaves Jenkins au maître Jenkins. Le maître s'exécute derrière un proxy SSL nginx configuré conformément à la documentation officielle . Au-delà de cette documentation, je rencontre des problèmes liés aux certificats.

Actuellement, je peux faire en sorte que la connexion principale de l'esclave sans tête JNLP fonctionne uniquement avec une connexion HTTP non sécurisée, mais pas avec HTTPS (bien que mon tableau de bord jenkins fonctionne généralement). J'utilise un certificat auto-signé, signé par mon propre certificat CA personnalisé (basé sur OpenSSL x509).

Alors, comment puis-je dire au binaire java de mon esclave de faire confiance à mon certificat SSL CA? J'ai essayé ça.

# add CA certificate to key store
$ keytool -import -file /usr/local/share/ca-certificates/my_ca.crt -alias my_ca -storepass mypassword

# try to reference keystore to JNLP headless call
$ java -Djavax.net.ssl.keyStorePassword=mypassword -Djavax.net.ssl.keyStore=/home/myuser/.keystore -jar slave.jar -jnlpUrl https://proxied-jenkins.example.com/computer/testslave/slave-agent.jnlp

En réalité, JAVA ne semble pas rechercher le certificat dans le fichier de clés fourni. Quelle est mon erreur ici?

MODIFIER

Un problème similaire / même se produit lors de l'utilisation de jenkins cli. D'après cela , maintenant, je suppose que cela n'a rien à voir avec la confiance en mon certificat, car je ne peux pas voir unjavax.net.ssl.SSLHandshakeException

Je viens de recevoir une réinitialisation de la connexion

Failing to obtain https://proxied-jenkins.example.com/computer/testslave/slave-agent.jnlp
java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
    at hudson.remoting.Launcher.parseJnlpArguments(Launcher.java:269)
    at hudson.remoting.Launcher.run(Launcher.java:219)
    at hudson.remoting.Launcher.main(Launcher.java:192)

.. donc je suppose un problème de configuration avec mon proxy. J'ai pris la configuration de la configuration du proxy inverse et ajouté la configuration suivante pour forcer SSL:

upstream jenkins-upstream {
  server unproxied-jenkins.example.com:8080 fail_timeout=0;
}

server {
  listen 80;
  server_name proxied-jenkins.example.com;
  return 301 https://$host$request_uri;
}
server {
  listen 443;
  server_name proxied-jenkins.example.com;

  #this is the jenkins web root directory (mentioned in the /etc/default/jenkins file)
  root            /var/run/jenkins/war/;

  ssl on;
  ssl_certificate /etc/nginx/conf.d/proxied-jenkins.example.com.crt;
  ssl_certificate_key /etc/nginx/conf.d/proxied-jenkins.example.com.key;
  ssl_protocols TLSv1.2;
  ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;

  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  [...] # continuing according to jenkins documentation
  location @jenkins {
      proxy_pass                  http://jenkins-upstream
      [....]
  }
  [....]
}

De nouveau lorsque vous passez à HTTP non sécurisé, JNLP et jenkins-cli fonctionnent comme prévu. Alors quelle est l'erreur?
Peut-être ai-je besoin de transmettre des informations d'en-tête supplémentaires? Peut-être ai-je besoin d'une configuration SSL supplémentaire dans mes paramètres de proxy?

ITL
la source
Vous avez besoin de votre CAcert dans le magasin de clés de sécurité SSL du processus client, pas dans le fichier de clés SSL. Toutes les exceptions SSLHandshakeException ne sont pas dues à des problèmes de cert, mais vous n'obtenez pas celle qui est telle que vous échouez probablement avant la validation du cert. (1) Quelle version de java (6/7/8, Oracle / OpenJDK / IBM /?) ​​Utilisez-vous pour le client? (2) Pouvez-vous (2A) obtenir une capture de réseau avec Wireshark tcpdump ou similaire, filtré aussi étroitement que possible et afficher ou établir un lien vers celle-ci; ou (2B) exécuté avec sysprop javax.net.debug=ssl, capturez la sortie (grande!) et ajoutez cela?
dave_thompson_085
@ dave_thompson_085 le javax.net.debug=sslfait le tour. J'ai pu découvrir que le binaire java (oracle jdk 7) avait essayé de manipuler le protocole TLSv1 avec des chiffrements "faibles" ... Après l'installation de Java Cryptography Extension (JCE), je disposais d'un meilleur support de chiffrement et j'étais capable de dire à java binaire à faire faire TLSv1.2. en utilisant -Dhttps.protocols=TLSv1.2. Cependant, après la mise à niveau vers Oracle JDK 8, cela fonctionne immédiatement. Je vous remercie donc de votre soutien et de m'avoir orienté dans la bonne direction ... Peut-être formulez-vous ceci comme réponse et je vais l'exclure et le faire passer au vote supérieur.
ITL

Réponses:

2

(Développé en fonction des commentaires sur les commentaires)

Ce serveur est configuré pour exiger la version de protocole TLSv1.2 (uniquement) et des suites de chiffrement utilisant au moins l’un des paramètres suivants: AES-GCM ou AES 256 bits, avec échange de clé DHE ou ECDHE (pour lequel OpenSSL et donc nginx utilisent des orthographes variantes EDH et EECDH dans certains cas, y compris celui-ci).

Client JSSE dans Oracle ou OpenJDK JDK7 n'offre pas TLSv1.2 ou 1.1 par défaut (je ne sais pas pour IBM, qui a ses propres fournisseurs de cryptage), mais ils sont implémentés et peuvent être activés ; car (Https)URLConnectioncela peut être fait avec la propriété système https.protocols. (Ou en superposant sa fabrique de sockets, mais la propriété système est généralement plus facile.) Mais JDK7 n’implémente pas GCM et les versions Oracle (mais PAS OpenJDK) interdisent le cryptage symétrique à 256 bits, à moins d’installer le fichier "JCE Unlimited Strength Jurisdiction Policy Files". "du site Web Oracle; voir https://stackoverflow.com/a/33712287/2868801 et éventuellementhttps://stackoverflow.com/questions/30350120/sslhandshakeexception-while-connecting-to-a-https-site

En revanche, JDK8 (Oracle et OpenJDK) offre les protocoles TLSv1.2 et 1.1 par défaut et implémente GCM afin de pouvoir se connecter sans la stratégie Unlimited Strength.

7 et 8 prennent en charge l'échange de clés DHE et ECDHE. Mais pour toute autre personne se trouvant dans une situation similaire avec JDK6: ECDHE ne fonctionnera pas si vous n’ajoutez pas de fournisseur tiers pour les primitives ECC, à bcprovpartir de http://www.BouncyCastle.org.

dave_thompson_085
la source
1

Pour les utilisateurs qui accèdent à cette page en se basant sur le titre plutôt que sur le contenu de cette question et voulant que les esclaves JNLP se connectent à un serveur Jenkins à proxy inversé s'exécutant sur un serveur distinct plutôt que sur le serveur proxy inverse, veuillez consulter ma réponse. to Jenkins: Comment configurer Jenkins derrière le proxy inverse de Nginx pour que les esclaves JNLP puissent se connecter .

PolyTekPatrick
la source