Jenkins est un outil d’intégration continue que j’utilise sur un serveur Windows pour gérer mes projets sous git. L’application programmée en Java possède une interface web très intuitive. Pour l’utiliser à partir d’un site web commercial (.com) j’ai dû configurer IIS avec un reverse proxy. Jenkins est accessible par TLS grâce à Let’s Encrypt. Cette configuration semble parfaite, sauf que j’ai un petit problème. Lorsque j’accède à la section Manage Jenkins, un message d’erreur est affiché.
Avertissement à propos du reverse proxy dans Jenkins
Plusieurs guides existent en ligne pour corriger ce problème, mais aucun n’a fonctionné complètement avec mon environnement. Après avoir regardé des instructions pour Apache et Nginx j’ai compris qu’il fallait modifier les en-tête HTTP suivantes: X-Forwarded-Proto, X-Forwarded-Port et X-Forwarded-Host.
J’ai essayer de les ajouter comme Server Variables dans les règles de mon site web sur IIS, mais cela n’a pas fonctionné. En lisant la documentation de Microsoft j’ai réalisé que les variables devaient être en majuscule, que les tirets devaient être remplacés par des traits de soulignement et que le préfixe « HTTP_ » était nécessaire. Donc, voici ce que j’ai ajouté comme valeurs de remplacement:
HTTP_X_FORWARDED_PROTO = https
HTTP_X_FORWARDED_PORT = 443
HTTP_X_FORWARDED_HOST = {HTTP_HOST}
Résultat dans IIS: Capture d’écran des règles pour Jenkins dans IIS
Après avoir enregistré les changements, j’ai actualisé la page de gestion sur Jenkins et l’erreur est disparue.
GitVersion est une application pour Windows codée en C# qui sert à la génération de version automatique à partir d’un dépôt Git. Jenkins est un outil d’intégration continue programmé en Java. Ces deux projets à code source ouvert sont tous deux hébergés sur GitHub. Cet article expliquera comment utiliser GitVersion dans Jenkins et ça, sans l’utilisation de plugin supplémentaires.
L’utilisation de GitVersion sera faite à l’intérieur d’un fichier Jenkinsfile qui est utilisé par des projets de type Pipeline. Dans mon premier exemple, le paramètre showvariable sera donné à GitVersion pour aller chercher une variable spécifique. Ce n’est pas très efficace si l’on a besoin d’aller chercher plusieurs variables. Par contre, c’est assez simple. Voici un bout code qui sert à changer la description du build:
Comme mentionné plus tôt, cette technique manque de flexibilité. Dans le prochain exemple, toutes les propriétés de GitVersion serviront à générer des variables d’environnement. Ces variables pourront par la suite être utilisées à n’importe quel endroit dans le fichier. L’inconvénient est que c’est un peu plus long:
steps {
// Génération du fichier gitversion.properties
bat '@"GitVersion.exe" /output buildserver'
// Enregistrement des variables d'environnement du fichier gitversion.properties
script {
readFile('gitversion.properties').split("\r\n").each { line ->
el = line.split("=")
env."${el[0]}" = (el.size() > 1) ? "${el[1]}" : ""
}
}
bat '''
@echo Quelques variables d’environnement:
@echo %GitVersion_SemVer%
@echo %GitVersion_BranchName%
@echo %GitVersion_AssemblySemVer%
@echo %GitVersion_MajorMinorPatch%
@echo %GitVersion_Sha%
'''
}
Voici un exemple de fichier gitversion.properties généré avec la version 4.0.0-beta.14 de GitVersion:
Avec certain type de projet Jenkins, j’ai dû ajouter un comportement supplémentaire lors de l’opération clone. La version demeurait toujours à 0.1.0 et cela même si des tags existaient. Dans les configurations du projet, dans la section Behaviors il faut ajouter la propriété Advanced clone behaviours. Ensuite, on s’assure que Fetch tags est sélectionné.
Cela va faire en sorte que le paramètre --tags sera utilisé lors du fetch.
Maintenant que vous avez ces informations de version, vous pouvez les utiliser pour générer la version de votre logiciel automatiquement. Je me sers de l’application envsubst pour faire des substitutions dans un fichier.
Un de mes plaisirs coupables est de voir un logiciel planter dans un endroit public. Par exemple, un guichet automatique, un téléviseur dans un aéroport, une pompe à essence, etc. Ce samedi par un bel après-midi, voici ce qui a mis un sourire dans mon visage.
Oups, on dirait qu’il y a eu un problème…
Je crois que le message complet est celui-ci:
A problem has been detected and Windows has been shut down to prevent damage to your computer.
The Windows Driver Framework has detected that a violation has occurred.
GitBucket est une solution Git auto-hébergée codée en Scala. Ce projet à code source ouvert hébergé sur GitHub a beaucoup de qualité, entre autres, sa compatibilité avec l’API GitHub et sa facilité d’installation. Maintenant, il est temps de parler de l’un de ses défauts: il ne peut pas être installé nativement comme service Windows.
Tout comme avec Gogs, c’est l’application NSSM qui sera utilisée. Il faut s’assurer qu’elle a été installée dans votre %PATH%. Par exemple, le fichier nssm.exe peut être copié dans le dossier C:\WINDOWS\system32.
Ensuite, on ouvre une fenêtre de terminal et on tape toutes ces commandes:
set warpath=C:\GitBucket
set datapath=C:\GitBucket\data
nssm install gitbucket "%PROGRAMFILES%\Java\jre1.8.0_152\bin\java.exe"
nssm set gitbucket AppDirectory "%warpath%"
nssm set gitbucket AppParameters "-jar gitbucket.war --gitbucket.home=\"%datapath%\" --port=8080"
nssm set gitbucket DisplayName "GitBucket Service"
nssm set gitbucket Description "A Git platform with easy installation, high extensibility & GitHub API compatibility."
nssm set gitbucket Start SERVICE_DELAYED_AUTO_START
nssm set gitbucket AppStdout "%datapath%\nssm.log"
nssm set gitbucket AppStderr "%datapath%\nssm.log"
nssm set gitbucket AppRotateFiles 1
nssm set gitbucket AppRotateBytes 1000000
nssm start gitbucket
Il est important de changer la ligne 1 pour y inscrire le chemin vers le fichier gitbucket.war. La ligne 2 doit pointer vers le dossier où les données seront enregistrées. GitBucket nécessite d’être démarré par Java.exe, donc la ligne 3 doit être le chemin vers ce fichier. La ligne 5 spécifie le port que vous voulez utiliser. Changez-le pour utiliser un port disponible. La dernière ligne va démarrer le service, donc ouvrez un navigateur web et testez que tout fonctionne.
Si vous désirez supprimer le service, c’est cette commande qu’il faut utiliser:
nssm remove gitbucket
Pour éditer un service déjà installé avec l’interface, on utilise cette commande:
Durant le développement d’une application sous C++Builder j’ai frappé un mur assez solide. Pendant presque qu’un mois il y a eu un problème que je n’ai su résoudre. Maintenant j’ai la solution et je vais vous la partager.
L’application en question est un client HTTP qui utilise les composants TIdHTTP et TIdSSLIOHandlerSocketOpenSSL. Elle possède la possibilité de se connecter à plusieurs serveur web dont certains qui utilisent une connexion sécurisée. Les serveurs fournissent un service à l’aide d’un API JSON.
La plupart de mes tests se faisaient avec un serveur Windows Server 2012 R2 qui utilise un certificat SSL généré gratuitement par Let’s Encrypt. Le certificat est renouvelé automatiquement par l’intermédiaire de l’application Windows ACME Simple, anciennement connu sous le nom letsencrypt-win-simple.
Le développement de l’application allait bon train, jusqu’au moment où j’ai commencé à recevoir l’exception suivante lors de l’utilisation de la méthode Get:
Project app.exe raised exception class EIdSocketError with message ‘Socket Error # 10054 Connection reset by peer.’.
Bien évidemment j’ai pensé que j’avais changé quelque chose dans mon code. Alors j’ai tenté d’utiliser le code de soumissions antérieures. J’utilise toujours Git, même pour mes projets personnels de petite envergure. Dans ce cas, cela aurait pu me sauver la vie, mais non, mon code qui fonctionnait ne fonctionne plus!
Je n’utilisais pas les derniers fichiers DLL de OpenSSL, alors j’ai téléchargé la dernière version. Au moment d’écrire ces lignes la version 1.0.2o était la version LTS la plus à jour. Malheureusement ceci ne provoqua aucun changement de comportement.
Il est important de mentionner que le problème survient seulement avec mon serveur Windows Server 2012 R2 et que l’API répond correctement sur celui-ci avec Chrome et Firefox. Donc, mon serveur fonctionne avec certains clients et mon application fonctionne avec tous les autres serveurs testés! Est-ce un problème de client ou de serveur?
Étant donné que je voulais continuer de développer mon application j’ai décidé d’utiliser un autre serveur pour faire mes tests. La bonne nouvelle, c’est que mon application pouvait progresser, la mauvaise c’est qu’il est possible que certains utilisateurs éprouvent le même problème. Pendant presque un mois ce problème est resté dans ma tête.
L’application tirant à sa fin, je n’avais plus qu’un seul problème à régler. Aux grand maux, les grands moyens, je décide d’utiliser Wireshark pour regarder ce qui se trame lors de la connexion. La seule chose que j’observe est qu’après une requête HTTPS (Client Hello) au serveur, celui-ci semble se déconnecter.
Je me dis alors que c’est peut-être une mise à jour manquante sur le serveur! Alors je fais toutes mes mises à jour Windows, même celles facultatives. J’en profite même pour désactivé TLS version 1.0. Je redémarre le serveur et malheureusement, ceci ne règle rien. C’était quand même une bonne idée de fixer les trous de sécurités sur le serveur.
Par la suite, je vais dans la console de IIS et pour la première fois j’y vois une alerte qui attire mon attention:
No default SSL site has been created. To support browsers without SNI capabilities, it is recommended to create a default SSL site.
Je commence donc à lire un peu sur le sujet et je me rappelle que dans l’outil SSL Server Test de SSL Labs il y avait une bannière bleue avec le texte suivant:
This site works only in browsers with SNI support.
Ma lecture m’amène à comprendre que Server Name Indication (SNI) fait partie du Client Hello. Tiens, cela me rappelle ce que j’ai vu dans Wireshark. C’est le client qui doit supporter cette extension. Dans mon cas, le client est la bibliothèque Indy. Est-ce qu’il y a des problèmes connus avec SNI dans Indy? Le support SNI a été introduit dans la soumission 5321 du 11 janvier 2016. J’utilise RAD Studio XE8 qui date de 2015. Pour être certain, je regarde aussi le fichier Idglobal.hpp où l’on trouve l’information sur la version de Indy utilisé:
Eh bien, la version de Indy que j’utilise ne supporte pas SNI!
Pour faire un test rapide, je désactive SNI sur mon serveur: La case à cocher Require Server Name Indication
Tout fonctionne!
En conclusion, je présume que ce qui s’est passé durant le développement de l’application est que le serveur sur Windows Server 2012 R2 a dû renouveler le certificat SSL et que la configuration du serveur à changer. D’ailleurs lorsque l’on regarde l’historique de soumission du logiciel Windows ACME Simple, plusieurs messages sont en lien avec SNI. J’ai fait une mise à jour à la version 1.9.10.1 et j’espère que lors du prochain renouvellement il n’y aura pas de problèmes. S’il y en a, au moins je sais où regarder en premier.
Selon le PCI Security Standards Council il serait recommandé de migrer du protocole Transport Layer Security (TLS) version 1.0 vers une version plus récente et cela pour le 30 juin 2018. Présentement, sur mon site web qui roule sous Windows Server 2012 R2, TLS 1.0 est encore disponible.
Dans un article précédent j’avais expliqué comment augmenter la sécurité d’un site web. Celui-ci sera similaire, sauf qu’au lieu d’aller éditer le registre de Windows directement, le logiciel IIS Crypto sera utilisé. Cela va grandement simplifier la tâche.
Il suffit d’ouvrir l’application et de décocher TLS 1.0 dans la section Protocols:
IIS Crypto 2.0 avec la case à cocher TLS 1.0 vide
Par la suite il faut cliquer sur le bouton Apply et redémarrer le serveur.
Gogs (Go Git Service) est une solution Git auto-hébergée codée en Go. Jenkins est un outil d’intégration continue programmé en Java. Ces deux projets à code source ouvert sont tous deux hébergés sur GitHub. Lorsque que combiné ensemble, ils permettent presque un cycle de développement logiciel complet.
Le type de projet à utiliser dans Jenkins est le Multibranch Pipeline car il est le mieux adapté à Git. C’est pourquoi que dans la section Branch Sources lorsque l’on clique sur Add source on doit choisir Git. Vous devez entrer le Project Repository, pour vous simplifier la tâche vous pouvez utiliser le bouton Copy de Gogs. Dans la section Behaviors, appuyez sur le bouton Add et choisissez l’option Configure Repository Browser. Dans la liste de Repository browser, il faut choisir gogs et entrer le URL de la page du projet. Cela fera en sorte qu’à plusieurs places dans Jenkins des liens vers Gogs seront ajoutés.
Le SHA1 sera un lien vers la soumission dans Gogs
Ceci conclut la première étape. La seconde consiste à pouvoir démarrer des tâches sur Jenkins suite à une soumission. Avant de quitter la page de configuration du projet, dans la section Scan Multibranch Pipeline Triggers on peut cocher l’option Periodically if not otherwise run. Cela va permettre une vérification du dépôt à tous les jours. C’est une protection au cas où Jenkins ou Gogs serait incapable d’effectuer la prochaine étape.
Dans Gogs il faut maintenant choisir votre dépôt et aller dans les Settings. Par la suite, on va dans la section Webhooks, on clique sur Add Webhook et on choisit Gogs. Entrez ces paramètres:
Org/Project.git = nom du dépôt utilisé dans Jenkins (sensible à la case)
Content Type: application/x-www-form-urlencoded
When should this webhook be triggered: Let me choose what I need.
Cocher les options suivantes:
Create
Delete
Push
Active doit être cocher
Pour terminer, appuyer sur le bouton Add Webhook.
Avec cette configuration les branches pourront être ajoutées et supprimées automatiquement dans Jenkins. Si vous avez un fichier Jenkinsfile inclus dans votre projet, les tâches ajoutées à celui-ci pourront être effectuées à chaque soumission. Malheureusement les requêtes de tirage (pull requests) ne fonctionnent pas.
Si vous avez besoin d’aide sur le plugin Git de Jenkins vous pouvez consulter cette page web.
Dernièrement je me suis fais présenter l’outil SSL Server Test de SSL Labs. C’est une application en ligne qui permet de tester la sécurité d’une site web. J’avais récemment installé un certificat SSL sur le serveur d’un ami. Il s’agit d’un certificat généré gratuitement par Let’s Encrypt. Donc, je croyais bien obtenir une bonne note. Eh bien… non! J’ai obtenu la note de B.
Voici les deux problèmes qui me limitaient à cette cote.
This server supports weak Diffie-Hellman (DH) key exchange parameters. Grade capped to B.
This server accepts RC4 cipher, but only with older browsers. Grade capped to B.
Le site web est hébergé sur Windows Server 2012 R2. Donc les prochaines étapes pour régler ces problèmes de sécurité ont seulement été testées avec cette version de Windows. Si vous les appliquez, voici ce qui pourrait arriver:
Cote B vers A-
A- ce n’est pas A ou même A+, mais c’est un bon départ.
Tous ces problèmes peuvent se régler dans l’Éditeur du Registre. On peut le démarrer avec la commande regedit.exe
Pour régler le problème avec Diffie-Hellman on doit aller dans la clef suivante: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SChannel\KeyExchangeAlgorithms Si elle n’existe pas on doit créer la sous-clef Diffie-Hellman Dans la clef Diffie-Hellman, on doit créer une valeur DWORD nommé Enabled dont la donnée est 0.
Maintenant passons à l’algorithme de chiffrement RC4 (Rivest Cipher 4) qui est désuet. On doit aller dans la clef suivante: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers Il va ensuite falloir créer les trois sous-clefs suivantes: RC4 128/128, RC4 40/128 et RC4 56/128. Pour chacune de ces clefs, on doit créer une valeur DWORD nommé Enabled dont la donnée est 0.
Éditeur du Registre – clef SCHANNEL
Vous pouvez maintenant fermer l’Éditeur du Registre et redémarrer votre serveur pour appliquer les modifications.
Si vous désirez annuler ces changements il suffit de mettre la valeur Enabled à 0xffffffff. Vous pouvez aussi simplement supprimer la valeur Enabled.
J’espère que cet article vous aidera à augmenter la sécurité de votre site en évitant d’exposer des méthodologies faibles ou insécures.
Dans mon dernier article, j’avais expliqué comment démarrer MiNET comme un service Windows. On avait la chance que la fonctionnalité était intégrée à l’application. Par contre, ce n’est pas toujours le cas.
Cette fois-ci c’est l’application Gogs que j’aimerais utiliser comme service Windows. Gogs (Go Git Service) est une solution Git auto-hébergée codée en Go. Ce projet à code source ouvert hébergé sur GitHub a beaucoup de qualité, la plus grande étant sans doute sa facilité d’installation. Maintenant, il est temps de parler de l’un de ses défauts: il ne peut pas être installé nativement comme service Windows.
La documentation de Gogs nous dirige vers l’application NSSM pour palier à ce problème. NSSM (Non-Sucking Service Manager) se vante de ne pas être médiocre comme les autres outils de ce genre. L’application possède même une interface graphique pour installer, éditer ou supprimer un service créer à partir de NSSM. Par contre, dans cet article, c’est plutôt des lignes de commande que nous utiliserons.
En premier, il faut que le fichier app.ini de Gogs soit modifié pour que le paramètre RUN_USER porte le nom du PC. Pour connaitre le nom, vous pouvez utiliser la commande suivante:
echo %COMPUTERNAME%
Le fichier ini doit être modifié comme ceci:
RUN_USER = NOMDUPC$
Le signe de dollar à la fin du nom est important.
En second lieu, il faut s’assurer que NSSM a été installé dans votre %PATH%. Par exemple, le fichier nssm.exe peut être copié dans le dossier C:\WINDOWS\system32.
Ensuite, on ouvre une fenêtre de terminal et on tape toutes ces commandes:
set gogspath=c:\gogs
set escapepath=^%PATH^%
nssm install gogs "%gogspath%\gogs.exe"
nssm set gogs AppDirectory "%gogspath%"
nssm set gogs AppParameters "web"
nssm set gogs DisplayName "Gogs - Go Git Service"
nssm set gogs Description "A painless self-hosted Git service."
nssm set gogs Start SERVICE_DELAYED_AUTO_START
nssm set gogs AppStdout "%gogspath%\gogs.log"
nssm set gogs AppStderr "%gogspath%\gogs.log"
nssm set gogs AppRotateFiles 1
nssm set gogs AppRotateBytes 1000000
nssm set gogs AppEnvironmentExtra "PATH=%escapepath%;%gogspath%;C:\Program Files\Git\bin"
nssm start gogs
Il est important de changer la ligne 1 pour y inscrire le chemin vers l’application Gogs. La ligne 13 doit aussi être changée si Git n’est pas dans le %PATH%. La dernière ligne va démarrer le service, donc ouvrez un navigateur web et testez que tout fonctionne.
Si vous désirez supprimer le service, c’est cette commande qu’il faut utiliser:
nssm remove gogs
Pour éditer un service déjà installé avec l’interface on utilise cette commande:
nssm edit gogs
Édition du service Gogs à l’aide de NSSM
En terminant, je veux vous parler de Gitea. Il s’agit d’un fork de Gogs qui semble avoir le vent dans les voiles. Pour l’instant, je préfère encore demeurer avec Gogs, mais je garde un œil attentif sur ce projet.