Autres https://www.vincentliefooghe.net/ fr Utilisation de SLAMD pour les benchmarks LDAP https://www.vincentliefooghe.net/content/utilisation-slamd-pour-les-benchmarks-ldap <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Utilisation de SLAMD pour les benchmarks LDAP</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Lorsqu'on réalise des études comparatives sur les annuaires LDAP, il est fréquent que le client demande d'établir des tests de performances, pour s'assurer que la solution en place sera capable de répondre à ses exigences.</p> <p>Pour faire celà, j'utilisais souvent les outils <em>authrate</em> ou <em>searchrate</em> présents dans les binaires des annuaires de Forgerock ou Ping.</p> <p>Si ces outils permettent de tester de manière unitaire, et avec un certain nombre de paramètres, ils manquait certaines possibilités / fonctionnalités :</p> <ul> <li>pas de possiblité de lancer plusieurs clients en parallèle, de manière synchronisée</li> <li>pas de reporting de base</li> <li>pas de réutilisation des modèles de "tirs"</li> </ul> <p>Dans le cadre d'un nouveau projet d'étude, je suis tombé sur l'outil <em>SLAMD</em> disponible sur <a href="https://github.com/dirmgr/slamd">GitHub</a>.</p> <h2>Présentation de SLAMD</h2> <p>Il s'agit d'un outil écrit en Java, par un ancien employé de Sun qui travaillait sur les annuaires OpenDS notamment.</p> <p>On trouve également chez Oracle (qui a racheté Sun il y a plusieurs années), les binaires à télécharger : <a href="https://www.oracle.com/security/identity-management/technologies/slamd-downloads/">Oracle SLAMD Downloads</a></p> <p>L'outil se présente comme "<em>Distributed Load Generation Engine</em>", ce qui donne une idée de son architecture répartie. En effet, <em>SLAMD</em> est articulé autour de plusieurs composants :</p> <ul> <li>un serveur, qui tourne dans un serveur Tomcat, qui permet de paramétrer les <em>jobs</em>, et construire les rapports</li> <li>un (ou plusieurs) clients, qui vont communiquer avec le serveur pour récupérer les <em>jobs</em> à traiter, et qui vont effectuer les requêtes demandées (ce sont eux qui vont vraiment faire le travail)</li> <li>un service de monitoring que l'on peut installer sur les serveurs LDAP pour remonter les informations au serveur SLAMD.</li> </ul> <p>L'outil a été développé à l'origine pour remplacer / améliorer les <em>authrate</em> et autres, avec une orientation LDAP, mais peut aussi être utilisé pour d'autres protocoles réseau (http, smtp, pop,imap).</p> <h2>Utilisation</h2> <p>Une fois qu'on a récupéré les binaires ou compilé à partir de GitHub et installé les composants sur les serveurs, est de définir les <em>jobs</em> qui seront ensuite activés.</p> <p>Ceci se fait via l'option de menu "Schedule a job", dans laquelle on voit toute la richesse de l'outil.</p> <p>Pour les tests LDAP, on dispose d'une vingtaine de modèle prédéfinis, notamment :</p> <ul> <li>Add and Delete : ajout et suppression, utilisé pour les tests d'écriture</li> <li>Basic Bind : connexion simple, sans recherche préalable</li> <li>Basic Search and Bind : connexion après recherche de l'utilisateur ; c'est ce que j'utilise pour tester les mécanismes d'authentification</li> <li>Comprehensive Search : possibilité de mettre plusieurs serveurs, plusieurs filtres et de préciser les attributs retournés</li> <li>Mix load : mélange de Add, Bind, Search, etc</li> </ul> <h2>Paramétrage du Search + Bind</h2> <p>Dans la majorité des cas en mode <em>Authentification</em>, celle-ci se passe en 2 étapes :</p> <ul> <li>on fait d'abord une recherche de l'utilisateur dans la base, via le RDN (ou un autre attribut)</li> <li>une fois le DN récupéré, on va faire une tentative de connexion avec le mot de passe.</li> </ul> <p>Pour tester ceci, on va utiliser différents paramètres (en mode Basic) :</p> <ul> <li>Durée du Job</li> <li>Nombre de clients (à savoir que si on n'a pas assez de clients disponibles, le job ne va pas démarrer)</li> <li>Nombre de threads par client</li> <li>Durée de montée en charge / descente de charge</li> <li>Nom et port du serveur LDAP, ainsi que la méthode de sécurité (aucune, StartTLS ou SSL)</li> <li>Bind DN et mot de passe utilisé pour la recherche (généralement, un compte de service)</li> <li>DN de base pour la recherche (par exemple : ou=Users,dc=example,dc=com)</li> <li>Périmètre de recherche (scope = subtree, single-level, base)</li> <li>Search Filter Pattern : le motif de recherche.</li> <li>Mot de passe utilisateur</li> </ul> <p>Pour que cela fonctionne, on aura au préalable inséré dans l'annuaire des utilisateurs de tests, avec le même mot de passe, puisque celui-ci est donné dans la configuration.</p> <p>Le motif de recherche LDAP peut être variabilisé. Par exemple, si j'ai généré des utilisateurs avec un uid=userXXXXX (XXXXX = numérique de 1 à 99999), je peux avoir différents motifs pour mon filtre LDAP :</p> <ul> <li>(uid=user[1-100000]) : recherche de user1 à user100000 de manière aléatoire</li> <li>(uid=user[1:100000]) : recherche de user1 à user100000 de manière séquentielle</li> </ul> <p>Un bouton permet de tester les paramètres (connexion à l'annuaire, existence du Base DN, etc).</p> <p>Une fois le job préparé, on peut l'activer pour qu'il soit traité par les clients. Il passe alors en état "<strong>Running</strong>".</p> <p>Lorsqu'il est terminé, il passe à l'état "<strong>Completed</strong>".</p> <p>On peut dupliquer / cloner un job si on veut le relancer tel quel, ou le modifier pour changer ses paramètres.</p> <h2>Données récupérées</h2> <p>Une fois que le <em>job</em> est terminé, on peut avoir accès aux données recueillies par les clients et centralisées sur le serveur.</p> <p>Les données peuvent être affichées sous forme de graphique, directement sur le serveur, ou être générées sous forme de rapport HTML ou PDF.</p> <p>Le rapport contient pas mal d'informations par défaut :</p> <ul> <li>le nom du job, sa description</li> <li>les informations de planification : durée, nombre de clients, nombre de threads</li> <li>paramètres du job</li> <li>les informations d'exécution : date de début et fin, durée, nom des machines clients</li> <li>les résultats des différentes requêtes : nombre, moyenne / seconde, moyenne / intervalle de collecte, ainsi qu'un graphe des données, et la même chose en temps de réponse.</li> <li>répartition des requêtes par statut et temps de réponse.</li> </ul> <h2>Autres éléments</h2> <p>Un système de "<em>folders</em>" permet de regrouper ses différents <em>jobs</em> ce qui peut être intéressant pour gérer les séances de tests, soit par type d'annuaire si on en compare plusieurs, soit par type de tests si on fait par exemple changer le nombre de threads.</p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2021-10-13T16:24:59+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">mer 13/10/2021 - 18:24</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/ldap" hreflang="fr">ldap</a></div> <div class="field__item"><a href="/tags/benchmark" hreflang="fr">benchmark</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> <h2 class="title comment-form__title">Ajouter un commentaire</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=212&amp;2=comment_node_blog&amp;3=comment_node_blog" token="rGeZhG9defyDWatkcDCg4uVhSr1m77C8ZNq7sKOkxhE"></drupal-render-placeholder> </section> Wed, 13 Oct 2021 16:24:59 +0000 vincentl 212 at https://www.vincentliefooghe.net Activation LDAPS sur Active Directory https://www.vincentliefooghe.net/content/activation-ldaps-sur-active-directory <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Activation LDAPS sur Active Directory</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><h2>Contexte</h2> <p>Lors des interactions en LDAP avec Active Directory, certaines actions nécessitent l’utilisation de LDAPS (LDAP sur SSL) entre le client et Active Directory.</p> <p>Ceci est notamment le cas si l’on veut modifier le mot de passe.</p> <p>Ce document décrit comment activer le LDAPS sur un environnement Active Directory.</p> <h2>Méthodes envisageables</h2> <p>A priori il y a deux méthodes possibles pour activer LDAPS sur un contrôleur de domaine :</p> <ul> <li>Installer un Certificat Racine sur le contrôleur de domaine</li> <li>Utiliser un certificat tiers sur le contrôleur de domaine.</li> </ul> <p>C’est la seconde méthode que nous allons détailler ici.</p> <h2>Procédure</h2> <p>Les étapes de mise en place sont les suivantes :</p> <ul> <li>Demande de certificat</li> <li>Signature de la demande de certificat</li> <li>Import du certificat sur le serveur</li> </ul> <h2>Certificat</h2> <p>Contraintes sur le certificat Le certificat qui sera généré doit respecter certaines contraintes :</p> <ul> <li>Il doit être validé pour l’authentification de server, c’est à dire contenir l’OID d’authentification du serveur (1.3.6.1.5.5.7.3.1)</li> <li>Le CN doit correspondre au FQDN du serveur. Par exemple, si mon serveur s’appelle pdc1.mondomaine.com, on aura CN=pdc1.mondomaine.com</li> </ul> <h3>Demande de certificat</h3> <p>La demande de certificat peut se faire dans une fenêtre de commande sous Windows, avec la commande suivante :</p> <pre>certreq -new request.inf request.req </pre><p>On aura auparavant créé le fichier request.inf contenant les informations suivantes :</p> <pre>;----------------- request.inf ----------------- [Version] Signature="$Windows NT$” [NewRequest] Subject = "CN=pdc1.mondomaine.com,O=IT,C=FR" ; replace with the FQDN of the DC KeySpec = 1 KeyLength = 2048 ; Can be 1024, 2048, 4096, 8192, or 16384. ; Larger key sizes are more secure, but have a greater impact on performance. Exportable = TRUE MachineKeySet = TRUE SMIME = False PrivateKeyArchive = FALSE UserProtected = FALSE UseExistingKeySet = FALSE ProviderName = "Microsoft RSA SChannel Cryptographic Provider" ProviderType = 12 RequestType = PKCS10 KeyUsage = 0xa0 [EnhancedKeyUsageExtension] OID=1.3.6.1.5.5.7.3.1 ; this is for Server Authentication ;----------------------------------------------- </pre><p>Note : les éléments du <em>Subject</em> doivent correspondre à ceux du certificat racine issu de la PKI.</p> <h3>Signature de la demande de certificat</h3> <p>La génération du certificat peut se faire via une commande OpenSSL, à partir du fichier <code>request.req</code> généré à l’étape précédente.<br />Le certificat racine aura été généré auparavant, dans le répertoire <code>/srv/pki/certs</code>. L'arborescence de ce répertoire est la suivante :</p> <pre>cd /srv/pki ls -R .: certs index.txt index.txt.attr newcerts private reqs serial ./certs: ca.crt ./newcerts: ./private: ca.key ./reqs: request.req </pre><p>On va générér le certificat à partir de la requête :</p> <pre>openssl ca -config /srv/pki/openssl.cnf -name CA_default -extensions CA_AD_SERVER -infiles /srv/pki/ca/reqs/request.req </pre><p>Le fichier openssl.cnf contient les lignes suivantes :</p> <pre>[ ca ] default_ca = CA_default [ CA_default ] dir = . certs = $dir/ca/certs new_certs_dir = $dir/ca/newcerts database = $dir/ca/index.txt certificate = $dir/ca/certs/ca.crt serial = $dir/ca/serial private_key = $dir/ca/private/ca.key default_days = 3650 default_md = sha256 preserve = no policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = optional organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ CA_AD_SERVER ] nsComment = "Certificat Serveur AD" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always issuerAltName = issuer:copy basicConstraints = critical,CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment nsCertType = client, server extendedKeyUsage = serverAuth, clientAuth </pre><p>Il faut ensuite extraire les informations « brutes », situées entre <code>-----BEGIN CERTIFICATE-----</code> et <code>-----END CERTIFICATE-----</code>.</p> <p>On va ensuite créer la “chaîne” de certificats, en concaténant le certificat racine :</p> <pre>cd /srv/pki/ca/certs cat dwdc1.crt ca.crt &gt; dwdc1-chain.crt </pre><h3>Intégration du certificat</h3> <p>Les certificats dwdc1-chain.crt et le certificat racine sont ensuite copiés sur le serveur Windows.</p> <p>Le certificat racine doit être intégré (en utilisant la console mmc) dans les autorités de certification racines de confiance.</p> <article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/LDAPSonAD_013.png" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;LDAPSonAD_013.png&quot;}" role="button" title="LDAPSonAD_013.png" data-colorbox-gallery="gallery-all--qQXT6IO0VU" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;LDAPSonAD_013.png&quot;}"><img src="/sites/default/files/styles/large/public/LDAPSonAD_013.png?itok=qeWJmF_T" width="480" height="223" alt="LDAPSonAD_013.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> <p>Le certificat chaîne peut ensuite être intégré via la commande :</p> <pre>certreq -accept dwdc1-chain.crt I</pre><p>On peut vérifier la bonne intégration, dans les certificats personnels.</p> <article class="media media--type-image media--view-mode-default" data-align="center"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Image</div> <div class="field__item"> <a href="https://www.vincentliefooghe.net/sites/default/files/LDAPSonAD_014.png" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;LDAPSonAD_014.png&quot;}" role="button" title="LDAPSonAD_014.png" data-colorbox-gallery="gallery-all--qQXT6IO0VU" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;LDAPSonAD_014.png&quot;}"><img src="/sites/default/files/styles/large/public/LDAPSonAD_014.png?itok=u-kAjPeE" width="480" height="115" alt="LDAPSonAD_014.png" loading="lazy" typeof="foaf:Image" class="image-style-large" /> </a> </div> </div> </article> <p>Il faut alors redémarrer le serveur sur lequel on vient d’installer le certificat.</p> <h3>Vérification</h3> <p>On peut vérifier en lançant <em>ldp.exe</em>, et en tentant une connexion sur le contrôleur de domaine, port 636.</p> <h2>Références</h2> <p>Ce document est basé sur les éléments suivants :</p> <p><a href="http://www.it-sudparis.eu/s2ia/user/procacci/Doc/ldaps-ad/ldaps-ad.html">http://www.it-sudparis.eu/s2ia/user/procacci/Doc/ldaps-ad/ldaps-ad.html</a></p> <p><a href="https://support.microsoft.com/en-us/help/321051/how-to-enable-ldap-over-ssl-with-a-third-party-certification-authority">https://support.microsoft.com/en-us/help/321051/how-to-enable-ldap-over…</a></p> <p><a href="https://www.petri.com/enable-secure-ldap-windows-server-2008-2012-dc">https://www.petri.com/enable-secure-ldap-windows-server-2008-2012-dc</a></p> <p><a href="https://social.technet.microsoft.com/wiki/contents/articles/2980.ldap-over-ssl-ldaps-certificate.aspx">https://social.technet.microsoft.com/wiki/contents/articles/2980.ldap-o…</a></p> <h2>Annexes</h2> <p>Pour plus de détails sur la partie SSL, on pourra se reporter à <a href="https://www.vincentliefooghe.net/content/mémento-openssl">https://www.vincentliefooghe.net/content/mémento-openssl</a></p> <h3>Génération du Certificat Racine</h3> <p>On génère d’abord la clé privée :</p> <pre>openssl genrsa -des3 -out /srv/pki/ca/certs/ca.key 2048</pre><p>Puis le certificat racine :</p> <pre>cd /srv/pki openssl req -new -x509 -days 3650 -key private/ca.key -sha256 -extensions v3_ca -out certs/ca.crt</pre><h3>Ajout du certificat dans OpenIDM</h3> <p>Si on veut activer les échanges sécurisés via SSL, il faut importer les certificats des serveurs distants dans le keystore OpenIDM.</p> <p>On peut récupérer le nom du truststore dans le fichier de configuration (<em>conf/boot/boot.properties</em>). Par défaut, il s’agit de OPENIDM_HOME/security/truststore.</p> <pre>cd /products/openidm/security keytool -import -alias ADLDAPS -file /tmp/ca/certs/dwdc1.crt -keystore truststore</pre><p>Il faut ensuite arrêter / relancer openidm</p> <p>Bien entendu, dans la déclaration du provisioner.openicf.json on va activer le ssl :</p> <pre> "configurationProperties" : { "host" : "&amp;{AD.HostName}", "port" : "&amp;{AD.LdapServerPortSSL}", "ssl" : true, "principal" : "&amp;{AD.DirectoryAdminName}", "credentials" : { "$crypto" : { </pre><p> </p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2017-05-04T15:37:48+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">jeu 04/05/2017 - 17:37</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/ssl" hreflang="fr">ssl</a></div> <div class="field__item"><a href="/tags/openssl" hreflang="fr">openssl</a></div> <div class="field__item"><a href="/taxonomy/term/3" hreflang="fr">openidm</a></div> <div class="field__item"><a href="/tags/ldap" hreflang="fr">ldap</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Thu, 04 May 2017 15:37:48 +0000 vincentl 176 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/activation-ldaps-sur-active-directory#comments Problème de connexion JDBC sur une base oracle https://www.vincentliefooghe.net/content/probl%C3%A8me-connexion-jdbc-sur-une-base-oracle <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Problème de connexion JDBC sur une base oracle</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Je suis tombé récemment sur un problème curieux, lors de l'installation d'une plate-forme de test de <a href="https://www.ca.com/us/products/identity-management.html">CA Identity Manager.</a></p> <p>L'application tourne sous JBoss EAP 6, avec un Java 1.8, et une base Oracle 12C.</p> <p>Après avoir installé la base et créé le listener, on observe un comportement curieux :</p> <ul> <li>la connexion sous sqlplus fonctionne bien</li> <li>la connexion avec un client java, via jdbc, tombe en <em>timeout</em>.</li> </ul> <p>Pour la connexion, je teste avec un client SQL java en ligne de commande (jisql, voir les tests ici <a href="https://www.vincentliefooghe.net/node/73">https://www.vincentliefooghe.net/node/73</a>).</p> <pre>SQLException : SQL state: 08006 java.sql.SQLRecoverableException: Erreur d'E/S: Connection reset ErrorCode: 17002 </pre><p>Mais on a le même souci lors du déploiement de l'application sous JBoss :</p> <pre>WARN [org.jboss.jca.core.connectionmanager.pool.strategy.PoolBySubject] (MSC service thread 1-2) IJ000604: Throwable while attempting to get a new connection: null: javax.resource.ResourceException: Could not create connection at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.getLocalManagedConnection(LocalManagedConnectionFactory.java:356) at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory.access$200(LocalManagedConnectionFactory.java:63) at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory$1.run(LocalManagedConnectionFactory.java:279) at org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory$1.run(LocalManagedConnectionFactory.java:270) at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_73] at javax.security.auth.Subject.doAs(Subject.java:422) [rt.jar:1.8.0_73] </pre><p>Après plusieurs - longues - recherches sur internet, il s'avère que c'est lié au calcul d'entropie.</p> <p>En passant un paramètre dans la commande java, on supprime ces problèmes :</p> <pre>java -Djava.security.egd=file:///dev/urandom</pre><p>Dans le lancement de JBoss, on ajoute la ligne suivante, avant l'appel à la JVM :</p> <pre>JAVA_OPTS=" $JAVA_OPTS -Djava.security.egd=file:///dev/urandom "</pre><p> </p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2017-01-04T16:54:52+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">mer 04/01/2017 - 17:54</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/java" hreflang="fr">java</a></div> <div class="field__item"><a href="/tags/oracle" hreflang="fr">oracle</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Wed, 04 Jan 2017 16:54:52 +0000 vincentl 172 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/probl%C3%A8me-connexion-jdbc-sur-une-base-oracle#comments Mémento OpenSSL https://www.vincentliefooghe.net/content/m%C3%A9mento-openssl <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Mémento OpenSSL</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Après avoir pas mal "joué" avec les certificats SSL ces derniers temps, pour des besoins de sécurisation d'accès à un annuaire LDAP entre autre, je me fais un petit mémo des commandes les plus utilisées.</p> <p><a href="https://www.openssl.org">OpenSSL</a> permet de gérer les certificats utilisés dans les connexions SSL (https, ldaps, etc.). Sur les O.S. de type Unix/Linux, il est généralement présent dans les dépôts et s'installe facilement :</p> <pre>yum install openssl</pre><p>ou encore</p> <pre>apt-get install openssl</pre><p>On dispose ensuite d'une quarantaine de commandes, qui permettent de gérer des certificats ou des clés.</p> <ul> <li><a href="#privkey">Génération d'une clé privée</a></li> <li><a href="#autosign">Génération d'un certificat auto-signé</a></li> <li><a href="#csrreq">Génération d'une demande de certificat (CSR)</a></li> <li><a href="#signcsr">Signature d'un CSR</a></li> <li><a href="#verif">Vérification d'un certificat</a></li> <li><a href="#rempass">Suppression de la pass-phrase d'une clé</a></li> <li><a href="#pkcs12">Conversion en format PKCS12</a></li> </ul> <h3 id="privkey">Générer une clé privée</h3> <p>Génération d'une clé privée, de 2048 bits, avec un algorithme DES3. Avec demande de <em>pass phrase</em> :</p> <pre>openssl genrsa -des3 -out macle.key 2048 Generating RSA private key, 2048 bit long modulus ...........+++ .............+++ e is 65537 (0x10001) Enter pass phrase for macle.key: Verifying - Enter pass phrase for macle.key: </pre><p><strong>N'oubliez pas de noter la pass phrase</strong>, elle sera utilisée par la suite</p> <h3 id="autosign">Génération d'un certificat auto-signé</h3> <p>Génération d'un certificat, auto-signé, avec une durée de 3650 jours (10 ans).<br />Il faut saisir la <em>pass phrase</em> pour utiliser la clé privée.</p> <pre>openssl req -new -x509 -days 3650 -key macle.key -sha256 -extensions v3_ca -out macle.crt Enter pass phrase for macle.key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:FR State or Province Name (full name) []:. Locality Name (eg, city) [Default City]:. Organization Name (eg, company) [Default Company Ltd]:My Company Organizational Unit Name (eg, section) []:My Department Common Name (eg, your name or your server's hostname) []:ldap.mycompany.com Email Address []: </pre><h3 id="csrreq">Génération d'une demande de certificat (CSR)</h3> <p>Si on ne veut pas générer un certificat auto-signé (pas reconnu dans les navigateurs et clients), il faut généralement passer par une étape intermédiaire : générer un CSR (Certificate Signing Request) qui sera signé par une autorité de certification (les sociétés telles que Verisign, Thwate &amp; Co). On peut aussi utiliser son propre certificat auto-signé comme certificat d'autorité par la suite.</p> <pre>openssl req -sha256 -new -key macle.key -out macle.csr -days 3650 Enter pass phrase for macle.key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:FR State or Province Name (full name) []:. Locality Name (eg, city) [Default City]:. Organization Name (eg, company) [Default Company Ltd]:My Company Organizational Unit Name (eg, section) []:My Department Common Name (eg, your name or your server's hostname) []:ldap.mycompany.com Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: </pre><p>Les informations à saisir sont globalement les mêmes que pour un certificat auto-signé, avec en option un mot de passe et le nom de la société.</p> <p>Ce fichier doit être envoyé à l'autorité de certification, qui va le signer et renvoyer un certificat validé.</p> <p>Le contenu du CSR est bien identifié comme une <em>CERTIFICATE REQUEST</em>:</p> <pre>cat macle.csr -----BEGIN CERTIFICATE REQUEST----- MIICnDCCAYQCAQAwVzELMAkGA1UEBhMCRlIxEzARBgNVBAoMCk15IENvbXBhbnkx FjAUBgNVBAsMDU15IERlcGFydG1lbnQxGzAZBgNVBAMMEmxkYXAubXljb21wYW55 LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKsWwBXdKvgyGyq6 BmlK5ay6RC1PnWjudnlSPDaiNNU3ZUyOVgcOPLxanhG84erI+/g6mui71+6nxtBa ZigsiZBzzoAA790O4Mb5J3BPUd5aHMn79BK74HblgMCUDqVCAwAouMRo1hjZB9Ak xl6dI+bu4WzeNeMrIsaW+aBvqLsW5CaRU8Qq9Jt3/KYm38I5DnkDyKh84wHMC6On xbpyiB8LxophrZEtrKOgV93XW9mHHzcBQgHHQ8L9u72yHo2HX+14ElWg3MZY/53m tlUBavO9s2Y3P8FnHRddbJpwdvPkJy6vlPuZxyPFGpdU1t6dAuKk3/ZffqMyPok1 F0P6cbsCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQBf4yNS8JPp4HtFnECQ032s ZVATdfdVZLY9UUQcYZYFlt9Ja91eskBKa1M5yvj7qJlUkA85bE9c3ZmlrHES7OFC z8c6hi7A2vLBHf9sLHvVbbekDgFobeXeMw/veaByvglIOFN40psNQiztBpcrdEHZ KXhuU0tKZIH/H/GqyfGPx2eLzAxDOQHhxqGq/vddmwNGXaKfEyfVzD/NhTdw6OlH 7B7h1DmhZ8i2jJhPLDsCArbgUQGRtG/Qxt7Sp9E+/JJoNTF9/pK+7zvbcdlfCMJk OHnfpt++Qf03ifuWzUfmQg3yFvUBU7Da6q9AMcfzyvCpfelouNE2arxxHXSZHK4I -----END CERTIFICATE REQUEST----- </pre><h3 id="signcsr">Signature d'un CSR</h3> <p>On va signer la demande de certificat (.csr) avec la clé et le certificat de l'autorité de certification :</p> <pre>openssl ca -in macle.csr -out macle.crt -keyfile ca.key -cert ca.crt -days 3650 -extensions usr_cert -notext -md sha256 Using configuration from /etc/pki/tls/openssl.cnf Enter pass phrase for ca.key: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 0 (0x0) Validity Not Before: Nov 24 13:01:30 2014 GMT Not After : Nov 21 13:01:30 2024 GMT Subject: countryName = FR stateOrProvinceName = France organizationName = My Company organizationalUnitName = My Department commonName = ldap.mycompany.com X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 90:D9:DA:D5:9C:DA:5E:40:F6:2B:16:2B:72:26:5F:AD:0B:20:02:78 X509v3 Authority Key Identifier: keyid:6E:B3:92:ED:A4:04:2C:A1:52:E2:5A:5A:CE:B5:F4:E5:19:ED:C0:E5 Certificate is to be certified until Nov 21 13:01:30 2024 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated </pre><p>Il est parfois nécessaire de créer un fichier index.txt et serial (selon les O.S.). Par exemple sur un Linux RHEL / CentOS :</p> <pre>touch /etc/pki/CA/index.txt echo 0000 &gt; /etc/pki/CA/serial </pre><h3 id="verif">Vérification d'un certificat</h3> <p>On peut vérifier le certificat de plusieurs manières :</p> <ul> <li>avec openssl verify, qui vérifie son DN et sa validité</li> <li>avec openssl x509, qui "dump" le contenu du certificat</li> </ul> <p>Par exemple :</p> <pre>openssl verify macle.crt macle.crt: C = FR, O = My Company, OU = My Department, CN = ldap.mycompany.com error 18 at 0 depth lookup:self signed certificate OK </pre><p>La vérification détermine qu'il s'agit d'un certificat auto-signé.</p> <p>Dans le cas d'un certificat signé par une autorité de confiance, on aura :</p> <pre>macle.crt: C = FR, ST = France, O = My Company, OU = My Department, CN = ldap.mycompany.com error 20 at 0 depth lookup:unable to get local issuer certificate </pre><p> </p> <p>on peut ajouter une option pour vérifier le "chaining" avec le certificat de l'autorité :</p> <pre>openssl verify -CAfile ca.crt macle.crt macle.crt: OK </pre><pre>openssl x509 -in macle.crt -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 0 (0x0) Signature Algorithm: sha256WithRSAEncryption Issuer: C=FR, ST=France, O=My Company, OU=My Department, CN=ROOT CA Validity Not Before: Nov 24 13:01:30 2014 GMT Not After : Nov 21 13:01:30 2024 GMT Subject: C=FR, ST=France, O=My Company, OU=My Department, CN=ldap.mycompany.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:ab:16:c0:15:dd:2a:f8:32:1b:2a:ba:06:69:4a: e5:ac:ba:44:2d:4f:9d:68:ee:76:79:52:3c:36:a2: 34:d5:37:65:4c:8e:56:07:0e:3c:bc:5a:9e:11:bc: e1:ea:c8:fb:f8:3a:9a:e8:bb:d7:ee:a7:c6:d0:5a: .../... </pre><h3 id="rempass">Suppression de la pass-phrase d'une clé</h3> <p>Il peut être utile de supprimer la <em>pass phrase</em> d'une clé privée, notamment si celle-ci doit être utilisée par une application. Ceci se fait via la commande :</p> <pre>cp macle.key macle.key.avecpass openssl rsa -in macle.key.avecpass -out maclesanspass.key Enter pass phrase for macle.key.avecpass: writing RSA key </pre><h3 id="pkcs12">Conversion en format PKCS12</h3> <p>Le format PKCS12 contient le certificat et la clé ; il est parfois utilisé pour l'import d'un certificat dans des <em>keystore</em> Java ou par des utilitaires Windows.</p> <p>Il faut disposer de la clé privé et du certificat pour les exporter au format pkcs12 :</p> <pre>openssl pkcs12 -export -inkey macle.key -in $acle.crt -name AliasDeLaCle -out macle.p12 </pre><p>Ceci demande d'entrer la <em>pass phrase</em> de la clé privée, et de saisir un nouveau mot de passe pour le fichier pkcs12.<br />Par exemple :</p> <pre>openssl pkcs12 -export -inkey macle.key -in macle.crt -name AliasDeLaMaCle -out macle.p12 Enter pass phrase for macle.key: Enter Export Password: Verifying - Enter Export Password: </pre></div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2014-11-24T13:09:00+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">lun 24/11/2014 - 14:09</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/ssl" hreflang="fr">ssl</a></div> <div class="field__item"><a href="/tags/openssl" hreflang="fr">openssl</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Mon, 24 Nov 2014 13:09:00 +0000 vincentl 113 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/m%C3%A9mento-openssl#comments Comment déplacer un Data File Oracle https://www.vincentliefooghe.net/content/comment-d%C3%A9placer-un-data-file-oracle <span property="dc:title" class="field field--name-title field--type-string field--label-hidden"> Comment déplacer un Data File Oracle</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>En cas de souci d'espace disque sur certaines partitions, il est possible de déplacer des <em>DataFiles</em> oracle. La démarche étant la suivante (dans l'ordre) :</p> <ul> <li>Récupérer le nom du fichier utilisé par le tablespace</li> <li>Mettre le tablespace en mode Offline</li> <li>Copier le fichier de données dans son nouveau répertoire</li> <li>Modifier le tablespace pour renommer le fichier de données</li> <li>Remettre le tablespace en mode Online</li> <li>Supprimer le fichier d'origine</li> </ul> <p>Ce qui se résume de la manière suivante :</p> <pre>sqlplus / as sysdba SQL&gt; SELECT FILE_NAME, BYTES FROM DBA_DATA_FILES WHERE TABLESPACE_NAME = 'ENROLE_DATA'; FILE_NAME BYTES ------------------------------------------------------------ ---------- /product/oracle/product/11.2.0.2/dbs/enrole1_data_001.dbf 1409286144 ALTER TABLESPACE enrole_data OFFLINE NORMAL; SQL&gt; exit</pre><p>On va ensuite copier le fichier, avec les commandes de l'O.S. Par exemple sous Unix/Linux :</p> <pre>cp /product/oracle/product/11.2.0.2/dbs/enrole1_data_001.dbf enrole1_data_001.dbf /product/oradat/ENROLE/datafile/enrole1_data_001.dbf</pre><p>A ce stade, on revient sous SQL*Plus :</p> <pre>sqlplus / as sysdba SQL&gt; alter tablespace enrole_data rename datafile '/product/oracle/product/11.2.0.2/dbs/enrole1_data_001.dbf' TO '/product/oradat/ENROLE/datafile/enrole1_data_001.dbf' ; Tablespace altered. SQL&gt; alter tablespace enrole_data online; Tablespace altered. SQL&gt; SELECT FILE_NAME, BYTES FROM DBA_DATA_FILES WHERE TABLESPACE_NAME = 'ENROLE_DATA'; FILE_NAME BYTES ------------------------------------------------------------ ---------- /product/oradat/ENROLE/datafile/enrole1_data_001.dbf 1409286144</pre><p>On peut ensuite supprimer le fichier d'origine, après avoir vérifié que la base de données fonctionnait correctement.</p> <pre>rm /product/oracle/product/11.2.0.2/dbs/enrole1_data_001.dbf</pre><p>Il va sans dire qu'il vaut mieux faire une sauvegarde de sa base de données avant les manipulations, et qu'il est bon également de lancer une sauvegarde après la modification.</p> <p> </p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2014-07-04T14:20:19+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">ven 04/07/2014 - 16:20</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/oracle" hreflang="fr">oracle</a></div> <div class="field__item"><a href="/tags/datafile" hreflang="fr">datafile</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Fri, 04 Jul 2014 14:20:19 +0000 vincentl 102 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/comment-d%C3%A9placer-un-data-file-oracle#comments Sécurisation SSL sur IBM httpServer https://www.vincentliefooghe.net/content/s%C3%A9curisation-ssl-sur-ibm-httpserver <span class="field field--name-title field--type-string field--label-hidden">Sécurisation SSL sur IBM httpServer</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Dans le contexte ITIM, nous voulons sécuriser l'accès au Self-Service via <em>https</em>, notamment car celui-ci permet aux utilisateurs de changer ou de ré-initialiser leur mot de passe.</p> <p>Cela a l'air facile, puisque le serveur http <em>IHS IBM Http Server</em> est basé sur <em>apache</em>. Dans un précédent article, j'expliquais comment faire pour <a href="http://www.vincentliefooghe.net/content/activer-un-acc%C3%A8s-https-sur-apache">activer un accès https sur apache</a>.<br />Malheureusement, IBM n'utilise pas les composants OpenSSL, mais utilise ses propres modules, et notamment <em>mod_ibm_ssl</em> pour le module du serveur http, qui est de plus incompatible avec les certificats SSL généré par les utilitaires OpenSSL. Il faut donc utiliser toute la panoplie des outils IBM.</p> <p>La mise en place de https passe par plusieurs étapes :</p> <ul> <li>Création du certificat</li> <li>Activation de SSL sur le serveur http</li> <li>Paramétrage du serveur https</li> </ul> <h2>Création du certificat</h2> <p>Nous allons faire les manipulations en ligne de commande, car le serveur ne dispose pas d'une interface graphique.</p> <p>L'utilitaire IBM dans ce cas est <strong>gsk7cmd</strong>, un script shell qui lance le programme Java <strong>ikeyman</strong>.<br />Cet utilitaire permet d'agir sur plusieurs éléments :</p> <ul> <li>les bases de données de clés (option keydb)</li> <li>les certificats (option cert)</li> <li>les demandes de certificats (option certreq)</li> <li>les clés secrètres (option seckey)</li> </ul> <p> </p> <p><strong>Note</strong> : on peut également utiliser le programme <strong>gsk7capicmd</strong>, qui est un exécutable POSIX (pas de Java), mais qui supporte un chiffrement plus fort que <strong>gsk7cmd</strong>. Il est également plus rapide.</p> <h3>Création d'une base de données de clés</h3> <p>Nous allons d'abord créer une base de données de clés (<em>key database</em>), qui va stocker les certificats. Cette base sera stockées dans le répertoire <code>/etc/ssl/certs</code>, qui permet de regrouper les certificats.</p> <pre>$IHS_HOME/bin/gsk7cmd -keydb -create -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer -type cms -expire 3650 -stash </pre><p>Les options utilisées :</p> <ul> <li>keydb : indique que l'on gère la base de données</li> <li>create : on va créer une nouvelle base de données</li> <li>db : chemin complet vers le fichier de la base</li> <li>pw : mot de passe pour accéder à la base de données</li> <li>type : précise le type de la base, CMS = Certificat Management System</li> <li>expire : durée (en jours) d'expiration du mot de passe</li> <li>stash : indique que l'on va cacher le mot de passe dans un fichier</li> </ul> <p>Nous pouvons ensuite créer un certificat. Celui-ci peut être auto-signé, ou être une demande de certification qui sera par la suite signé par une PKI interne, afin d'être reconnu par les navigateurs.</p> <h3>Génération d'un certificat auto-signé</h3> <pre>$IHS_HOME/bin/gsk7cmd -cert -create -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer -label "ITIM-Self-Service" \ -expire 3650 -default_cert [yes|no] -dn "CN=myserver.mycorp.com,O=mycorp,C=fr" </pre><p>Les options utilisées :</p> <ul> <li>cert : indique que l'on gère les certificats</li> <li>create : on va créer un nouveau certificat (auto signé)</li> <li>db : chemin complet vers le fichier de la base</li> <li>pw : mot de passe pour accéder à la base de données</li> <li>label : libellé pour le certificat</li> <li>default_cert : est-ce que le certificat est celui par défaut pour la base de données</li> <li>dn : DN complet (voir ci-dessous)</li> <li>expire : durée (en jours) d'expiration du mot de passe</li> </ul> <p>Le format du DN est celui-ci : CN=common_name, O=organization, OU=organization_unit, L=location, ST=state, province, C=country.<br />Seuls les attributs CN, O et C sont requis.<br />On peut par exemple avoir :</p> <pre>CN=itimserver.mycorp.com,O=MyCompany,OU=IT,C=FR</pre><p>Le CN doit correspondre au FQDN (Fully Qualified Domain Name) du serveur (correspondant à l'URL qui est protégée en https).</p> <h3>Génération d'une demande de certificat</h3> <p>On peut générer une demande de certificat, qui devra par la suite être signée par une autorité de certification :</p> <pre>$IHS_HOME/bin/gsk7cmd -certreq -create -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer -label "ITIM-Self-Service" \ -dn DN -size 1024 -file /etc/ssl/certs/itim-self.req </pre><h3>Réception du certificat signé</h3> <p>Une fois le certificat signé par l'autorité, on l'intègre dans la <em>key database</em> :</p> <pre>$IHS_HOME/bin/gsk7cmd -cert -receive -file /tmp/myNewCert.pem -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer \ -format [ascii | binary] -default_cert [yes | no] </pre><p>Par exemple :</p> <pre>$IHS_HOME/bin/gsk7cmd -cert -receive -file /etc/ssl/certs/itimserver.mycorp.com.pem \ -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer -format ascii -label "ITIM-Self-Service" -default_cert yes </pre><p>Les options utilisées :</p> <ul> <li>cert : indique que l'on gère les certificats</li> <li>receive : on va importer un certificat signé</li> <li>db : chemin complet vers le fichier de la base</li> <li>pw : mot de passe pour accéder à la base de données</li> <li>format : précise si l'autorité de certification fournit le certificat en format ASCII ou binaire</li> <li>label : libellé pour le certificat. Ceci permet de distinguer les différents certificats dans la base</li> <li>default_cert : est-ce que le certificat est celui par défaut pour la base de données</li> </ul> <h3>Lister les certificats dans la base</h3> <p>Il est possible de lister les certificats de la base :</p> <pre>bin/gsk7cmd -cert -list -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer Certificates in database /etc/ssl/certs/ihs.kdb: ITIM-Self-Service </pre><p>On peut également avoir le détail, en précisant le libellé :</p> <pre>bin/gsk7cmd -cert -details -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer -label ITIM-Self-Service Libellé : ITIM-Self-Service Taille de clé : 1024 Version : X509 V3 Numéro de série : 53 AA E8 E8 Emis par : CN=itimserver.mycorp.com, O=mycorp, C=FR Sujet : CN=itimserver.mycorp.com, O=mycorp, C=FR Valide : Du : mercredi 25 juin 2014 17 h 21 CEST au : samedi 22 juin 2024 17 h 21 CEST Empreinte digitale : 3D:00:42:7C:FB:84:76:0B:C7:F3:05:59:E0:DD:72:08:B3:B6:8B:6A Algorithme de signature : SHA1withRSA (1.2.840.113549.1.1.5) Etat de confiance : activé </pre><h3>Importer  un certificat</h3> <p>Il est également possible d'importer un certificat, <strong>uniquement</strong> au format PKCS12 ou KeyDatabase.</p> <p>Dans ce cas, la commande à utiliser est :</p> <pre>bin/gsk7cmd -cert -import -file /le/chemin/vers/monfichier.p12 -target_type kdb -target /etc/ssl/certs/ihs.kdb -target_pw IBMHttpServer</pre><p><strong>Note</strong> : l'utilisation de <strong>gsk7cmd</strong> (qui encapsule du Java) peut conduire à une erreur de type :</p> <pre><em>The command cannot complete because your JRE is using restricted policy files. Replace your policy files with the Unlimited Strength files.</em></pre><p>On peut dans ce cas utiliser la commande <strong>gsk7capicmd</strong>, qui est un exécutable Linux. La syntaxe n'est pas la même :</p> <pre>bin/gsk7capicmd -cert -import -db /le/chemin/vers/monfichier.p12 -type pkcs12 -target_type cms -target "/etc/ssl/certs/ihs.kdb" -target_pw IBMHttpServer</pre><p>Le fichier PKCS12 est protégé par un mot de passe, car il contient le certificat ET la clé privée.</p> <h2>Activation de SSL sur le serveur http</h2> <p>Maintenant que nous avons un certificat, il faut activer le SSL sur le serveur, en activant plusieurs choses :</p> <ul> <li>écouter sur le port 443</li> <li>charger le module mod_ibm_ssl</li> </ul> <p>Ceci s'effectue dans le fichier de configuration <code>$INS_HOME/conf/httpd.conf</code>, dans lequel on ajoutera les lignes suivantes :</p> <pre>.../... NameVirtualHost *:80 NameVirtualHost *:443 LoadModule ibm_ssl_module modules/mod_ibm_ssl.so Listen 443 </pre><p>Les deux premières lignes permettent de gérer les <em>VirtualHost</em> sur les ports http et https (voir ci-dessous).</p> <h2>Paramétrage du serveur https</h2> <p>Le paramétrage s'effectue dans le fichier <code>$INS_HOME/conf/httpd.conf</code>, au niveau d'un VirtualHost. Par exemple :</p> <pre>&lt;VirtualHost *:443&gt; ServerName myserver.mycorp.com SSLEnable KeyFile /etc/ssl/certs/ihs.kdb LogLevel warn ErrorLog logs/myserver-error.log CustomLog logs/myserver-access.log common &lt;/VirtualHost&gt; </pre><p>Pour le serveur <em>myserver.mycorp.com</em>, on active le SSL (paramètre <code>SSLEnable</code>), avec le fichier de base de données précisé par le paramètre <code>keyFile</code></p> <h2>Troubleshooting</h2> <h3>Erreur lors de l'import d'un certificat</h3> <p>Lors de l'import d'une fichier pkcs12, si le label existe déjà (pour la remplacer par exemple) on a un message :</p> <pre>Error: 23 Please refer to the GSKCapiCmd User's Guide for the meaning of the error. Error id: GSKKM_ERR_DATABASE_DUPLICATE_KEY_LABEL</pre><p>ou encore</p> <pre>Error: 2 Please refer to the GSKCapiCmd User's Guide for the meaning of the error.</pre><p>Dans ce cas, il faut d'abord supprimer l'ancien certificat, avec son label en paramètre :</p> <pre>bin/gsk7capicmd -cert -delete -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer -label MaVieilleCle</pre><h3>Erreur au redémarrage IHS</h3> <p>Si en redémarrant IHS, on a dans le fichier log des lignes telles que :</p> <pre>[Fri Jun 27 16:00:23 2014] [error] [client 128.240.165.134] [864a618] SSL0208E: SSL Handshake Failed, Certificate validation error </pre><p>Il s'agit d'un problème d'autorité de certification qui n'est pas reconnue. Ceci peut se vérifier avec la commande :</p> <pre>$IHS_HOME/bin/gsk7capicmd -cert -list -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer Certificates found: * default, - has private key, ! trusted *-! ITIM-Self-Service </pre><p>Le certificat existe, mais n'est pas digne de confiance...</p> <p><strong>Note</strong> : on utilise ici la commande <em>gsk7capicmd</em>, au lieu de <em>gsk7cmd</em>, mais les 2 commandes sont interchangeables.</p> <p>Il faut alors ajouter dans la base de données la chaîne de certificats qui ont permis de signer notre certificat :</p> <pre>$IHS_HOME/bin/gsk7capicmd -cert -add -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer -label ChainCA -file /tmp/chain.pem </pre><p>On peut alors vérifier que cela fonctionne :</p> <pre>bin/gsk7capicmd -cert -list -db /etc/ssl/certs/ihs.kdb -pw IBMHttpServer Certificates found: * default, - has private key, ! trusted ! ChainCA *-! ITIM-Self-Service </pre><h2>Références</h2> <p>Les références utilisées sont :</p> <ul> <li><a href="http://websphere-scripts.blogspot.fr/2010/11/ibm-http-server-ssl-configuration-using.html">http://websphere-scripts.blogspot.fr/2010/11/ibm-http-server-ssl-config…</a></li> <li><a href="ftp://ftp.software.ibm.com/software/webserver/appserv/library/v70/ihs_70.pdf">ftp://ftp.software.ibm.com/software/webserver/appserv/library/v70/ihs_7…</a></li> <li><a href="http://planetlotus.org/profiles/dave-hay_114257_more-on-ihs-and-ssl--ssl0208e-ssl-handshake-failed-certificate-validation-error">http://planetlotus.org/profiles/dave-hay_114257_more-on-ihs-and-ssl--ss…</a></li> <li><a href="http://publib.boulder.ibm.com/httpserv/ihsdiag/errorlog.html#SSL0208">http://publib.boulder.ibm.com/httpserv/ihsdiag/errorlog.html#SSL0208</a></li> </ul> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span class="field field--name-created field--type-created field--label-hidden">lun 30/06/2014 - 15:48</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/ihs" hreflang="fr">ihs</a></div> <div class="field__item"><a href="/tags/ssl" hreflang="fr">ssl</a></div> <div class="field__item"><a href="/tags/ibmhttpserver" hreflang="fr">ibmhttpserver</a></div> </div> </div> <section class="field field--name-comment-node-book field--type-comment field--label-hidden comment-wrapper"> </section> Mon, 30 Jun 2014 13:48:09 +0000 vincentl 101 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/s%C3%A9curisation-ssl-sur-ibm-httpserver#comments Envoi de mail : ajout d'un enregistrement DNS SPF contre le SPAM https://www.vincentliefooghe.net/content/envoi-mail-ajout-dun-enregistrement-dns-spf-contre-le-spam <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Envoi de mail : ajout d&#039;un enregistrement DNS SPF contre le SPAM</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item">Lors de l'envoi de mails à partir d'un domaine vers une adresse gmail, le message arrive dans les SPAMS.<h2>Identification de la cause</h2>Si on choisit "Afficher l'original" dans les options du message, on a quelque chose du type : Delivered-To: xxxxxxxx@gmail.com Received: by 10.194.120.39 with SMTP id kz7csp252651wjb; Thu, 15 May 2014 01:33:27 -0700 (PDT) X-Received: by 10.180.98.232 with SMTP id el8mr7428006wib.27.1400142807504; Thu, 15 May 2014 01:33:27 -0700 (PDT) Return-Path: &lt;no-reply@hebinweb.com&gt; Received: from vps58368.ovh.net (194.ip-37-187-182.eu. [37.187.182.194]) by mx.google.com with ESMTP id fx19si1569427wjc.191.2014.05.15.01.33.27 for &lt;xxxxxxx@gmail.com&gt;; Thu, 15 May 2014 01:33:27 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning no-reply@hebinweb.com does not designate 37.59.123.77 as permitted sender) client-ip=37.59.123.77; Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning no-reply@hebinweb.com does not designate 37.59.123.77 as permitted sender) smtp.mail=no-reply@hebinweb.com.fr Received: by vps58368.ovh.net (Postfix, from userid 1002) id BE8CE2E53B; Thu, 15 May 2014 10:33:29 +0200 (CEST) Subject: Order Verification Email Message-Id: &lt;20140515083329.BE8CE2E53B@vps58368.ovh.net&gt; Date: Thu, 15 May 2014 10:33:29 +0200 (CEST) From: no-reply@hebinweb.com.fr (Operator) This is a mail verification content. Please read the message header. Sent at: Thu May 15 10:33:29 CEST 2014 On constate dans les trace la ligne :<strong>Received-SPF: softfail (google.com: domain of transitioning <a href="mailto:no-reply@hebinweb.com">no-reply@hebinweb.com</a> does not designate 37.59.123.77 as permitted sender) client-ip=37.59.123.77;</strong>En clair, l'adresse IP du serveur source n'est pas clairement désignée comme étant autorisée à envoyer des mail pour le domaine hebinweb.com.<h2>Résolution du problème</h2>Il faut ajouter des champs de type TXT dans les enregistrements DNS du domaine, notamment pour autoriser l'adresse IP du serveur. Ces champs sont dits SPF (<a href="http://fr.wikipedia.org/wiki/Sender_Policy_Framework">Sender Policy Framework</a>), une norme de vérification du nom de domaine de l'expéditeur d'un message électronique.Le contenu du champ TXT doit être : nomdedomaine.tld. TXT v=spf1 ip4:IP_ADDRESS ~all Par exemple : hebinweb.com. TXT v=spf1 ip4:37.59.123.77 ~all Si on veut autoriser plusieurs adresses IP, on les sépare par un espace, dans le même enregistrement DNS : hebinweb.com. TXT v=spf1 ip4:37.59.123.77 ip4:46.105.18.175 ~all Une fois l'opération réalisée, Google ne considère plus les mails comme du spam.<strong>Note</strong> : d'autres serveurs de messagerie sont moins stricts et autorisent quand même la réception de mails depuis un domaine inconnu, sans vérifier ce paramétrage.On peut vérifier la mise à jour via la commande : dig TXT domaine.tldPar exemple : dig hebinweb.com TXT ; &lt;&lt;&gt;&gt; DiG 9.8.4-rpz2+rl005.12-P1 &lt;&lt;&gt;&gt; hebinweb.com TXT ;; global options: +cmd ;; Got answer: ;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 773 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 4 ;; QUESTION SECTION: ;hebinweb.com. IN TXT ;; ANSWER SECTION: hebinweb.com. 59145 IN TXT "v=spf1 ip4:37.59.123.77 ~all" hebinweb.com. 59145 IN TXT "v=spf1 ip4:46.105.18.175 ~all" On retrouve bien nos enregistrements TXT avec les 2 adresses IP déclarées </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2014-05-15T16:27:26+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">jeu 15/05/2014 - 18:27</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/dns" hreflang="fr">dns</a></div> <div class="field__item"><a href="/tags/spam" hreflang="fr">spam</a></div> <div class="field__item"><a href="/tags/spf" hreflang="fr">spf</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Thu, 15 May 2014 16:27:26 +0000 vincentl 99 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/envoi-mail-ajout-dun-enregistrement-dns-spf-contre-le-spam#comments Owncloud : convertir la base de SQLite à MySQL https://www.vincentliefooghe.net/content/owncloud-convertir-la-base-sqlite-%C3%A0-mysql <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Owncloud : convertir la base de SQLite à MySQL</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Lors de l'installation d'une instance <a href="http://owncloud.org/">OwnCloud</a>, j'ai pris les options par défaut, avec une base SQLite3.</p> <p>Ceci est visible dans le fichier de configuration :</p> <pre><!--?php $CONFIG = array ( 'instanceid' =--> '52186ab50eee7', 'passwordsalt' =&gt; 'ae24c0a26cb22899d0dd54285fee51', 'datadirectory' =&gt; '/var/www/owncloud/data', 'dbtype' =&gt; 'sqlite3', 'version' =&gt; '5.0.17', 'installed' =&gt; true, 'maxZipInputSize' =&gt; 209715200, 'allowZipDownload' =&gt; true, ); </pre><p>Hors, j'ai sur le serveur plusieurs bases MySQL, qui sont sauvegardées régulièrement, et au final je préférerais donc avoir toutes mes données dans du MySQL (ou MariaDB en l'occurence).</p> <p>Il est possible de convertir la base SQLite3 en MySQL, puis modifier le fichier de configuration pour faire pointer sur la "bonne" base.</p> <p>Ceci se fait en plusieurs étapes :</p> <ul> <li>Installation de sqlite3</li> <li>Dump du contenu de la base sqlite3</li> <li>Conversion du dump au format MySQL</li> <li>Création d'une base MySQL</li> <li>Import du contenu</li> <li>Modification du fichier de configuration</li> </ul> <h2>Installation et dump</h2> <p>L'installation se fait de la manière suivante (sur debian) :</p> <pre>apt-get install sqlite3 </pre><p>On se positionne ensuite dans le répertoire <em>/var/www/owncloud/data</em>, dans lequel on trouve un fichier owncloud.db,et on lance la commande :</p> <pre>sqlite3 owncloud.db .dump &gt; dump.mycloud.sql </pre><h2>Conversion</h2> <p>Le format du fichier dump est différent entre les bases sqlite3 et MySQL. Il est donc nécessaire de le convertir. On peut trouver un <a href="http://www.redmine.org/attachments/download/6239/sqlite3-to-mysql.py">script python</a> qui effectue cette conversion, via la séquence suivante :</p> <pre>wget http://www.redmine.org/attachments/download/6239/sqlite3-to-mysql.py chmod a+x sqlite3-to-mysql.py cat dump.mycloud.sql | python sqlite3-to-mysql.py &gt; owncloud.sql </pre><p>A ce niveau, le fichier owncloud.sql contient des instructions compatibles avec MySQL.</p> <h2>Création de la base MySQL et import des données</h2> <p>On va créer une base MySQL, avec les commandes :</p> <pre>mysql -u root --password=ROOTPASS create database DB; grant all on DB.* to 'USER'@'localhost' identified by 'PASS' exit mysql -u USER --password=PASS DB &lt; owncloud.sql </pre><h2>Changement de la configuration OwnCloud</h2> <p>Il reste à modifier le fichier de configuration pour lui indiquer les nouveaux paramètres. Pour des raisons de sûreté, on fait d'abord une sauvegarde de la configuration avec sqlite3 :</p> <pre>sudo cp config.php config.php.sqlite3 </pre><p>Reste à indiquer les nouveaux paramètres :</p> <pre><!--?php $CONFIG = array ( 'instanceid' =--> '52186ab50eee7', 'passwordsalt' =&gt; 'ae24c0a26cb22899d0dd54285fee51', 'datadirectory' =&gt; '/data/www/owncloud/data', 'dbtype' =&gt; 'mysql', 'dbname' =&gt; 'DB', 'dbhost' =&gt; 'localhost', 'dbtableprefix' =&gt; 'oc_', 'dbuser' =&gt; 'USER', 'dbpassword' =&gt; 'PASS', 'installed' =&gt; true, 'maxZipInputSize' =&gt; 209715200, 'allowZipDownload' =&gt; true, ); </pre><p>On profite maintenant d'une base régulièrement sauvegardée, et de performances nettement améliorées !</p> <p><strong>Référence</strong> : <a href="http://fabianpeter.de/cloud/owncloud-migrating-from-sqlite-to-mysql/">http://fabianpeter.de/cloud/owncloud-migrating-from-sqlite-to-mysql/</a></p> <p>Addendum : lors d'un autre essai, j'ai également du modifier des clauses CLOB (sqlite) en LONGTEXT (mysql).</p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2013-12-13T21:02:09+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">ven 13/12/2013 - 22:02</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/owncloud" hreflang="fr">owncloud</a></div> <div class="field__item"><a href="/tags/mysql" hreflang="fr">mysql</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> <article data-comment-user-id="0" id="comment-14" class="comment js-comment by-anonymous"> <mark class="hidden" data-comment-timestamp="1394609170"></mark> <footer class="comment__meta"> <p class="comment__submitted">Soumis par <span lang="" typeof="schema:Person" property="schema:name" datatype="">André Schild</span> le mer 12/03/2014 - 08:26</p> <a href="/comment/14#comment-14" hreflang="fr">Permalien</a> </footer> <div class="content"> <h3><a href="/comment/14#comment-14" class="permalink" rel="bookmark" hreflang="fr">Don&#039;t use this for owncloud 6</a></h3> <div class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item">According to the original page, this will break owncloud 6 installation.<a href="http://fabianpeter.de/cloud/owncloud-migrating-from-sqlite-to-mysql/">http://fabianpeter.de/cloud/owncloud-migrating-from-sqlite-to-mysql/</a> So use this only for owncloud version 5</div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=14&amp;1=default&amp;2=fr&amp;3=" token="n9DVM4AiC6_wboV8WncKOs4ZeZcrbT8EIk6yU74K4M4"></drupal-render-placeholder> </div> </article> </section> Fri, 13 Dec 2013 21:02:09 +0000 vincentl 83 at https://www.vincentliefooghe.net Copier / Coller entre une applet Java et le presse-papier https://www.vincentliefooghe.net/content/copier-coller-entre-une-applet-java-et-le-presse-papier <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">Copier / Coller entre une applet Java et le presse-papier</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>J'ai parfois des soucis lorsque l'essaye de copier le contenu d'une applet Java (utilisées par exemple dans IBM Tivoli Identity Manager pour définir les workflows).</p> <p>Impossible de copier le contenu dans un programme externe, via le presse-papiers (<em>clipboard</em> en anglais).</p> <p>La copie dans l'autre sens n'est pas possible non plus.</p> <p>Pour résoudre ce problème, il faut ajouter une ligne dans le fichier <em>java.policy</em>. Souci sur ma machine : j'ai une petite dizaine de ces fichiers, en fonction des mises à jour des JVM.</p> <pre>find / -name java.policy /etc/java-6-openjdk/security/java.policy /etc/java-7-openjdk/security/java.policy /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/java.policy /usr/lib/jvm/java-6-openjdk-amd64/jre/lib/security/java.policy /usr/lib/jvm/java-6-oracle/jre/lib/security/java.policy</pre><p>Pour éviter de modifier tous ces fichiers, et garder la fonctionnalité quelle que soit la version de JVM installée, on peut créer un fichier java.policy dans le répertoire $HOME/.java, à partir d'un fichier existant :</p> <pre>cd /usr/lib/jvm cp java-6-oracle/jre/lib/security/java.policy $HOME/.java </pre><p>On ajoute ensuite les lignes à la fin, juste avant l'accolade de fin :</p> <pre> permission java.util.PropertyPermission "java.vm.vendor", "read"; permission java.util.PropertyPermission "java.vm.name", "read"; //Used to give access to clipboard (copy / paste) permission java.awt.AWTPermission "accessClipboard"; }; </pre><p>Si on lance une applet on peut ensuite vérifier que ça fonctionne. Ce qui évite de recopier bêtement des lignes à la main...</p> <p> </p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2013-08-26T15:57:16+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">lun 26/08/2013 - 17:57</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/java" hreflang="fr">java</a></div> <div class="field__item"><a href="/tags/clipboard" hreflang="fr">clipboard</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Mon, 26 Aug 2013 15:57:16 +0000 vincentl 75 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/copier-coller-entre-une-applet-java-et-le-presse-papier#comments A la recherche d'un client SQL en ligne de commande java https://www.vincentliefooghe.net/content/la-recherche-dun-client-sql-ligne-commande-java <span property="dc:title" class="field field--name-title field--type-string field--label-hidden">A la recherche d&#039;un client SQL en ligne de commande java</span> <div property="content:encoded" class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><h2>Contexte</h2> <p>Il est parfois nécessaire d'accéder aux données d'une base SQL externe, sans avoir forcément sur le poste les clients SQL propres à la plate-forme (<em>sql*plus, mysql-client, etc</em>).<br />Dans ce contexte, l'utilisation d'un client Java, utilisant JDBC, permet d'accéder à de multiples bases, pour peu que l'on dispose des bons <em>drivers</em>.<br />Une recherche sur internet mène rapidement vers <a href="http://java-source.net/open-source/sql-clients">java-source.net/open-source/sql-clients</a>, qui liste des clients Java.</p> <p>Recherchant uniquement des clients utilisables en ligne de commande (sur un serveur sans affichage X11), j'ai finalement retenu ces différentes solutions à tester :</p> <ul> <li>DataBase Java Console (DBJC)</li> <li>jisql</li> <li>sqlshell</li> <li>jsqsh</li> </ul> <p> </p> <p>J'ai donc testé ces différentes solutions, pour tenter d'en trouver une qui soit la mieux adaptée à mes besoins, à savoir :</p> <ul> <li>Utilisation en ligne de commande</li> <li>Déploiement simple</li> <li>Scriptable : utilisable dans un script shell avec un fichier de paramètres, sans intervention manuelle</li> <li>Permettant les SELECT mais aussi les mises à jour et plus généralement toutes opérations SQL</li> <li>sous licence libre, évidemment</li> </ul> <p>Toutes ces solution sont sous licence libre.</p> <h2>DataBase Java Console (DBJC)</h2> <h3>Présentation</h3> <p>DataBase Java Console (DBJC) est un projet accessible sur <a href="http://nioto.com/dbjc/">nioto.com/dbjc/</a>. Il semble assez ancien, car le contenu de l'archive date de Mai 2002.</p> <h3>Installation</h3> <p>L'installation est très simple : il suffit de décompresser l'archive, qui comprend :</p> <ul> <li>Un répertoire <code>lib</code>, qui contient le fichier jar</li> <li>Un fichier README, expliquant le mode d'utilisation</li> <li>Un fichier d'exemple de propriétés</li> <li>Un répertoire <code>src</code>, comprenant les sources</li> </ul> <h3>Utilisation</h3> <p><strong>dbjc</strong> s'utilise toujours conjointement avec un fichier <em>.properties</em>, qui définit le type de driver, l'utilisateur et son mot de passe, mais également les requêtes SQL à utiliser. Exemple type d'utilisation</p> <pre>CLASSPATH=/data/progs/squirrel-sql-3.4.0/lib/ojdbc-11.1.0.7.jar:/data/opt/jdbc/dbjc/lib/dbjc.jar export CLASSPATH java -cp $CLASSPATH com.nioto.dbjc.Main test.properties Choose a query: 0: Quit program 1: select * from PRA_PRF_APP where nsq_obj &gt; 610000 2: Select Profils d'une Application enter your choice: 2 Enter param value for param # 1 ( string ):620613 Results: ------- NSQ_PRA = 195 NSQ_OBJ = 620613 COD_UTL_PRA = ADMIN &lt;enter&gt; for next, or q to quit: -- NSQ_PRA = 196 NSQ_OBJ = 620613 COD_UTL_PRA = DEFAULT &lt;enter&gt; for next, or q to quit: -- NSQ_PRA = 275 NSQ_OBJ = 620613 COD_UTL_PRA = TEST &lt;enter&gt; for next, or q to quit: -- enter your choice: 0 exiting ... </pre><p>Comme on peut le voir, les fonctionnalités sont assez restreintes. L'affichage des résultats, notamment, n'est pas très exploitable, car il faut taper sur la touche <em>Entrée</em> pour faire défiler tous les résultats. Il n'est pas possible d'exporter le résultat sous forme d'un fichier, et seules les requêtes SELECT sont utilisables.</p> <h3>Conformité aux exigences</h3> <ul> <li>Utilisation : restreinte. Nécessite un fichier de propriétés, qui définit les opérations SELECT possibles</li> <li>Déploiement : très simple</li> <li>Scriptable : non. Demande toujours une intervention sur le clavier</li> <li>Opérations SQL: SELECT uniquement, prédéfinies</li> <li>Licence : GPL v2</li> </ul> <p>Cette solution est simple à installer, mais peu utilisable au final pour mes besoins.</p> <h2>jisql</h2> <h3>Présentation</h3> <p>jisql est un projet accessible sur <a href="http://www.xigole.com/software/jisql/jisql.jsp">www.xigole.com/software/jisql/jisql.jsp</a>. Les fichiers de l'archive datent de Septembre 2011.</p> <h3>Installation</h3> <p>Le fichier zip est simplement décompressé. Il contient :</p> <ul> <li>build.xml : fichier de <em>build java</em></li> <li>javadoc : répertoire contenant la documentation au format Javadoc</li> <li>lib : répertoire contenant les jars</li> <li>runit : exemple d'utilisation pour unix/linux</li> <li>runit.bat : exemple d'utilisation pour Windows</li> <li>runit_query : exemple d'utilisation avec requête</li> <li>src : répertoire contenant les sources</li> </ul> <h3>Utilisation</h3> <p><strong>jisql</strong> se lance via une ligne de commande :</p> <pre>CLASSPATH=/data/progs/squirrel-sql-3.4.0/lib/ojdbc-11.1.0.7.jar:/data/opt/jdbc/jisql-2.0.11/lib/jisql-2.0.11.jar:/data/opt/jdbc/jisql-2.0.11/lib/jopt-simple-3.2.jar export CLASSPATH DBUSER=scott DBPASS=tiger DRIVER=oracle.jdbc.driver.OracleDriver DBURL=jdbc:oracle:thin:@lnxql99723005.example.com:1521:MUTU export CLASSPATH java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c \; Enter a query: 1 &gt; select * from PRA_PRF_APP where nsq_obj &gt; 610000; NSQ_PRA | NSQ_OBJ | COD_UTL_PRA | -----------------------+------------------------+----------------------------------------------------------------------------------| 195 | 620613 | ADMIN | 196 | 620613 | DEFAULT | 275 | 620613 | TEST | Enter a query: 1 &gt; exit </pre><p><strong>jisql</strong> dispose de plusieurs options intéressantes, tel que :</p> <ul> <li>-input : nom d'un fichier comprenant les commandes à exécuter</li> <li>-query : requête SQL à exécuter</li> <li>-formatter : type de formatage en sortie (csv, xml, default)</li> </ul> <p>Par exemple, avec le script <code>jdbctest</code> qui contient le code :</p> <pre>#!/bin/sh CLASSPATH=/data/progs/squirrel-sql-3.4.0/lib/ojdbc-11.1.0.7.jar:/data/opt/jdbc/jisql-2.0.11/lib/jisql-2.0.11.jar:/data/opt/jdbc/jisql-2.0.11/lib/jopt-simple-3.2.jar export CLASSPATH DBUSER=scott DBPASS=tiger DRIVER=oracle.jdbc.driver.OracleDriver DBURL=jdbc:oracle:thin:@lnxql99723005.example.com:1521:MUTU export CLASSPATH java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c \; DBQUERY="select * from PRA_PRF_APP where NSQ_OBJ &gt; 610000;" echo "Formatter CSV" java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c\; -formatter csv -query "$DBQUERY" echo " " echo "Formatter XML" java -cp $CLASSPATH com.xigole.util.sql.Jisql -user $DBUSER -password $DBPASS -driver $DRIVER -cstring $DBURL -c\; -formatter xml -query "$DBQUERY" </pre><p>L'exécution de ce script donne les résultats suivants :</p> <pre> ./jdbctest Formatter CSV 195,620613,ADMIN 196,620613,DEFAULT 275,620613,TEST Formatter XML &lt;&lt;?xml version="1.0" encoding="utf-8" ?&gt; &lt;&lt;NSQ_PRA&gt;195&lt;&lt;NSQ_OBJ&gt;620613&lt;&lt;COD_UTL_PRA&gt;ADMIN &lt;&lt;NSQ_PRA&gt;196&lt;&lt;NSQ_OBJ&gt;620613&lt;&lt;COD_UTL_PRA&gt;DEFAULT &lt;&lt;NSQ_PRA&gt;275&lt;&lt;NSQ_OBJ&gt;620613&lt;&lt;COD_UTL_PRA&gt;TEST </pre><p>Il est également possible de donner des options supplémentaires pour le formattage CSV : délimiteur, nom des colonnes.</p> <h3>Conformité aux exigences</h3> <ul> <li>Utilisation : possible en ligne de commande sans interaction</li> <li>Déploiement : simple</li> <li>Scriptable : oui, possibilité d'utiliser un fichier pour les commandes à exécuter, et export en CSV ou XML</li> <li>Opérations SQL: toutes,</li> <li>Licence : Apache 2.0</li> </ul> <p><strong>jisql</strong> correspond bien à nos besoins. Il permet un fonctionnement en ligne de commande ou en script, permet de formatter les résultats sous diverses formes, exploitables par des programmes, et peut être complètement piloté par un fichier de requête.<br />De plus, il est livré avec ses sources et la javadoc, et on peut très facilement l'intégrer dans un script, vu le peu de dépendance et la taille réduite (88 ko pour les 3 librairies).</p> <h2>jsqsh</h2> <h3>Présentation</h3> <p>jsqsh, disponible sur <a href="http://sourceforge.net/projects/jsqsh/">sourceforge.net/projects/jsqsh</a>, et un client shell SQL, recommandé par IBM (<a href="sourceforge.net/projects/jsqsh">cf.</a>).</p> <p>Il se positionne comme un concurrent / remplaçant de SQL*Plus, avec des fonctionnalités assez semblables : historiques des commandes, utilisation de variables, formatage de sortie adaptable (CSV, etc).</p> <p>La dernière version 2.0 date du mois d'Août 2012.</p> <p><strong>jsqsh</strong> peut s'installer à partir des sources, ou à partir d'un fichier RPM ou DEB.<br />J'ai eu des difficultés pour le faire fonctionner avec une base Oracle (Erreur ORA-12504). La solution fonctionne bien avec du MySQL.</p> <h3>Installation</h3> <p>Sur une plate-forme Linux, l'installation est très simple. Elle peut se faire à partir du fichier RPM ou DEB.<br />Dans tous les cas, il existe aussi une archive sous forme de fichier ZIP, qu'il suffit de décompresser. L'archive comprend :</p> <ul> <li>bin : répertoire avec les scripts permettant de lancer <em>jsqsh</em></li> <li>share : répertoire contenant les librairies java utilisées</li> </ul> <p>L'ensemble des librairies "pèse" 2,2 Mo.</p> <h3>Utilisation</h3> <h3>Conformité aux exigences</h3> <ul> <li>Utilisation : ok.</li> <li>Déploiement : ok. Simple via les paquets ou l'archive</li> <li>Scriptable : oui. On peut lancer un script SQL en paramètres</li> <li>Opérations SQL: toutes les opérations sont possibles</li> <li>Licence : Apache v2</li> </ul> <p><strong>jsqsh</strong> est une solution complète, qui peut remplacer un outil tel que SQL*Plus. Il peut être un peu surdimensionné par rapport à nos besoins assez simples.<br />Du fait de l'impossibilité de se connecter à une base Oracle, cette solution ne sera pas retenue.</p> <p>L'analyse des logs Oracle donne les éléments suivants, avec deux solutions différentes, pour une connexion sur la même base : .<br />Avec <strong>jisql</strong> :</p> <pre>12-AUG-2013 15:56:09 * (CONNECT_DATA=(SID=ENROLE)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=vliefooghe))) * (ADDRESS=(PROTOCOL=tcp)(HOST=128.240.165.11)(PORT=48056)) * establish * ENROLE * 0 </pre><p>Avec <strong>jsqsh</strong></p> <pre>Mon Aug 12 15:57:39 2013 12-AUG-2013 15:57:39 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=__jdbc__)(USER=vliefooghe))(SERVICE_NAME=)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=vliefooghe))) * establish * 12504 TNS-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA TNS-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA </pre><p>Dans le deuxième cas, il manque bien le passage du paramètre SID. Je n'ai pas eu le courage ni le temps de récupérer les sources pour corriger le problème, d'autant plus que la solution me paraissant un peu trop "riche" pour mes besoins.</p> <p> </p> <h2>SQL Shell</h2> <h3>Présentation</h3> <p>SQL Shell est un projet qui remplace un terminal complet, et inclut par exemple la complétion de commandes, l'historique, etc. La dernière version date de Janvier 2010.<br />Le site du projet est <a href="http://sqlshell.sourceforge.net">http://sqlshell.sourceforge.net</a>.</p> <h3>Installation</h3> <p>Le fichier zip est simplement décompressé. Il contient :</p> <ul> <li>db : répertoire de configuration des bases de données</li> <li>lib : répertoire contenant les jars et librairies</li> <li>ChangeLog : journal des modifications</li> <li>db.properties : exemple de fichier de configuration de base de données</li> <li>README : fichier d'aide</li> <li>sqlshell : script principal à exécuter sous linux/unix</li> <li>sqlshell.bat : script principal à exécuter sous Windows</li> <li>sqlshell.jar : archive java du programme</li> </ul> <p>L'ensemble représente 2,5 Mo.</p> <p>Si vous avez une machine Linux 64bits, il faut récupérer les librairies sur <a href="http://sourceforge.net/projects/javacurses/">sourceforge.net/projects/javacurses/</a>, et les copier dans le répertoire <em>lib</em> aux côtés de la librairie java.</p> <h3>Utilisation</h3> <p>L'application utilise <em>jcurses</em>, et offre une interface complète de terminal.</p> <h3>Conformité aux exigences</h3> <ul> <li>Utilisation : propose un mode ligne de commande évolué, mais aussi l'utilisation de scripts</li> <li>Déploiement : assez simple, demande de disposer des bonnes librairies (fournies avec la solution, sauf les version 64bits)</li> <li>Scriptable : utilisation de script SQL externes possible</li> <li>Opérations SQL: toutes les opérations sont possibles</li> <li>Licence : Apache 2.0</li> </ul> <p><strong>sqlshell</strong> semble être une solution assez intéressante, dédiée à un usage interactif plutôt qu'à embarquer dans des scripts (même si c'est faisable). Les fonctionnalités de rappel de commande, édition d'une ligne, dump, etc. rendent l'outil assez sympathique à utiliser.</p> <h2>Conclusion</h2> <p>Suite aux différents tests réalisés, la solution <strong>jisql</strong> me semble être la plus intéressante : simple à utiliser, souple au niveau formattage, elle peut facilement être utilisée en mode script. Elle est également légère à installer.</p> <h2>Autres solutions</h2> <h3>sqlshell</h3> <p>Homonyme d'une autre solution, il s'agit d'une application scala. Disponible sur <a href="http://software.clapper.org/sqlshell/">software.clapper.org/sqlshell</a>. L'application fait plus de 10 Mo, dispose d'un installeur graphique... et donne une impression de sérieux : bien documenté, fonctionnalités assez complètes.</p> <p>Je ne l'ai cependant pas (encore ?) testé</p> <p>Et vous, quelle est votre solution fétiche pour accéder à vos bases SQL en java ?</p> </div> <span rel="sioc:has_creator" class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/users/vincentl" typeof="schema:Person" property="schema:name" datatype="">vincentl</span></span> <span property="dc:date dc:created" content="2013-08-14T19:25:19+00:00" datatype="xsd:dateTime" class="field field--name-created field--type-created field--label-hidden">mer 14/08/2013 - 21:25</span> <div class="field field--name-field-categorie field--type-entity-reference field--label-above"> <div class="field__label">Catégorie</div> <div class="field__item"><a href="/cat%C3%A9gorie/autres" hreflang="fr">Autres</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tag</div> <div class="field__items"> <div class="field__item"><a href="/tags/sql" hreflang="fr">sql</a></div> <div class="field__item"><a href="/tags/java" hreflang="fr">java</a></div> </div> </div> <section class="field field--name-comment-node-blog field--type-comment field--label-hidden comment-wrapper"> </section> Wed, 14 Aug 2013 19:25:19 +0000 vincentl 73 at https://www.vincentliefooghe.net https://www.vincentliefooghe.net/content/la-recherche-dun-client-sql-ligne-commande-java#comments