Jenkins sous Apache
Cet article présente la configuration mise en place sur un serveur Apache
pour une instance de Jenkins
.
Sommaire
Votre avis
Nobody voted on this yet
|
|
Configuration Tomcat
Certains arguments, passés en paramètre d'URL, sont encodés et doivent transiter tel quel au serveur d'application. Il est donc nécessaire d'indiquer au serveur Apache
de ne pas les modifier, à l'aide de la directive AllowEncodedSlashes NoDecode
, mais il faut également que le serveur Tomcat
les accepte. Pour cela, il faut spécifier la valeur true
à l'aide de la variable d'enironnement org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH
. Dans le cadre de cette installation, le fichier /var/lib/tomcat8/bin/setenv.sh
est modifié, comme indiqué dans l'article suivant, pour ajouter le paramétrage dans la variable d'exécution CATALINA_OPTS
.
export CATALINA_OPTS="-Xms256m -Xmx512m -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
Déploiement site sécurisé
La procédure décrite ci dessous permet de mettre à disposition l'application avec un accès sécurisé HTTPS
avec utilisation d'un certificat fourni par Let's Encrypt et un tutoriel très bien réalisé.
L'application sera rendue disponible depuis un sous domaine du domaine principal. La documentation officielle indique qu'il faut que le context soit exactement le même sur le serveur Tomcat
que sous Apache
.
Pour rappel, l'application est exécutée sous Tomcat
avec la racine jenkins
.
Préparation environnement
Certbot sera utilisé pour demander et renouveler le certificat du site. Dans son fonctionnement, le process essaye d'accéder à un .well-known
à la racine du site. De plus, une bonne pratique consiste à fournir un répertoire racine pour les sites déployés sous Apache
. Le répertoire /var/www/jenkins
est alors créé, ainsi que le sous répertoire .well-known
.
#sudo mkdir -p /var/www/jenkins/.well-known
Pour cette application, il n'est pas nécessaire de placer un fichier index.html
, avec un contenu vide, dans le répertoire racine, soit /var/www/jenkins
, car les accès seront gérés par l'application.
Un fichier robots.txt
y est placé avec les directives indiquant aux moteurs de recherche de ne rien indexer. Attention ceci est nécessaire si l'instance Jenkins
est rendue accessible avec une URL racine.
User-agent: *
Disallow: /
Dans le cas où Jenkins
serait accessible à la racine du site, le fichier robots.txt
ne serait pas nécessaire car l'application met à disposition ce fichier.
Les permissions mises en place donnent un accès uniquement aux compte du serveur, soit www-data
.
#sudo find /var/www/jenkins -type f -exec chmod 0600 {} \; #sudo find /var/www/jenkins -type d -exec chmod 0700 {} \; #sudo chown -R www-data:www-data /var/www/jenkins
Pour les besoins de personnalisation de Jenkins
, des images et des CSS sont mises à dispositions depuis une URL du type /sitesExtensions
. Ce répertoire est créé dans le répertoire racine /var/www/jenkins
et la configuration Apache
permettra d'y accéder.
Configuration HTTP
Dans un premier temps, une configuration temporaire est mise en place pour accéder de façon non sécurisé.
Un fichier jenkins
est créé dans le répertoire /etc/apache2/sites-available
avec le contenu suivant.
<VirtualHost *:80>
ServerAdmin contact-email@dummy.net
ServerName www.jenkins.dummy.net
DocumentRoot /var/www/jenkins
DirectoryIndex index.html
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/jenkins_error.log
CustomLog ${APACHE_LOG_DIR}/jenkins_access.log combined
<Directory "/var/www/jenkins">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ProxyPass /.well-known !
ProxyPassReverse /.well-known !
ProxyPass /sitesExtensions !
ProxyPassReverse /sitesExtensions !
ProxyRequests Off
AllowEncodedSlashes NoDecode
ProxyPass /jenkins http://localhost:8080/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8080/jenkins
</VirtualHost>
Les directives sur l'accès à /.well-known
et sitesExtensions
permettent de servir les éléments depuis la racine /var/www/jenkins
.
La configuration du Proxy respectent les recommandations de la document officielle, contraitement à d'autre applications où ces spécificités ne sont pas mises en place.
Cette configuration doit être mise à disposition en plaçant un lien dans /etc/apache2/sites-enabled
.
#sudo ln -s /etc/apache2/sites-available/jenkins /etc/apache2/sites-enabled/008-jenkins.conf
Le nom du lien, à savoir 008-jenkins.conf
, respecte une incrémentation sur la machine utilisée, il peut être remplacé pour tout autre nom valide pour Apache
.
Il suffit de relancer la configuration d'Apache
pour qu'elle soit prise en compte.
#sudo apache2ctl graceful
Certificat
L'application est à présent disponible avec l'URL http://www.jenkins.dummy.net. Un certificat va être demandé à l'aide de Certbot.
#sudo certbot certonly --webroot -w /var/www/jenkins -d www.jenkins.dummy.net --email contact-email@dummy.net Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Obtaining a new certificate Performing the following challenges: http-01 challenge for www.jenkins.dummy.net Using the webroot path /var/www/jenkins for all unmatched domains. Waiting for verification... Cleaning up challenges IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/www.jenkins.dummy.net/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/www.jenkins.dummy.net/privkey.pem Your cert will expire on 2018-05-17. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Le certificat est stocké dans le répertoire /etc/letsencrypt/live/www.jenkins.dummy.net/
.
Configuration HTTPS
Le certificat étant disponible, la configuration HTTPS
peut être mise en place.
Un fichier jenkins-dummy-ssl
est créé dans le répertoire /etc/apache2/sites-available
avec le contenu suivant.
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin contact-email@dummy.net
ServerName www.jenkins.dummy.net
DocumentRoot /var/www/jenkins
DirectoryIndex index.html
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/jenkins_ssl_error.log
CustomLog ${APACHE_LOG_DIR}/jenkins_ssl_access.log combined
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.jenkins.dummy.net/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.jenkins.dummy.net/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.jenkins.dummy.net/chain.pem
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCompression off
SSLOptions +StrictRequire
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
<Directory "/var/www/jenkins">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ProxyPass /.well-known !
ProxyPassReverse /.well-known !
ProxyPass /sitesExtensions !
ProxyPassReverse /sitesExtensions !
ProxyRequests Off
AllowEncodedSlashes NoDecode
ProxyPass /jenkins http://localhost:8080/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8080/jenkins
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>
</IfModule>
A noter les deux directives RequestHeader
pour X-Forwarded-Proto
et X-Forwarded-Port
. Ceci fait suite à la recommandation de la procédure officielle : https://wiki.jenkins.io/display/JENKINS/Running+Jenkins+behind+Apache au niveau du paragraphe mod_proxy with HTTPS
, ainsi que des exemples pour d'autres applications.
Cette configuration doit être mise à disposition en plaçant un lien dans /etc/apache2/sites-enabled
.
#sudo ln -s /etc/apache2/sites-available/jenkins-dummy-ssl /etc/apache2/sites-enabled/009-jenkins-ssl.conf
Le nom du lien, à savoir 009-jenkins-ssl.conf
, respecte une incrémentation sur la machine utilisée, il peut être remplacé pour tout autre nom valide pour Apache
.
Enfin la configuration HTTP
, sur le port 80
, est modifiée pour forcer la redirection sur l'accès en HTTPS
. Le précédent fichier jenkins
est modifié avec le contenu suivant.
<VirtualHost *:80>
ServerAdmin contact-email@dummy.net
ServerName www.jenkins.dummy.net
DocumentRoot /var/www/jenkins
DirectoryIndex index.html
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/jenkins_error.log
CustomLog ${APACHE_LOG_DIR}/jenkins_access.log combined
RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
Il suffit de relancer la configuration d'Apache
pour que les modifications soient prises en compte.
#sudo apache2ctl graceful
Jenkins en service
Suite à l'installation du service avec Jenkins Runner, l'application est démarré dans son propre contexte. N'étant plus sous Tomcat
, la configuration Apache
doit être modifiée. Par défaut, le numéro de port est 8080
mais il a été modifié en 8090
.
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin contact-email@dummy.net
ServerName www.jenkins.dummy.net
DocumentRoot /var/www/jenkins
DirectoryIndex index.html
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/jenkins_ssl_error.log
CustomLog ${APACHE_LOG_DIR}/jenkins_ssl_access.log combined
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.jenkins.dummy.net/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.jenkins.dummy.net/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.jenkins.dummy.net/chain.pem
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCompression off
SSLOptions +StrictRequire
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
<Directory "/var/www/jenkins">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ProxyPass /.well-known !
ProxyPassReverse /.well-known !
ProxyPass /sitesExtensions !
ProxyPassReverse /sitesExtensions !
ProxyRequests Off
AllowEncodedSlashes NoDecode
ProxyPass / http://localhost:8090/ nocanon
ProxyPassReverse / http://localhost:8090/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>
</IfModule>
A noter que l'instance est accessible depuis l'URL racine. Donc contrairement aux précédentes configuration, les directives ProxyPass
et ProxyPassReverse
se termine par le /
.
Configuration simple
La première configuration mise en place a été réalisée sur un serveur Apache
simple, à savoir qu'il était utilisé pour un seul site. Dans ce cas, et pour une installation sous Ubuntu, les paramètres ont été mis en place dans le fichier /etc/apache2/httpd.conf
.
ProxyPass /jenkins http://localhost:8080/jenkins
ProxyPassReverse /jenkins http://localhost:8080/jenkins
<Proxy http://localhost:8080/jenkins>
Order allow,deny
Allow from all
</Proxy>
Dans ce cas, toutes requêtes sur /jenkins seront redirigées vers l'application Jenkins hébergée sur un Tomcat en local.
Configuration pour un domaine spécifique
Au fil du temps, le serveur Apache
a été enrichi sur la machine, afin de servir différents domaine. La première configuration mise en place rendait l'application disponible sur l'ensemble des domaines, chose qui n'était pas souhaitée. La configuration dans le fichier /etc/apache2/httpd.conf
a été déplaçée dans le fichier de configuration du domaine souhaité, à savoir /etc/apache2/sites-enabled/002-dev.conf
, pour le domaine dev.jouvinio.net
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/default
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/default>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
# Old configuration for APACHE 2.2
# Order allow,deny
# allow from all
Require all granted
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
# Old configuration for APACHE 2.2
# Order allow,deny
# Allow from all
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
ProxyPass /jenkins http://localhost:8080/jenkins
ProxyPassReverse /jenkins http://localhost:8080/jenkins
<Proxy http://localhost:8080/jenkins>
Order allow,deny
Allow from all
</Proxy>
</VirtualHost>
Ainsi l'application Jenkins ne sera disponible que pour ce domaine.
Configuration Reverse Proxy
Suite à la mise à jour 1.552, une erreur de reverse proxy est indiqué dans la page d'administration.

Le rendu du message dépend de la version installée, il se présente ainsi sur une version 2.X
.

Le message indique une erreur de configuration du mode Reverse Proxy
La configuration de votre proxy inverse n'est pas bonne
La documentation officielle, https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache, indique la configuration à mettre en place afin de ne plus avoir ce message d'erreur.
La configuration Apache
mise en place prend en compte les directives.
ProxyRequests Off
AllowEncodedSlashes NoDecode
ProxyPass /jenkins http://localhost:8080/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8080/jenkins
Voir aussi
Documentation officielle : https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache