Partager une connexion VPN Windows sous Windows

Soit une connexion VPN définie sur un PC portable Windows. Comment peut-on dans ces conditions accéder à une ressource se trouvant de l’autre côté du tunnel depuis un téléphone mobile ?

Y a qu’à ouvrir le VPN depuis le routeur et non le poste de travail ? Ça a du sens, mais :

  • il faut avoir la main sur le routeur, c’est rarement le cas pour un travailleur nomade
  • il faut que le routeur supporte la technologie utilisée pour monter ce VPN (SSTP par exemple n’est pas très Linux friendly, ou alors si tout simplement on monte le VPN chez soit et qu’on se retrouve donc avec une infâme box d’un FAI)

Une autre solution est de configurer le VPN sur le smartphone ou la tablette, là encore il faut étudier la faisabilité technique. En général, ça ne passe pas.

Une solution qui fonctionne en toute autonomie est le partage de connexion internet avec une petite configuration en plus.

Le VPN est vu par Windows comme une nouvelle interface réseau. En configurant à l’avance une route statique vers les ressources mises à disposition par le VPN, le partage de connexion entre le Wi-Fi du PC portable et l’interface VPN va permettre au téléphone d’accéder au VPN.

On ajoute la route dans un prompt élevé comme suit :

route add [net] mask [mask] 0.0.0.0 metric [a low value] if [vpn interface number]

où :

  • net  et mask  permettent de désigner les ressources distantes. Si ces ressources vont de l’IP 172.16.8.0 à 172.16.9.255, alors net  vaudra 172.16.8.0 et mask  vaudra 255.255.254.0
  • la métrique doit être une valeur basse afin d’être prioritaire
  • le numéro d’interface du VPN est obtenu en tapant la commande route print . Le premier tableau liste toutes les interfaces préfixées par leur identifiant.
  • la passerelle, qui peut être dynamique, doit donc être considérée comme inconnue. C’est ce qu’on indique par 0.0.0.0 .

Domotisation de ma maison – part 1

Depuis peu, je me suis mis en tête d’ajouter une composante domotique à ma future maison.
Je ne suis pas un expert en électronique, loin de là et mes connaissances actuelles se limitent à l’étude de circuit basique composés de résistances, condensateurs et bobines.
On ne va pas aller loin avec ça, mais qu’à cela ne tienne, ce billet va concentrer le résultats de mes recherches sur le sujet.

Objectif

La domotique, comme plein d’autres secteur, offre un univers dont les perspectives ne sont limités que par notre imagination. Dis autrement, quand on sait faire, ce n’est en général pas la technique qui bloque, mais ce qu’on en fait avec. Par chance, c’est chez moi tout le contraire : l’idée est là, c’est la technique qui pêche.
Dans un premier temps, histoire de se familiariser avec ce nouveau domaine, mes objectifs vont se limiter à commander à distance des interrupteurs.

Ci-dessous la liste des exigences :

  • il faut que l’interrupteur manuel continue à fonctionner normalement, aucun programme ne peut s’adapter à toutes les situations du quotidien, et par conséquent je veux être capable d’imposer mes choix quand j’en ai envie, quitte à modifier ultérieurement le programme pour prendre en compte une nouvelle situation
  • les circuits « esclaves », ceux qui agissent sur les interrupteurs, devront être le plus petit possible, puisque je compte les mettre derrière l’interrupteur, dans le mur
  • les circuits « esclaves » devront également être auto-alimenté, ça serait vraiment con d’utiliser des piles alors qu’ils vont servir d’interrupteur sur le secteur (230V alternatif), de plus, il peut ne pas être évident de détecter un interrupteur mort et/ou d’en changer la pile
  • les circuits « esclaves » devront être conçus pour consommer un minimum d’énergie, étant donnés qu’ils vont être en fonctionnement permanent. Je vise, à priori, le 1W, avec une tension de 12V maxi et un courant consommé de 10mA. Dans ces conditions (très faible consommation), la consommation elle-même est une donnée beaucoup plus importante que l’efficacité du circuit, c’est à dire que je préfère avoir un circuit « pourri » qui consomme mon 1W, plutôt qu’un circuit à meilleur rendement qui consommerait 2W ; si on a les deux, tant mieux, mais l’important reste la consommation dans l’absolu.
  • l’ensemble des circuits esclaves devront pouvoir communiquer dans les 2 sens avec le circuit maître, afin de pouvoir recevoir un ordre du maître, mais également de pouvoir communiquer son état au maître
  • le circuit maître sera directement connecté avec un pc-routeur tout le temps allumé.

Les points à respecter étant posés, voyons chaque problèmes qui se sont présenté à moi et les solutions que j’ai retenu.

L’alimentation

L’alimentation par transformateur

Tout serait tellement plus simple si EDF envoyait du courant continu… mais ce n’est évidement pas le cas et il faudra faire avec.
J’ai étudié en cours de manière basique une alimentation « classique », c’est à dire avec transformateur, pont de diode, et un condensateur bien placé pour redresser le courant à la sortie du pont de diode (en savoir plus).

On remarquera au passage que ce type d’alimentation isole physiquement le circuit de son alimentation. C’est ce qu’on appelle une isolation galvanique et c’est une bonne chose, surtout vis à vis d’EDF.
Ce n’est pas une alimentation acceptable pour mon projet : non seulement le transformateur prend beaucoup de place, mais en plus il ferait du bruit. De plus, son rendement a l’air vraiment pourri (50%).

Les autres alimentations

J’ai pu trouver 3 autres manières de générer un courant basse tension continu à partir du secteur :

  • l’alimentation par résistance,
  • l’alimentation par condensateur ou « capa chuteur »
  • trois vieux composants, le MAX610 de MAXIM, le HIP5600 de Harris et le HV2405E de Intersil, tous obsolètes

On va sans plus s’étendre laisser tomber les vieux composants, bien qu’ils eussent pu résoudre rapidement le problème de l’alimentation.

L’alimentation par résistance semble peu prometteuse car là où le condensateur conserve de l’énergie pour la rendre plus tard, les résistances vont la dissiper. La perte énergétique risque d’être plus importante, et l’échauffement généré peut être problématique pour un circuit qui sera confiné et non aéré.

Il reste donc la solution « capa chuteur », que je retiens. Je vais probablement prendre la variante avec pont de diode puisque cela va permettre de diminuer de moitié l’ondulation résiduelle et augmenter de façon significative le rendement de l’alim.
Je ne sais pas exactement ce que va consommer mon circuit, mais l’ajout de 4 diodes, pour un prix dérisoire sont au pire superflus, au mieux augmenteront la durée de vie du micro-contrôleur par une tension plus stable.

L’interrupteur

Il n’a pas été facile de trouver l’interrupteur idéal. Qu’est ce qu’il doit faire cet interrupteur :

  • pouvoir être fermé ou ouvert par l’envoi d’un signal de très faible amplitude et si possible avec une très faible tension également, genre +3~5V
  • fonctionner sur du courant alternatif

J’ai pu trouver deux composants qui pouvaient répondre à ce besoin :

  • le TRIAC
  • le relais

Le relai électromécanique n’est pas très tentant à cause de sa taille imposante et son bruit, je le laisse donc de côté, sauf s’il n’y a pas mieux.
Le relai état solide (solid state) ne me semble pas indispensable.

Le TRIAC au contraire est plutôt intéressant par sa taille, mais en étudiant son fonctionnement, il y a juste un oOps des plus dérangeant. Pour que le TRIAC laisse passer un courant alternatif, donc qui passe sur la barre des 0V très souvent, la tension appliquée à la gateway doit être  »permanente », mais le seuil de déclenchement du TRIAC dépend de la polarité du courant passant.
http://www.bristolwatch.com/ele/triacs.htm
Soit donc il faut synchroniser les impulsions envoyés à la gateway avec le 50Hz de EDF, soit on oublie directement cette solution, qui :

  • provoque des micro-coupures
  • déforme le signal
  • serait responsables de parasites HF, et je n’ai aucune envie d’envoyer ça à mes appareils sensibles

On peut à la place utiliser un opto-triac, qui est la même chose, mais où la gateway est remplacée par une led à mettre sous tension. Tant que la LED est allumée, l’opto-triac est passant, pile ce qu’il me faut.
Actuellement, j’ai trouvé 2 candidats opto-triacs :

  • le MOC3021, peut servir d’interrupteur 230V, mais ne possède pas de détecteur de passage au 0V
  • le MOC3041, peut servir d’interrupteur 210V, mais possède un détecteur de passage au 0V, cela permet de réduire les parasites émis.

Ces modèles semblent également obsolètes, il faut que j’en cherche d’autres en choisissant judicieusement leur caractéristique, en particulier un courant d’entrée le plus petit possible.

Taille

En surfant, il se trouve que les composants traditionnels, ou traversants sont en perte de vitesse devant les composants montés en surface (CMS). J’en avais déjà vu plein en réalité, mais je n’avais tout simplement pas pu les identifier. On a ainsi sous ce format des résistantes et des diodes.
Ce format est mieux en tout :

  • beaucoup moins encombrant
  • plus efficace
  • il n’est plus nécessaire de faire des trous sur le circuit imprimé

Le seul inconvénient à mes yeux serait qu’il est plus délicat à souder que les composants traditionnels, mais c’est loin d’être impossible et cela semble se faire très bien avec un fer à souder correct (27W semble idéal, au-delà il y a risque de cramer le composant), il faudra juste plus de précision et une pince.

Communication

Je pense partir sur une communication sans-fil. L’autre moyen étant d’utiliser le CPL, cela ne conviendra pas au circuit master qui sera alimenté par le PC et non directement par le secteur.
J’ai trouvé un transceiver (émetteur et récepteur) Aurel RTX MID 3V qui pourrait bien faire l’affaire, mais à 20€ pièce, j’ai pas intérêt à le faire griller durant mes tests.
D’après les spécifications, ce composant bouffe 20.008mA au maximum, c’est à dire en émission.
Aurel propose pour ce module un [manuel utilisateur|http://www.aurelwireless.com/wp-content/uploads/user-manual/650201033G_um.pdf|en] très précieux, puisqu’il indique la procédure à suivre pour basculer en mode émission ou réception, à savoir les pins à basculer et le délai d’attente incompressible entre 2 bascules.

Récapitulatif

Sources

Il y en a beaucoup trop pour que je les cites tous, surtout que ce billet a été rédigé en plein milieu de mes recherches, voici néanmoins les principaux :

Construire sa propre autorité de certification

Ce billet explique comment on peut monter une autorité de certification à 2 sous et surtout l’utiliser au quotidien sans pour autant sacrifier les exigences techniques en terme de sécurité.

Avant la technique, remettons en contexte, une autorité de certification doit répondre à au moins ces deux conditions :

  • les clés privées des autorités racines et intermédiaires doivent être tenues secrètes
  • les clés privées des autorités racines et intermédiaires ne doivent pas être perdues, autrement dit, il faut en garder au moins une copie, également secrète ailleurs.

Le mot « secret » est bien entendu à comprendre au sens « chiffré » et non pas caché en loose dans un dossier invisible ou similaire.

Et la contrainte :

  • la solution doit coûter un minimum

D’où la solution suivante, qui rempli toutes les exigences :

  • le stockage se fait sur une Dropbox (ou hébergement cloud similaire)
  • toutes les clés sont chiffrées
  • l’outil utilisé pour la manipulation et génération des certificats sera OpenSSL, qui est open-source et multi-plateforme (vraiment multi-plateforme, c’est à dire Linux, Cygwin et Windows)

Et maintenant la technique !

L’autorité de certification

OpenSSL est assez mal fichu sur la manière de configurer car il va nous falloir un fichier de configuration pour les certificats d’autorité, et un séparé pour les autres type de certificats. Voyons le contenu pour les certificats d’autorité, puisque c’est ce qui nous intéresse maintenant :

oid_section = new_oids

[ new_oids ]
STREET = 2.5.4.9
S = 2.5.4.8
PostalCode = 2.5.4.17

[ distinguished_name ]
C = FR
O = Kveer
OU = Root CA
CN = Kveer Root CA

[ req ]
default_bits = 4096
default_md = sha1
distinguished_name = distinguished_name
reqs_extensions = x509_ca
prompt = no
utf8 = yes

[ x509_ca ]
basicConstraints = critical,CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
keyUsage = critical, keyCertSign, cRLSign
crlDistributionPoints = URI:http://pki.kveer.com/my.crl

Rien d’extraordinaire ici. Le certificat à générer est marqué comme une autorité de certification, on précise son usage : signer des certificats et des listes de révocation de certification (CRL) et on précise le point de distribution des CRLs. On aurait pu également limiter la longueur de la chaîne de certification, je ne l’ai pas fait.
Et le script bash qui va bien :

#!/bin/bash

#cannot use ecdsa as windows nt 5.x does not support it yet.
# prime192v1 seems to be the best one otherwise.

CA_KEY=ca.key
CA_CERT=ca.crt
CONF=kveer-ca.openssl.cnf

if [[ -f ca.key && -f ca.crt ]]; then
echo 'There is already an existing CA root'
exit 1
fi

# password
stty -echo
read -p 'Please enter a password that will be used to encrypt all private keys: ' PASSWD;echo
stty echo

# key generation
openssl genrsa -aes192 -out ca.key -passout pass:"$PASSWD" 4096

# root ca cert generation
openssl req -new -x509 -extensions x509_ca -key ca.key -passin pass:"$PASSWD" -days 7300 -config $CONF -utf8 -out tmp.crt

mkdir certs reqs keys
touch index.txt
echo 01 > serial.txt
echo 00 > crlnumber

J’aurais souhaité utiliser l’algorithme ECDSA qui est pour le moment considéré plus sur, à taille de clé équivalente, mais pour conserver une compatibilité avec Windows NT5.1 (XP et 2003 Server), je suis resté à l’algorithme RSA.

  1. Le script commence par une petite vérification : ça serait dommage d’écraser son certificat racine, n’est-ce pas ?
  2. Il va demander un mot de passe (ce qui évitera de le taper 36 fois), lequel va servir à chiffrer la clé privée. Attention : c’est à ce moment qu’est définit LE mot de passe pour chiffrer toutes vos clés privées, il a donc intérêt à être costaud
  3. Il génère une clé privée, qu’il encode avant d’écrire sur le disque
  4. Il crée et signe un certificat dont la clé privée vient d’être généré
  5. Il crée quelques fichiers nécessaire à l’utilisation du module « ca » de openssl

Une fois le certificat créée, il ne reste plus qu’à déployer la partie publique (sous la forme du fichier ca.crt) vers tous vos postes pour que les futurs certificats émis puisse être validées par les postes clients.

Les certificats d’autorités intermédiaires

Avant de créer un certificat « standard », c’est à dire ceux qui servent à faire du SSL ou du S/MIME pour l’utilisateur final, je recommande vivement de créer encore un certificat d’autorité, signé par le précédent certificat, qu’on appelle alors certificat d’autorité intermédiaire.

La raison est que si par malheur le certificat racine vient à être compromis, vous êtes mort, tout le château de cartes tombe, vous devez repartir de zéro.
En revanche, si c’est un certificat d’autorité intermédiaire qui est compromis, vous êtes dans la merde également, mais il est possible de récupérer le coup en révoquant ce certificat au niveau du CRL de l’autorité racine, puis en recréant ce certificat d’autorité intermédiaire ainsi que de re-signer tous les certificats qu’il aurait pu émettre. Il n’est pas nécessaire de redéployer le certificat racine sur tous les postes, puisqu’il est safe.

Dans le schéma que je propose, la seule faille est la robustesse du mot de passe généré précédemment et d’éviter de le taper sur un poste dpoé au keylogger.
Si on stocke les fichiers sur une Dropbox, on peut considérer que les fichiers sont publics, et bien que cela puisse ne pas être agréable (on aurait la liste des certificats émis, leur type, leur usage…), l’autorité reste sûre tant que les clés privées ne sont pas déchiffrées, donc si le mot de passe utilisé ainsi que l’algorithme de chiffrage (ici : AES 192 bits) sont solides. Etant donné que AES 192bits est plus que solide, que la connaissance des certificats émis n’a que peu d’importance (avec toutes les conséquences que cela entraîne, puisque indirectement j’accepte de dévoiler une partie du réseau), je réduis la faiblesse de mon système au seul mot de passe.

Par ailleurs l’utilisation de certificats d’autorité intermédiaire permet de déléguer la gestion à un tiers ou un collègue à cet seule autorité intermédiaire sans risquer de tout compromettre. Pour rappel, il est possible de créer une autorité intermédiaire qui ne peut pas émettre de certificat d’autorité, en fixant la chaîne de certification à 0 sur cette autorité.

Les scripts maintenant. Tout d’abord le fichier de configuration :

oid_section = new_oids

[ new_oids ]
STREET = 2.5.4.9
S = 2.5.4.8
PostalCode = 2.5.4.17

[ req ]
default_bits = 4096
default_md = sha1
distinguished_name = distinguished_name

[ distinguished_name ]
countryName = Pays
countryName_default = FR
countryName_min = 2
countryName_max = 2

O = Sujet
O_default = Kveer

OU = Unité organisationnelle

CN = Common Name

[ x509_ca ]
basicConstraints = critical,CA:true
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
keyUsage = critical, keyCertSign, cRLSign
crlDistributionPoints = URI:http://pki.kveer.com/my.crl

Puis le script :

#!/bin/bash

#cannot user ecdsa because windows nt 5.x does not support it yet.
# prime192v1 seems to be the best one otherwise.

CA_KEY=ca.key
CA_CERT=ca.crt
CONF=kveer-subca.openssl.cnf
CONF_CA=kveer.openssl.cnf

if [[ ! (-f ca.key && -f ca.crt) ]]; then
echo 'There is no CA root'
exit 1
fi

if [ $# < 1 ]; then
echo "$0 certificate_name"
exit 2
fi

# password
stty -echo
read -p 'Please enter a password that will be used to encrypt all private keys: ' PASSWD;echo
stty echo

# key generation
openssl genrsa -aes192 -out tmp.key -passout pass:"$PASSWD" 4096

# root ca cert generation
openssl req -new -extensions x509_ca -key tmp.key -passin pass:"$PASSWD" -config $CONF -utf8 -out tmp.csr
openssl ca -config $CONF_CA -extensions x509_ca -days 3650 -keyfile $CA_KEY -key $PASSWD -cert $CA_CERT -in tmp.csr -out "$1.crt"

if [[ ! -f "$1.crt" || ! -f tmp.key || ! -f tmp.csr ]]; then
echo 'Missing files, stopping here'
exit 3
fi

mv "$1.crt" "certs/$1.crt"
mv tmp.key "keys/$1.key"
mv tmp.csr "reqs/$1.csr"

mkdir -p "$1/certs" "$1/keys" "$1/reqs"
cp "certs/$1.crt" "$1/ca.crt"
cp "keys/$1.key" "$1/ca.key"
cp *.sh "$1/"
cp *.cnf "$1/"
touch "$1/index.txt"
echo '00' > "$1/serial.txt"

En essence, c’est similaire au script précédent, mais ici le fichier n’est pas auto-signé, et un dossier est créer pour préparer la gestion de l’autorité intermédiaire. On notera les quelques vérifications pour éviter tout accident. Ce n’est pas exhaustif, mais ça me convient pour le moment.
Arrivé à cet étape nous avons une autorité de certification racine, ainsi qu’au moins une autorité de certification intermédiaire. On peut s’attaquer au plus intéressant.

Les certificats « serveur » et « client »

Par certificat « serveur » j’entends ceux utilisé pour authentifier le serveur, donc ceux servant pour initier une connexion SSL sur un serveur web, un protocol de messagerie comme SMTP, POP, IMAP en SSL ou TLS, ou encore un serveur FTP.
Et par certificat « client » j’entends ceux utilisés par Outlook pour signer ses messages.
On va avoir un « gros » fichier de configuration pour ces deux types de certificats :

oid_section = new_oids

[ new_oids ]
STREET = 2.5.4.9
S = 2.5.4.8
PostalCode = 2.5.4.17

[ ca ]
default_ca = default_ca

[ default_ca ]
dir = .
new_certs_dir = $dir/certs
certificate = $dir/ca.pem
private_key = $dir/private/ca.key
RANDFILE = $dir/private/.rand
default_days = 365
default_crl_days = 30
default_md = sha1
database = $dir/index.txt # list of all signed certificates
unique_subject = no # allows to generate multiple certs with same subject name
serial = $dir/serial.txt # next cetificate serial
crlnumber = $dir/crlnumber # next crl number
email_in_dn = no # no email in distinguished name
name_opt = ca_default
cert_opt = ca_default
copy_extensions = copy # copy all new extensions from request to certificate
policy = policy

[ policy ]
C = match
O = match
OU = match
CN = supplied

[ x509_server ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = URI:http://pki.kveer.com/my_kveer_vpn_ca.crl

[ x509_client ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
keyUsage = digitalSignature, keyAgreement
extendedKeyUsage = clientAuth
crlDistributionPoints = URI:http://pki.kveer.com/my_kveer_vpn_ca.crl

[ req ]
default_bits = 4096
default_md = sha1
distinguished_name = distinguished_name

[ distinguished_name ]
countryName = Pays
countryName_default = FR
countryName_min = 2
countryName_max = 2

O = Sujet
O_default = Kveer

OU = Unité organisationnelle
OU_default = VPN Services

CN = Common Name

Là j’ai pris l’exemple de mon autorité intermédiaire gérant les certificats pour un VPN. On prendra soin de changer le point de distribution des CRL : chaque autorité de certification doit avoir un point de distribution distinct, sinon il ne sert à rien et risque d’invalider les certificats d’une autre autorité.
Le script bash :

#!/bin/bash

#cannot user ecdsa because windows nt 5.x does not support it yet.
# prime192v1 seems to be the best one otherwise.

CA_KEY=ca.key
CA_CERT=ca.crt
CONF=kveer.openssl.cnf
CONF_TMP=_openssl.conf

if [[ ! (-f ca.key && -f ca.crt) ]]; then
    echo 'There is no CA root'
    exit 1
fi

if [ $# -lt 1 ]; then
    echo "$0 -n [certificate_name] -p [pathlen] -c [crlurl] [-e] [-s altsubject, -s...]"
    echo '-e for using an ecdsa key, else an rsa key'
    exit 2
fi

ECDSA=0
REUSE_PKEY=0
REUSE_REQ=0
REGEN=0
ONLY_REQUEST=0
SHA1=0
TEMPLATE=
FILENAME=
declare -a ALTSUBJECT
while getopts 'cen:rs:t:f:1' OPT
do
    case $OPT in
        c)
            ONLY_REQUEST=1
            ;;
        e)
            ECDSA=1
            ;;
        n)
            NAME=$OPTARG
            ;;
        r)
            REGEN=1
            REUSE_PKEY=1
            ;;
        s)
            ALTSUBJECT+=($OPTARG)
            ;;
        1)
            SHA1=1
            ;;
        t)
            TEMPLATE=$OPTARG
            ;;
        f)
            FILENAME=$OPTARG
            ;;
    esac
done

if [ "$FILENAME" = "" ]; then
    FILENAME=$NAME
fi

if [ -z "$NAME" ]; then
    echo 'Use -n to specify the certificate name.'
    exit 6
fi

if [ "$REGEN" -eq 0 -a -f "certs/$FILENAME.crt" ]; then
    echo 'A certificate with the same name exists already.'
    exit 5
fi

if [ -f "keys/$FILENAME.key" ]; then
    read -p 'An existing private has been found. Use it ? [yes|no] ' TEST;echo
    [[ "$TEST" = 'yes' || "$TEST" = 'y' ]] && REUSE_PKEY=1
fi

if [ -f "reqs/$FILENAME.csr" ]; then
    read -p 'An existing certificat request has been found. Use it ? [yes|no] ' TEST;echo
    [[ "$TEST" = 'yes' || "$TEST" = 'y' ]] && REUSE_REQ=1
fi

if [ "$TEMPLATE" = "" ]; then
    TEMPLATE=x509_server
fi

# password
stty -echo
read -p 'Please enter the master password: ' PASSWD;echo
stty echo

# key generation
if [ $REUSE_PKEY -eq 0 ]; then
    if [ $ECDSA -eq 1 ]; then
        openssl ecparam -conv_form compressed -name prime256v1 -genkey | openssl ec -aes128 -out tmp.key -passout pass:$PASSWD
    else
        openssl genrsa -aes192 -out tmp.key -passout pass:"$PASSWD" 2048
    fi
else
    ln -f "keys/$FILENAME.key" tmp.key
fi

if [ $REUSE_REQ -eq 0 ]; then
    # generate conf
    sed -e "s/^CN_default.*/CN_default = $NAME/g" \
        $CONF > $CONF_TMP
    if [ $SHA1 = 1 ]; then
        sed -i -e 's/sha256/sha1/g' $CONF_TMP
    fi
    if [ ${#ALTSUBJECT[@]} -gt 0 ]; then
        dns=0
        ip=0
        
        sed -i -e "/\\[[ $TEMPLATE \\]]/a subjectAltName = @subjectAltName" -e '$a [ subjectAltName ]' $CONF_TMP
        #sed -i "/\[ $TEMPLATE \]/a subjectAltName = @subjectAltName" -i '$a [ subjectAltName ]' $CONF_TMP
        
        
        for s in "${ALTSUBJECT[@]}"
        do
            if [[ $s =~ ^([0-9]+\.){3}[0-9]+$ || $s =~ ^[0-9\:]+$ ]]; then
                let ip++
                sed -i "/\[ subjectAltName \]/a IP.$ip=$s" $CONF_TMP
            else
                let dns++
                sed -i "/\[ subjectAltName \]/a DNS.$dns=$s" $CONF_TMP
            fi
        done
    fi

    # cert generation
    openssl req -new -extensions $TEMPLATE -key tmp.key -passin pass:$PASSWD -config $CONF_TMP -utf8 -out tmp.csr
else
    cp "reqs/$FILENAME.csr" tmp.csr
fi

[[ $ONLY_REQUEST == 0 ]] && openssl ca -config $CONF_TMP -days 3650 -extensions $TEMPLATE -keyfile $CA_KEY -key $PASSWD -cert $CA_CERT -in tmp.csr -out "$FILENAME.crt"

if [[ $ONLY_REQUEST == 0 && ! -f "$FILENAME.crt" || ! -f tmp.key || ! -f tmp.csr ]]; then
    echo 'Something wrong, stopping here'
    exit 3
fi

[[ $ONLY_REQUEST == 0 ]] && mv "$FILENAME.crt" "certs/$FILENAME.crt"
mv tmp.key "keys/$FILENAME.key"
mv tmp.csr "reqs/$FILENAME.csr"

Une seule ligne change en fonction de si l’on souhaite un certificat serveur ou client, c’est celle où la signature du certificat intervient avec le paramètre -extensions, qui indique ou bien la section x509_server pour un certificat serveur, ou bien la section x509_client pour un certificat client.

Les certificats EV

Ces certificats EV, ou extended validation, sont un peu spéciaux, précieux même en ce sens que du point de vue de l’utilisateur, cela rend la barre du navigateur vert, alors qu’avec les autres certificats, le navigateur se content de rendre la barre bleue ou bien d’afficher uniquement un cadenas.

ll s’agit de certificats ayant des informations supplémentaires, tout comme le certificat d’autorité qui l’a émis, dont certains non-référencé par OpenSSL d’ailleurs, donc à rajouter manuellement dans la section new_oids . Mais la liste des certificats d’autorité pouvant émettre des certificats EV est codé en dur dans chaque navigateur, donc même s’il est possible de forger un certificat en tout point identique au niveau de la liste des attributs contenus à un vrai certificat EV, y compris pour un usage interne, le navigateur ne reconnaîtra jamais un certificat que vous avez créée comme EV, il sera considéré comme un certificat standard.

Les autres script

Afin de parfaire l’autorité, d’autres script sont nécessaires.

Script de génération de la liste de révocation de certificats

Cette liste, aussi appelée plus simplement CRL, publiquement accessible et signée, permet d’informer sur les certificats qui ont été prématurément révoqués, pour une raison ou une autre (certificat compromis, perdu, clé privée faible, révocation d’accès…)

#!/bin/bash

# password
stty -echo
read -p 'Please enter the master password: ' PASSWD;echo
stty echo

openssl ca -gencrl -crldays 365 -keyfile ca.key -key $PASSWD -cert ca.crt -config kveer.openssl.cnf | openssl crl -outform DER -out crl.crl

Une fois la liste générée, il faudra la rendre accessible à l’adresse qui a été spécifiée par le paramètre crlDistributionPoints . Ce paramètre est présent dans chaque certificat généré, c’est de cette manière que le point de communication est connu. A noté que la CRL ne contenant que les numéros de séries des certificats émis par une autorité de certification, une CRL est propre à chaque autorité de certification.

Tout comme un certificat, la CRL a une durée de vie, ici fixé à 1 an, dont le but est de forcer régulièrement le programme à récupérer la version à jour de la liste des certificats périmés. Surtout qu’un certificat révoqué ne se fait que lorsqu’un problème de sécurité est rencontré, il est impératif que l’information se propage au plus vite afin de limiter l’utilisation abusive d’un certificat périmé.

Remarque : tous les certificats émis par une même autorité de certification doivent avoir la même adresse dans le paramètre crlDistributionPoints .

Corollaire 1 : Pour une autorité de certification intermédiaire B, son point de distribution est donc celle décidé par l’autorité A ayant signée le certificat intermédiaire, dans mon cas, c’est donc l’autorité racine.

Corollaire 2 : Une autorité intermédiaire B ne peut pas se révoquer elle-même. Son autorité parente A peut révoquer  B et publier un nouveau CRL signé avec la clé de l’autorité parente A.

Script de révocation

Ce script permet de révoquer un certificat émis, c’est-à-dire le rendre invalide avant sa date d’expiration.

#!/bin/bash

CA_KEY=ca.key
CA_CERT=ca.crt
CONF_CA=kveer.openssl.cnf

if [[ ! (-f ca.key && -f ca.crt) ]]; then
    echo 'There is no CA root'
    exit 1
fi

if [[ $# < 1 ]]; then
    echo "$0 certificate_name"
    exit 2
fi

# password
stty -echo
read -p 'Please enter the master password: ' PASSWD;echo
stty echo

openssl ca -revoke certs/$1.crt -keyfile ca.key -key $PASSWD -cert ca.crt -config $CONF_CA

Ce script est inutile tout seul. Une fois un certificat révoqué, la CRL doit être mise à jour afin de publier l’information.

Script d’export au format PFX

Le seul moyen d’importer un certificat avec sa clé privée dans un magasin de certificats géré par Windows est de passer par un package PFX ou PKCS12. Il s’agit d’un standard permettant d’échanger du contenu sensible à l’aide d’un mot de passe.

#!/bin/bash

#cannot user ecdsa because windows nt 5.x does not support it yet.
# prime192v1 seems to be the best one otherwise.

if [[ $# < 1 ]]; then
    echo "$0 certificate_name"
    exit 2
fi

# Generate a random password
#  $1 = number of characters; defaults to 32
#  $2 = include special characters; 1 = yes, 0 = no; defaults to 1
function randpass {
    [ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]"
    cat /dev/urandom | tr -cd "$CHAR" | head -c ${1:-32}
}

EXPORT=$(randpass 20 0)
echo "Note this import password somewhere:" $EXPORT

# password
stty -echo
read -p "Please enter the password: " PASSWD;echo
stty echo

cat "keys/$1.key" "certs/$1.crt" ca.crt ../ca.crt | openssl pkcs12 -export -name "$1" -passout pass:$EXPORT -passin pass:$PASSWD -aes192 -out "certs/$1.pfx" -CAfile ca.crt

Il suffit de spécifier le nom d’un certificat précédemment généré et le script génère le PFX ainsi que son mot de passe de manière aléatoire.

Spam sur mon blog

Mon blog, que quasiment personne ne lit, est spammé à hauteur de 10 messages / mois, je n’ose même pas imaginer ce que ça doit être sur les blogs populaires, mais je salue l’existence d’outils performant tels qu’Akismet pour faire le tri entre les commentaires réels, et le reste.

Mais aujourd’hui en regardant les commentaires indésirables, je suis tombé sur ça :

{Hello|Hi} there, {simply|just} {turned into|became|was|become|changed into} {aware of|alert to} your {blog|weblog} {thru|through|via} Google, {and found|and located} that {it is|it's} {really|truly} informative. {I'm|I am} {gonna|going to} {watch out|be careful} for brussels. {I will|I'll} {appreciate|be grateful} {if you|should you|when you|in the event you|in case you|for those who|if you happen to} {continue|proceed} this {in future}. {A lot of|Lots of|Many|Numerous} {other folks|folks|other people|people} {will be|shall be|might be|will probably be|can be|will likely be} benefited {from your|out of your} writing. Cheers!
{It is|It's} {appropriate|perfect|the best} time to make {a few|some} plans for {the future|the longer term|the long run} and {it is|it's} time to be happy. {I have|I've} {read|learn} this {post|submit|publish|put up} and if I {may just|may|could} I {want to|wish to|desire to} {suggest|recommend|counsel} you {few|some} {interesting|fascinating|attention-grabbing} {things|issues} or {advice|suggestions|tips}. {Perhaps|Maybe} you {could|can} write {next|subsequent} articles {relating to|referring to|regarding} this article. I {want to|wish to|desire to} {read|learn} {more|even more} {things|issues} {approximately|about} it!
{Nice|Excellent|Great} post. {I used to be|I was} checking {continuously|constantly} this {blog|weblog} and {I am|I'm} {inspired|impressed}! {Very|Extremely} {useful|helpful} {information|info} {specially|particularly|specifically} the {final|last|ultimate|remaining|closing} {phase|part|section} :) I {take care of|care for|deal with|maintain|handle} such {info|information} {a lot|much}. {I used to be|I was} {seeking|looking for} this {particular|certain} {info|information} for a {long time|very {long|lengthy} time}. {Thank you|Thanks} and {good luck|best of luck}.
{hey|hello} there and {thank you|thanks} {for your|on your|in your|to your} {information|info} ? {I've|I have} {definitely|certainly} picked up {anything|something} new from {right|proper} here. I did {on the other hand|however|then again|alternatively} {expertise|experience} {some|a few|several} technical {issues|points} {the use of|using|the usage of} this {web site|site|website}, {since|as} I {experienced|skilled} to reload the {site|web site|website} {many|a lot of|lots of} {times|occasions|instances} {prior to|previous to} I {may just|may|could} get it to load {properly|correctly}. I {were|have been|had been} {thinking about|brooding about|pondering|considering|puzzling over|wondering} {if your|in case your} {hosting|web hosting|web host} is OK? {Now not|Not|No longer} that {I am|I'm} complaining, {however|but} {sluggish|slow} loading {cases|instances|circumstances} {times|occasions|instances} will {very frequently|often|sometimes} {have an effect on|affect|impact} your placement in google and {can|could} {damage|injury|harm} your {high quality|quality|high-quality} {rating|score|ranking} if {advertising|ads} and marketing with Adwords. {Anyway|Well} {I'm|I am} {adding|including} this RSS to my {e-mail|email} and {can|could} {glance|look} out for {a lot|much} {more|extra} of your respective {intriguing|fascinating|interesting|exciting} content. {Make sure|Ensure that} you {update|replace} this {again|once more} {soon|very soon}..
{Great|Wonderful|Fantastic|Magnificent|Excellent} {goods|items} from you, man. {I've|I have} {keep in mind|bear in mind|remember|consider|take into account|have in mind|take note|be mindful|understand|be aware|take into accout} your stuff {prior to|previous to} and {you're|you are} {simply|just} {too|extremely} {great|wonderful|fantastic|magnificent|excellent}. I {really|actually} like what {you've|you have} {got|received|obtained|acquired|bought} {here|right here}, {really|certainly} like what {you're|you are} {stating|saying} and {the way|the best way|the way in which} {in which|by which|during which|through which|wherein} {you assert|you are saying|you say} it. {You are making|You make|You're making} it {entertaining|enjoyable} and {you still|you continue to} {take care of|care for} to {stay|keep} it {smart|sensible|wise}. I {cant|can not|can't} wait to {read|learn} {far more|much more} from you. {This is|That is} {actually|really} a {terrific|great|wonderful|tremendous} {website|site|web site}.
{Pretty|Very} {great|nice} post. I {simply|just} stumbled upon your {blog|weblog} and {wanted|wished} {to mention|to say} that {I have|I've} {really|truly} {enjoyed|loved} {browsing|surfing around} your {blog|weblog} posts. {In any case|After all} {I'll|I will} be subscribing {for your|on your|in your|to your} {feed|rss feed} and {I am hoping|I hope|I'm hoping} you write {again|once more} {soon|very soon}!
I {like the|just like the} {valuable|helpful} {information|info} you {supply|provide} {for your|on your|in your|to your} articles. {I will|I'll} bookmark your {weblog|blog} and {test|check|take a look at} {again|once more} {here|right here} {frequently|regularly}. {I am|I'm} {rather|quite|somewhat|slightly|fairly|relatively|moderately|reasonably} {certain|sure} {I will|I'll} {be informed|be told|learn} {lots of|many|a lot of|plenty of|many} new stuff {right|proper} {here|right here}! {Good luck|Best of luck} for {the following|the next}!
{I think|I feel|I believe} {this is|that is} {one of the|among the} {so much|such a lot|most} {important|significant|vital} {information|info} for me. And {i'm|i am} {satisfied|glad|happy} {reading|studying} your article. {However|But} {wanna|want to|should} {observation|remark|statement|commentary} on {few|some} {general|common|basic|normal} {things|issues}, The {website|site|web site} {taste|style} is {perfect|ideal|great|wonderful}, the articles is {in point of fact|actually|really|in reality|truly} {excellent|nice|great} : D. {Just right|Good|Excellent} {task|process|activity|job}, cheers
{We are|We're} {a group|a gaggle|a bunch} of volunteers and {starting|opening} {a new|a brand new} scheme in our community. Your {site|web site|website} {provided|offered} us with {helpful|useful|valuable} {information|info} to {paintings|work} on. {You have|You've} {performed|done} {an impressive|a formidable} {task|process|activity|job} and our {whole|entire} {community|group|neighborhood} {will be|shall be|might be|will probably be|can be|will likely be} {grateful|thankful} to you.
{Undeniably|Unquestionably|Definitely} {believe|consider|imagine} that {that you|which you} {stated|said}. Your {favourite|favorite} {justification|reason} {appeared to be|seemed to be} {at the|on the} {internet|net|web} the {simplest|easiest} {thing|factor} to {keep in mind|bear in mind|remember|consider|take into account|have in mind|take note|be mindful|understand|be aware|take into accout} of. I say to you, I {definitely|certainly} get {irked|annoyed} {at the same time as|whilst|even as|while} {other folks|folks|other people|people} {consider|think about} {concerns|worries|issues} that they {plainly|just} {do not|don't} {realize|recognize|understand|recognise|know} about. You {controlled|managed} to hit the nail upon {the top|the highest} {as {smartly|well|neatly} as|and also|and} {defined|outlined} out {the whole thing|the entire thing} {with no need|without having} {side effect|side-effects} , {other folks|folks|other people|people} {can|could} take a signal. Will {likely|probably} be {back|again} to get more. {Thank you|Thanks}
{This is|That is} {very|really} {interesting|fascinating|attention-grabbing}, {You are|You're} {an overly|an excessively|a very} {professional|skilled} blogger. {I have|I've} joined your {feed|rss feed} and {look ahead to|look forward to|sit up for|stay up for} {in search of|seeking|looking for|in quest of|in the hunt for|searching for} {more|extra} of your {great|wonderful|fantastic|magnificent|excellent} post. {Also|Additionally}, {I have|I've} shared your {site|web site|website} in my social networks
{Hey|Hello} There. {I found|I discovered} your {blog|weblog} {the use of|using|the usage of} msn. {This is|That is} {a very|an extremely|a really} {smartly|well|neatly} written article. {I will|I'll} {be sure|make sure} to bookmark it and {come back|return} to {read|learn} {more|extra} of your {useful|helpful} {information|info}. {Thank you|Thanks} for the post. {I will|I'll} {definitely|certainly} {comeback|return}.
I {loved|liked|beloved|cherished} {up to|as much as} {you will|you'll} {receive|obtain} {performed|carried out} {right|proper} here. The {comic strip|cartoon|caricature|sketch} is {tasteful|attractive}, your authored {subject matter|material} stylish. {however|nevertheless|nonetheless}, you command get {bought|got} an {edginess|nervousness|impatience|shakiness} over that {you would like|you wish|you want} be {turning in|delivering|handing over} the following. {in poor health|ill|unwell|sick} {without a doubt|no doubt|undoubtedly|surely|certainly|for sure|definitely|unquestionably|indisputably|indubitably} come {further|more} {previously|earlier|beforehand|before|in the past|until now|formerly} {again|once more} {since|as} {precisely|exactly} {the similar|the same} {just about|nearly} {a lot|very} {frequently|regularly|incessantly|steadily|ceaselessly|often|continuously} {inside of|inside|within} case you {shield|defend|protect} this {increase|hike}.
{Hi|Hello}, {i think|i feel|i believe} that i {saw|noticed} you visited my {blog|weblog|website|web site|site} {so|thus} i {got here|came} to {go back|return} the {prefer|choose|favor|want|desire}?.{I am|I'm} {trying to|attempting to} {in finding|find|to find} {things|issues} to {improve|enhance} my {website|site|web site}!{I guess|I assume|I suppose} its {good enough|ok|adequate} {to use|to make use of} {some of|a few of} your {ideas|concepts|ideas}!!
{Simply|Just} {want to|wish to|desire to} say your article is as {astonishing|amazing|surprising|astounding}. The {clearness|clarity} {for your|on your|in your|to your} {post|submit|publish|put up} is {simply|just} {spectacular|nice|excellent|cool|great} {and i|and that i} {can|could} {think|assume|suppose} {you are|you're} {a professional|knowledgeable|an expert} {in this|on this} subject. {Well|Fine} {with your|together with your|along with your} permission {allow|let} me to {take hold of|grab|clutch|grasp|seize|snatch} your {RSS feed|feed} to {stay|keep} {up to date|updated} with {drawing close|approaching|coming near near|forthcoming|imminent|impending} post. {Thank you|Thanks} {a million|one million|1,000,000} and please {keep up|continue|carry on} the {gratifying|rewarding|enjoyable} work.
Its {like you|such as you} {read|learn} my {mind|thoughts}! You {seem|appear} {to understand|to know|to grasp} {so much|a lot} {approximately|about} this, {like you|such as you} wrote the {book|e-book|guide|ebook|e book} in it or something. {I think|I feel|I believe} {that you|that you simply|that you just} {could|can} do with {some|a few} {%|p.c.|percent} to {force|pressure|drive|power} the message {house|home} {a bit|a little bit}, {however|but} {other than|instead of} that, {this is|that is} {great|wonderful|fantastic|magnificent|excellent} blog. {A great|An excellent|A fantastic} read. {I'll|I will} {definitely|certainly} be back.
{Thank you|Thanks} for the {auspicious|good} writeup. It {if truth be told|in fact|actually|in reality|in truth} {used to be|was|was once} a {entertainment|amusement|leisure|enjoyment} account it. {Glance|Look} {complex|complicated|advanced} to {far|more} {brought|introduced|added|delivered} agreeable from you! {By the way|However}, how {can|could} we {keep in touch|keep up a correspondence|communicate|be in contact}?
{Hello|Hey|Hi} there, {You have|You've} {performed|done} {a great|an excellent|a fantastic|an incredible} job. {I will|I'll} {definitely|certainly} digg it and {for my part|personally|individually|in my opinion|in my view} {recommend|suggest} to my friends. {I am|I'm} {sure|confident} {they will|they'll} be benefited from this {site|web site|website}.
{Great|Wonderful|Fantastic|Magnificent|Excellent} beat ! I {wish to|would like to} apprentice {at the same time as|whilst|even as|while} you amend your {site|web site|website}, how {can|could} i subscribe for a {blog|weblog} {site|web site|website}? The account {aided|helped} me a {appropriate|applicable|acceptable} deal. I {were|have been|had been} {tiny|a little} bit {familiar|acquainted} of this your broadcast {provided|offered} {bright|shiny|brilliant|vibrant|vivid} {transparent|clear} {concept|idea}
{I am|I'm} {extremely|really} {inspired|impressed} {with your|together with your|along with your} writing {talents|skills|abilities} {and also|as {smartly|well|neatly} as} with the {layout|format|structure} {for your|on your|in your|to your} {blog|weblog}. {Is this|Is that this} a paid {subject|topic|subject matter|theme} or did you {customize|modify} it {yourself|your self}? {Either way|Anyway} {stay|keep} up the {nice|excellent} {quality|high quality} writing, {it's|it is} {rare|uncommon} {to peer|to see|to look} a {nice|great} {blog|weblog} like this one {these days|nowadays|today}..
{Pretty|Attractive} {part of|section of|component to|portion of|component of|element of} content. I {simply|just} stumbled upon your {blog|weblog|website|web site|site} and in accession capital {to claim|to say|to assert} that I {acquire|get} {in fact|actually} {enjoyed|loved} account your {blog|weblog} posts. {Any way|Anyway} {I'll|I will} be subscribing {for your|on your|in your|to your} {augment|feeds} {or even|and even} I {fulfillment|achievement|success} you {get entry to|access|get right of entry to|get admission to} {consistently|persistently|constantly} {rapidly|fast|quickly}.
My brother {suggested|recommended} I {would possibly|might|may} like this {blog|website|web site}. He {used to be|was|was once} {totally|entirely} right. This {post|submit|publish|put up} {actually|truly} made my day. You {cann't|can not} {believe|consider|imagine} {just|simply} how {so much|much|a lot} time I had spent for this {information|info}! {Thank you|Thanks}!
I {don't|do not} even {know the way|understand how|know how} {I stopped|I ended|I finished} up {here|right here}, {however|but} {I thought|I assumed|I believed} this {post|submit|publish|put up} {used to be|was|was once} {good|great}. I {don't|do not} {realize|recognize|understand|recognise|know} who {you are|you're|you might be} {however|but} {definitely|certainly} {you are|you're} going to a {famous|well-known} blogger {if you|should you|when you|in the event you|in case you|for those who|if you happen to} {are not|aren't} already. Cheers!
Heya {i'm|i am} for {the primary|the first} time here. I {came across|found} this board and I {in finding|find|to find} It {truly|really} {useful|helpful} & it helped me out {a lot|much}. {I am hoping|I hope|I'm hoping} {to give|to offer|to provide|to present} {something|one thing} {back|again} and {help|aid} others {like you|such as you} {helped|aided} me.
{I used to be|I was} {recommended|suggested} this {blog|website|web site} {through|via|by way of|by means of|by} my cousin. {I am|I'm} {now not|not|no longer} {sure|positive|certain} {whether|whether or not} this {post|submit|publish|put up} is written {through|via|by way of|by means of|by} him as {no one|nobody} else {realize|recognize|understand|recognise|know} such {specific|particular|certain|precise|unique|distinct|exact|special|specified|targeted|detailed|designated|distinctive} {approximately|about} my {problem|difficulty|trouble}. {You are|You're} {amazing|wonderful|incredible}! {Thank you|Thanks}!
{Nice|Excellent|Great} {blog|weblog} {here|right here}! {Also|Additionally} your {website|site|web site} {a lot|lots|so much|quite a bit|rather a lot|loads} up {fast|very fast}! What {host|web host} are you {the use of|using|the usage of}? Can {I am getting|I get} your {associate|affiliate} {link|hyperlink} {for your|on your|in your|to your} host? I {desire|want|wish} my {website|site|web site} loaded up as {fast|quickly} as yours lol
Wow, {amazing|wonderful|awesome|incredible|marvelous|superb|fantastic} {blog|weblog} {layout|format|structure}! How {long|lengthy} {have you|have you ever} been {blogging|running a blog} for? you {make|made} {blogging|running a blog} {glance|look} easy. {The total|The entire|The whole|The full|The overall} {glance|look} of your {site|web site|website} is {great|wonderful|fantastic|magnificent|excellent}, {let alone|as {smartly|well|neatly} as} the {content|content material}!
{I'm|I am} {now not|not|no longer} {sure|positive|certain} {where|the place} {you are|you're} getting your {info|information}, {however|but} {good|great} topic. I {needs to|must} spend {a while|some time} {studying|learning|finding out} {more|much more} or {working out|understanding|figuring out} more. {Thank you|Thanks} for {great|wonderful|fantastic|magnificent|excellent} {information|info} {I used to be|I was} {looking for|in search of|on the lookout for|searching for} this {information|info} for my mission.
You {really|actually} make it {seem|appear} {so easy|really easy} {with your|together with your|along with your} presentation {however|but} I {in finding|find|to find} this {topic|matter} to be {really|actually} {something|one thing} {which|that} {I think|I feel|I believe} {I would|I might|I'd} {never|by no means} understand. {It kind of feels|It sort of feels|It seems} too {complicated|complex} and {very|extremely} {wide|broad|extensive|large|vast|huge} for me. {I am|I'm} {taking a look|looking|having a look} {forward|ahead} {for your|on your|in your|to your} {next|subsequent} {post|submit|publish|put up}, {I will|I'll} {try to|attempt to} get the {hang|hold|grasp|cling|dangle} of it!
{I have|I've} been {surfing|browsing} {online|on-line} {more than|greater than} {three|3} hours {these days|nowadays|today|lately|as of late}, {yet|but} I {never|by no means} {found|discovered} any {interesting|fascinating|attention-grabbing} article like yours. {It's|It is} {lovely|pretty|beautiful} {worth|value|price} {enough|sufficient} for me. {In my opinion|Personally|In my view}, if all {webmasters|site owners|website owners|web owners} and bloggers made {just right|good|excellent} {content|content material} as {you did|you probably did}, the {internet|net|web} {will be|shall be|might be|will probably be|can be|will likely be} {much more|a lot more} {useful|helpful} than ever before.
I do {accept as true with|agree with|believe|consider|trust} {all the|all of the} {ideas|concepts|ideas} {you have|you've} {presented|introduced|offered} {for your|on your|in your|to your} post. {They are|They're} {very|really} convincing {and will|and can} {definitely|certainly} work. {Still|Nonetheless}, the posts are {too|very} {brief|quick|short} for {newbies|beginners|novices|starters}. {May just|May|Could} you please {extend|prolong|lengthen} them {a bit|a little} from {next|subsequent} time? {Thank you|Thanks} for the post.
You {can|could} {definitely|certainly} see your {enthusiasm|expertise|skills} {in the|within the} {paintings|work} you write. {The arena|The world|The sector} hopes for {more|even more} passionate writers {like you|such as you} who {aren't|are not} afraid {to mention|to say} how they believe. {Always|All the time|At all times} {go after|follow} your heart.
{I will|I'll} {right away|immediately} {take hold of|grab|clutch|grasp|seize|snatch} your {rss|rss feed} as I {can not|can't} {in finding|find|to find} your {email|e-mail} subscription {link|hyperlink} or {newsletter|e-newsletter} service. Do {you have|you've} any? {Please|Kindly} {allow|permit|let} me {realize|recognize|understand|recognise|know} {so that|in order that} I {may just|may|could} subscribe. Thanks.
{A person|Someone|Somebody} {necessarily|essentially} {lend a hand|help|assist} to make {seriously|critically|significantly|severely} {articles|posts} {I would|I might|I'd} state. {This is|That is} the {first|very first} time I frequented your {web page|website page} and {to this point|so far|thus far|up to now}? I {amazed|surprised} with the {research|analysis} you made to {create|make} {this actual|this particular} {post|submit|publish|put up} {incredible|amazing|extraordinary}. {Great|Wonderful|Fantastic|Magnificent|Excellent} {task|process|activity|job}!
{Great|Wonderful|Fantastic|Magnificent|Excellent} {site|web site|website}. {A lot of|Lots of|Plenty of} {useful|helpful} {information|info} here. {I'm|I am} sending it to {some|a few|several} {pals|buddies|friends} ans {also|additionally} sharing in delicious. And {of course|obviously|naturally|certainly}, {thank you|thanks} {for your|on your|in your|to your} {effort|sweat}!
{hi|hello}!,{I love|I really like|I like} your writing {so|very} {so much|much|a lot}! {percentage|proportion|share} we {keep in touch|keep up a correspondence|communicate|be in contact} {more|extra} {approximately|about} your {post|article} on AOL? I {need|require} {an expert|a specialist} {in this|on this} {space|area|house} {to solve|to unravel|to resolve} my problem. {May be|Maybe} {that is|that's} you! {Taking a look|Looking|Having a look} {forward|ahead} {to peer|to see|to look} you.
{Awesome|Tremendous|Remarkable|Amazing} {things|issues} here. {I'm|I am} very {satisfied|glad|happy} {to peer|to see|to look} your {article|post}. {Thank you|Thanks} {so much|a lot} and {I'm|I am} {taking a look|looking|having a look} {forward|ahead} to {touch|contact} you. Will you {please|kindly} drop me a {mail|e-mail}?
I {simply|just} {could not|couldn't} {leave|depart|go away} your {site|web site|website} {prior to|before} suggesting that I {really|extremely|actually} {enjoyed|loved} {the standard|the usual} {information|info} {a person|an individual} {supply|provide} {for your|on your|in your|to your} {visitors|guests}? Is {going to|gonna} be {back|again} {frequently|regularly|incessantly|steadily|ceaselessly|often|continuously} {in order to|to} {check up on|check out|inspect|investigate cross-check} new posts
{You are|You're} {in point of fact|actually|really|in reality|truly} a {just right|good|excellent} webmaster. The {site|web site|website} loading {speed|velocity|pace} is {incredible|amazing}. {It kind of feels|It sort of feels|It seems} that {you are|you're} doing any {unique|distinctive} trick. {Also|In addition|Moreover|Furthermore}, The contents are {masterpiece|masterwork}. {you have|you've} {performed|done} a {great|wonderful|fantastic|magnificent|excellent} {task|process|activity|job} {in this|on this} {topic|matter|subject}!
{Thank you|Thanks} a {bunch|lot} for sharing this with all {folks|people|of us} you {really|actually} {realize|recognize|understand|recognise|know} what {you are|you're} {talking|speaking} {approximately|about}! Bookmarked. {Please|Kindly} {also|additionally} {talk over with|discuss with|seek advice from|visit|consult with} my {site|web site|website} =). We {will have|may have|could have|can have} a {link|hyperlink} {exchange|trade|change|alternate} {agreement|contract|arrangement} {among|between} us
{Terrific|Great|Wonderful} {paintings|work}! {This is|That is} {the type of|the kind of} {information|info} {that are meant to|that are supposed to|that should} be shared {around the|across the} {web|internet|net}. {Disgrace|Shame} on {the {seek|search} engines|Google} for {now not|not|no longer} positioning this {post|submit|publish|put up} {upper|higher}! Come on over and {talk over with|discuss with|seek advice from|visit|consult with} my {site|web site|website} . {Thank you|Thanks} =)
{Helpful|Useful|Valuable} {info|information}. {Fortunate|Lucky} me {I found|I discovered} your {site|web site|website} {accidentally|by chance|by accident|unintentionally}, and {I am|I'm} {surprised|stunned|shocked} why this {twist of fate|coincidence|accident} {did not|didn't} {came about|happened|took place} {in advance|earlier}! I bookmarked it.
{I've|I have} been exploring for {a little bit|a little|a bit} for any {high-quality|high quality} articles or {blog|weblog} posts {in this|on this} {kind of|sort of} {space|area|house} . Exploring in Yahoo I {at last|eventually|finally|ultimately} stumbled upon this {site|web site|website}. {Reading|Studying} this {info|information} So {i'm|i am} {satisfied|glad|happy} to {express|show|exhibit|convey} that {I have|I've} {a very|an incredibly} {just right|good|excellent} uncanny feeling I {found out|came upon|discovered} {exactly|just} what I needed. I {so much|such a lot|most} {without a doubt|no doubt|undoubtedly|surely|certainly|for sure|definitely|unquestionably|indisputably|indubitably} will make {certain|sure} to {don?t|do not} {put out of your mind|forget|fail to remember|overlook|disregard|omit} this {site|web site|website} {and give|and provides} it {a look|a glance} {on {a constant|a continuing|a relentless} basis|regularly}.
Woah this {blog|weblog} is {great|wonderful|fantastic|magnificent|excellent} {i love|i really like|i like} {reading|studying} your {articles|posts}. {Stay|Keep} up the {good|great} {paintings|work}! {You know|You understand|You realize|You recognize|You already know}, {many|a lot of|lots of} {people are|individuals are|persons are} {hunting|searching|looking} {around|round} for this {info|information}, {you can|you could} {help|aid} them greatly.
I {enjoy|take pleasure in|get pleasure from|appreciate|delight in|have fun with|savor|relish|savour}, {lead to|cause|result in} {I found|I discovered} {exactly|just} what {I used to be|I was} {taking a look|looking|having a look} for. {You have|You've} ended my {4|four} day {long|lengthy} hunt! God Bless you man. Have a {nice|great} day. Bye
{Thank you|Thanks} for {any other|another|some other|every other} {great|wonderful|fantastic|magnificent|excellent} {article|post}. {Where|The place} else {may just|may|could} {anyone|anybody} get that {kind of|type of} {information|info} in such {a perfect|an ideal} {way|method|means|approach|manner} of writing? {I have|I've} a presentation {next|subsequent} week, and {I am|I'm} {at the|on the} {look for|search for} such {information|info}.
It's {really|actually} a {nice|cool|great} and {helpful|useful} piece of {information|info}. {I'm|I am} {satisfied|glad|happy} {that you|that you simply|that you just} shared this {helpful|useful} {info|information} with us. Please {stay|keep} us {informed|up to date} like this. {Thank you|Thanks} for sharing.
{Great|Wonderful|Fantastic|Magnificent|Excellent} {post|submit|publish|put up}, very informative. {I wonder|I'm wondering|I ponder} why {the other|the opposite} {experts|specialists} of this sector {do not|don't} {realize|understand|notice} this. You {should|must} {continue|proceed} your writing. {I am|I'm} {sure|confident}, {you have|you've} {a huge|a great} readers' base already!|What's {Taking place|Happening|Going down} {i'm|i am} new to this, I stumbled upon this {I have|I've} {found|discovered} It {positively|absolutely} {helpful|useful} and it has {helped|aided} me out loads. {I am hoping|I hope|I'm hoping} to {give a contribution|contribute} & {assist|aid|help} {other|different} {users|customers} like its {helped|aided} me. {Good|Great} job.
{Thank you|Thanks }, {I have|I've} {recently|just} been {searching for|looking for} {information|info} {approximately|about} this {topic|subject} for {a while|ages|a long time} and yours is the {best|greatest} {I have|I've} {found out|came upon|discovered} {so far|till now}. {However|But}, what {about the|concerning the|in regards to the} {conclusion|bottom line}? Are you {sure|positive|certain} {about the|concerning the|in regards to the} {source|supply}?|What i {do not|don't} {realize|understood} is {if truth be told|in fact|actually|in reality|in truth} how {you're|you are} {now not|not|no longer} {really|actually} {a lot more|much more} {smartly|well|neatly}-{liked|appreciated|favored|preferred} than you {may be|might be} {right now|now}. {You are|You're} {so|very} intelligent.
{You know|You understand|You realize|You recognize|You already know} {therefore|thus} {significantly|considerably} {when it comes to|in terms of|in relation to|with regards to|relating to|on the subject of|in the case of} this {topic|matter|subject}, {produced|made} me {for my part|personally|individually|in my opinion|in my view} {believe|consider|imagine} it from {so many|numerous|a lot of} {various|numerous|varied} angles. Its like {men and women|women and men} {don't seem to be|aren't|are not} {interested|fascinated|involved} {unless|until|except} {it's|it is} {something|one thing} to {accomplish|do} with {Woman|Lady|Girl} gaga! {Your own|Your personal|Your individual} stuffs {excellent|nice|great|outstanding}. {Always|All the time|At all times} {take care of|care for|deal with|maintain|handle} it up!
{Usually|Normally|Generally} I {do not|don't} {read|learn} {article|post} on blogs, {however|but} I {wish to|would like to} say that this write-up very {forced|pressured|compelled} me {to take a look at|to try|to check out} and do {so|it}! Your writing {taste|style} has been {amazed|surprised} me. {Thank you|Thanks}, {quite|very} {great|nice} {article|post}.
{Hi|Hello} my {family member|loved one|friend}! I {want to|wish to} say that this {article|post} is {awesome|amazing}, {great|nice} written and {come with|include} {almost|approximately} all {important|significant|vital} infos. {I'd|I would} like {to peer|to see|to look} {more|extra} posts like this .
{of course|obviously|naturally|certainly} like your {web-site|website|web site} {however|but} you {need to|have to} {test|check|take a look at} the spelling on {quite a few|several} of your posts. {A number|Several|Many} of them are rife with spelling {problems|issues} and I {in finding|find|to find} it very {bothersome|troublesome} {to tell|to inform} {the truth|the reality} {on the other hand|however|then again|nevertheless} {I will|I'll} {certainly|surely|definitely} come {back|again} again.
{Hi|Hello}, Neat post. {There is|There's} {a problem|an issue} {with your|together with your|along with your} {site|web site|website} in {internet|web} explorer, {may|might|could|would} {check|test} this? IE {still|nonetheless} is the {marketplace|market} {leader|chief} and {a large|a good|a big|a huge} {part of|section of|component to|portion of|component of|element of} {other folks|folks|other people|people} will {leave out|omit|miss|pass over} your {great|wonderful|fantastic|magnificent|excellent} writing {due to|because of} this problem.
{I've|I have} {read|learn} {some|several|a few} {just right|good|excellent} stuff here. {Definitely|Certainly} {worth|value|price} bookmarking for revisiting. I {wonder|surprise} how {so much|much|a lot} {attempt|effort} {you put|you set|you place} to {create|make} {this type of|this kind of|this sort of|such a|one of these|any such|the sort of} {great|wonderful|fantastic|magnificent|excellent} informative {site|web site|website}.
{Hello|Howdy|Hiya|Hey|Whats up|Good day|Hi there} very {nice|cool} {blog|website|web site|site}!! {Guy|Man} .. {Beautiful|Excellent} .. {Amazing|Superb|Wonderful} .. {I will|I'll} bookmark your {blog|website|web site|site} and take the feeds {also|additionally}?{I am|I'm} {satisfied|glad|happy} {to find|to seek out|to search out} {so many|numerous|a lot of} {useful|helpful} {information|info} {here|right here} {in the|within the} {post|submit|publish|put up}, {we need|we'd like|we want} {develop|work out} {more|extra} {strategies|techniques} {in this|on this} regard, {thank you|thanks} for sharing. . . . . .
{It's|It is} {in point of fact|actually|really|in reality|truly} a {nice|great} and {helpful|useful} piece of {information|info}. {I'm|I am} {satisfied|glad|happy} {that you|that you simply|that you just} shared this {helpful|useful} {info|information} with us. Please {stay|keep} us {informed|up to date} like this. {Thanks|Thank you} for sharing.
{Great|Wonderful|Fantastic|Magnificent|Excellent} {issues|points} altogether, you {just|simply} {won|gained|received} {a {logo|emblem|brand} new|a new} reader. What {may|might|could|would} you {suggest|recommend} {in regards to|about} your {post|submit|publish|put up} {that you|that you simply|that you just} made {a few|some} days {ago|in the past}? Any {sure|positive|certain}?
{Thank you|Thanks } for {any other|another|some other|every other} informative {blog|website|web site|site}. {Where|The place} else {may just|may|could} {I am getting|I get} that {kind of|type of} {info|information} written in such {a perfect|an ideal} {way|method|means|approach|manner}? {I have|I've} a {project|venture|challenge|undertaking|mission} that {I am|I'm} {simply|just} now {running|operating|working} on, and {I have|I've} been {at the|on the} {glance|look} out for such {information|info}.
{Hi|Hello} there, {I found|I discovered} your {blog|website|web site|site} {by means of|via|by the use of|by way of} Google {at the same time as|whilst|even as|while} {searching for|looking for} a {similar|comparable|related} {topic|matter|subject}, your {site|web site|website} {got here|came} up, it {looks|appears|seems|seems to be|appears to be like} {good|great}. {I have|I've} {bookmarked|added} to {|my }favourites|added to {|my }bookmarks.

Je n’ai rien changé, c’était tel quel. On arrive aisément à lire le modèle qui permet de générer un certain nombre de message plus ou moins identiques.

C’est à croire que les mecs ne sont même pas foutu de coder pour spammer correctement et tester avant d’envoyer la sauce. La qualité se perd, je vous le dis !

Incompétence ou payé au lance-pierre ? Je ne saurais dire, mais ça me rappelle que les choses sont similaires avec les codes malicieux : beaucoup semblent codés à l’arrache, sans tests, ce qui au passage le rend particulièrement visible (système instable, crash, lenteur, etc…).
Le spam par mail également semble alimenté par des crétins, qui arrosent (ou au moins essaie) mon système, et qui retentent encore sans comprendre que leur put*@§ de pourriels ne passera jamais.

On doit voir passer de drôle de choses sur les honeypots.

Sinon, au spammeurs, vous pouvez toujours tenter, ça ne marchera jamais sans cerveau ! Pas chez moi en tout cas.

Youtube à plein tube

C’est pas une nouveauté, Youtube + Free = caca lorsqu’on a l’IPv6 d’activé. Voici une démarche permettant de contourner ce problème aisément.
Le tutoriel ne fonctionnera que sous Windows Vista ou Windows 7, mais l’idée peut être adaptée partout. Elle consiste simplement à filtrer les IPv6 utilisées par Youtube.

Voici donc la procédure :

  1. Accédez au pare-feu, via par exemple le bouton Démarrer > wf.msc (il faut évidemment être administrateur de sa machine)
  2. Ajoutez une règle de trafic sortant avec les paramètres suivants (voir plus bas pour la version en images) :
    • Type de règle: personnalisé
    • Appliqué à tous les programmes
    • Le protocole TCP sur le port distant 80
    • Lorsque les IP distantes sont dans la rangée : 2a00:1450::/32 ou 2607:f8b0::/32
    • Bloquer la connexion
    • sur tous les emplacements (Domaine, Privé et Public)
    • avec le nom suivant : Youtube IPv6
    • C’est tout. Il n’y a plus qu’à rafraîchir la page du navigateur

Les IPs s’obtiennent avec n’importe quel analyseur réseau comme Wireshark, Firebug ou les Outils de développements intégrés à Chrome. Ensuite, l’utilisation du bon RIR (Ripe pour les IPs européennes, ARIN pour le continent américain, APNIC pour l’Asie et le Pacifique) permet d’obtenir le bloc contenant l’IP cherchées qui a été affecté. On vérifiera que le propriétaire des 2 blocs est bien Google, propriétaire de Youtube.

En images :

youtube_templateyoutube_programyoutube_portyoutube_hostyoutube_actionyoutube_profilyoutube_name

SQL Server : une contrainte conditionnelle

Mon besoin d’une contrainte conditionnelle s’était exprimé sur une contrainte de type UNIQUE, que je voulais restreindre à certaines lignes, c’est à dire les lignes pour lesquelles une condition du type MaColonne = X est satisfaite. Ce billet montre 2 manières différente de les créer.

Prenons l’exemple suivant :

CREATE TABLE Moron (
	Id INT NOT NULL,
	Name NVARCHAR(25),
	IsDeleted BIT NOT NULL,
	CONSTRAINT UQ_Moron_Name UNIQUE(Name)
)

On définit cette table comme étant les abrutis présents dans une classe.
On sait qu’il ne peut pas y avoir 2 abrutis avec le même nom dans une classe, on tape donc dans le marbre la contrainte UQ_Moron_Name  pour que cette valeur de vérité soit toujours vérifiée.

Supposons maintenant qu’un abruti Aurélien s’en aille, on va le marquer IsDeleted = 1 .
Supposons ensuite, qu’un autre abruti arrive en classe et qu’il s’appelle aussi Aurélien. Boum, on ne peut pas l’insérer dans la table à cause de la contrainte d’intégrité.
L’idéal serait donc de modifier cette contrainte (ça serait vraiment dommage de la supprimer, non ?), et ainsi prendre en compte cette nouvelle réalité, à savoir que ce qui nous intéresse est : il ne peut pas y avoir 2 abrutis avec le même nom dans une classe, c’est à dire que c’est la contrainte précédente mais uniquement lorsque IsDeleted = 0 .

Et donc ?

Il faut trouver le moyen de réaliser une contrainte conditionnelle, et deux moyens au moins s’offrent à nous :

La vue

On peut créer une vue telle que définie:

CREATE View ActiveMoron
AS
	SELECT Name
	FROM Moron
	WHERE IsDeleted = 0
GO
CREATE UNIQUE CLUSTERED INDEX IDX_Active_Moron ON ActiveMoron(Name)

On raffine ainsi la table aux colonnes essentielles à la condition (avec le SELECT ), et aux lignes sur lesquelles on doit l’appliquer (avec le WHERE ).
Il n’y a plus qu’à poser la contrainte, ici via un index UNIQUE .

L’index conditionnel

Disponible à partir de SQL Server 2008, il est possible de poser des index contenant une condition. Ainsi

CREATE UNIQUE INDEX IDX_Active_Moron ON ActiveMoron(Name) WHERE IsDeleted = 0

est complètement équivalent à la solution précédente, du point de vue de la contrainte, mais la vue en moins.

Source

Utiliser ruby (on rails) avec nginx

Ruby on Rails, ce n’est vraiment pas la panacée du point du déploiement, et je dirais même que c’est une technologie chiante avec tous ses modules et bugs obscurs dû à des dépendances pourries, mais lorsqu’on désire utiliser l’excellent gestionnaire de projet redmine, il faut bien mettre les mains dans le cambouis.

Jusqu’à présent, je faisais tourner redmine en utilisant mongrel, donc avec une passerelle fastcgi pour le faire communiquer avec nginx.
C’est une solution complètement naze, j’en conviens, car de cette manière, une seule requête pouvait être traitée à la fois, mais au moins c’était fonctionnel.
J’ai pu tricher en détournant les requêtes vers les ressources statiques vers nginx de la manière suivante :

server {
	listen 443;
	listen [mon_ipv6]:443 ssl ipv6only=on;
	server_name redmine.mondomaine.com;

	access_log /var/log/nginx/redmine.access_log main;
	error_log /var/log/nginx/redmine.error_log notice;

	root /var/www/redmine/htdocs/public;

	location ~* (^$|/$|^/(projects|attachments)|^[^\.]+$) {
		proxy_pass http://127.0.0.1:1091;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X_FORWARDED_PROTO 'https';
		proxy_redirect http://redmine.mondomaine.com https://$host;
	}
}

Mais ce genre de rustine atteint très rapidement ses limites dès lors que plusieurs personnes utilisent le site en même temps.

Depuis que redmine est passé en version 1.4.x, j’ai mis à jour les modules demandés selon les prérequis, et là ça marche… si on veut :

  • consommation de mon quad-core de manière très variable mais plus souvent vers le 80% que vers le 0%, même lorsqu’il n’y a personne
  • warning en folie sur des instructions dépréciées

C’est une situation qui n’est pas tenable très longtemps, mon instance teamspeak sur le même serveur pourra confirmer, ça laggait grave.

Comment remédier à ces 3 problèmes que je rappelle :

  • consommation CPU délirante
  • warnings
  • mono-tache (1 requête à la fois)

J’ai tenté la solution phusion passenger, qui consiste à compiler un module passenger à Nginx. Nginx n’étant pas modulaire, compiler un module pour Nginx revient à recompiler Nginx.

Solution 1

J’ai installé la dernière version stable disponible dans portage, la version =www-apache/passenger-3.0.7 , puis utilisé la commande passenger-install-nginx-module . J’ai tenté, j’ai eu une erreur, je n’ai pas cherché très longtemps car cette solution ne me plaît pas : la commande va recompiler nginx, avec les modules par défaut et le module passenger, donc exit les USE que j’avais utilisés sur nginx.

Solution 2

J’ai utilisé passenger –start . A la première exécution, il va compiler une version de nginx avec passenger et l’installer quelque part dans /var/lib.

Cette solution est mieux au niveau architecture car on se retrouve avec deux instances nginx :

  • l’instance d’origine, qui était là avant passenger, celle que j’ai compilé et configuré reste et prend le rôle de frontend
  • passenger se lance dans une seconde instance d’une autre compilation de nginx (celle incluant le module passenger, ici ce nginx n’est qu’une coquille pour passenger). Elle a le rôle de backend et héberge donc l’application ruby. Elle communique avec le frontend par fastcgi.

Ca n’a pas marché, passenger n’étant pas fichu de compiler correctement la dépendance libev.

Solution 3

Mettons donc à jour passenger avec gem en version 3.0.13 (gem install passenger -v 3.0.13 ), non encore stable sur ma distribution au moment où je rédige ce billet. En retestant la solution 2, ça marche 🙂
Mais j’ai toujours une consommation CPU délirante.

Solution 4 (c’est la bonne)

OK, la solution 3 fonctionne, mais avoir 2 nginx, c’est un peu naze. N’y-a-t-il pas moyen de compiler « manuellement » nginx ? Ainsi j’aurais passenger directement intégré à mon nginx principal.
En lisant la doc un peu plus loin, c’est effectivement possible.
Et bah c’est partie, je copie l’ebuild nginx dans mon overlay, et zou on intègre passenger.
Ça compile, très bon signe ; on notera que des fichiers supplémentaires ont été générés durant la compilation pour phusion passenger : l’agent Nginx.

J’ajoute la configuration suivante dans nginx :

http {
	# path obtenu avec passenger-config --root
	passenger_root /usr/local/lib64/ruby/gems/1.8/gems/passenger-3.0.13;
	passenger_max_pool_size 10;
}

server {
	listen 443;
	listen [mon_ipv6]:443 ssl ipv6only=on;
	server_name redmine.mondomaine.com;

	access_log /var/log/nginx/redmine.access_log main;
	error_log /var/log/nginx/redmine.error_log notice;

	root /var/www/redmine/htdocs/public;
	passenger_enabled on;
	passenger_use_global_queue on;
	passenger_user mongrel_redmine;
}

Et là c’est jackpot, tous les problèmes ont été résolus, que ça soit les vieux pics cpu ou les warnings, c’est maintenant de l’histoire ancienne (jusqu’à la prochaine grosse update de redmine…), et j’ai gagné en rapidité dans un environnement multi-utilisateurs vu que j’ai désormais un pool et non plus un seul processus pour gérer les requêtes vers l’application redmine (qui repose sur le framework ruby on rails). Le changement se ressent immédiatement.

Je n’ai pas trop cherché à comprendre pourquoi, mais j’ai obtenu une conf parfaitement fonctionnelle, donc ON NE TOUCHE PLUS.

Pour les intéressés sous Gentoo, j’ai un overlay contenant un ebuild permettant de compiler nginx avec passenger. Il faut juste ajouter ça dans layman pour synchroniser l’overlay : https://raw.github.com/LordVeovis/gentoo/master/repositories.xml.

Je suppose, sans l’avoir testé, que cet ebuild est capable de fonctionner avec une version plus ancienne de passenger, comme celle marquée comme stable dans portage, mais je ne testerais pas, tant que ça ne bug pas.

Voir aussi

SQL Server ne démarre plus avec SSL activé

SQL Server supporte, au moins depuis la version 2005, les connexions sécurisés en utilisant SSL.
En suivant la procédure décrite par Microsoft, ça se fait relativement bien… mais les règles semblent avoir changées avec la version 2008 R2.

En effet, à partir de cette version, une étape supplémentaire est requise afin d’autoriser et de s’assurer que l’utilisateur qui exécute le service puisse accéder à la clé privée associée au certificat. Dans le cas contraire, SQL Server balance plusieurs erreurs abscons dont la première a pour EventID 26014 avec pour seules explications que le certificat spécifié n’existe pas et pourtant, il est bien là !

Revoyons les étapes nécessaires pour activer SSL sur une instance SQL Server :

  1. Installer le certificat de sécurité sur la machine qui exécute SQL Server en utilisant la MMC gérant les certificats. Le certificat DEVRA bien entendu être au format PFX pour qu’il puisse être importé dans un magasin de certificats géré par Windows.
    • il est important de noter que le certificat DOIT ÊTRE accessible par l’utilisateur qui exécute SQL Server, donc on ne peut pas utiliser par exemple le magasin de certificat du compte administrateur (à moins que ce soit lui qui exécute SQL Server, auquel cas c’est complètement débile d’un point de vue sécurité). Le certificat peut donc être installé ou bien dans le magasin de la machine locale, ou bien dans le magasin du compte utilisateur. J’ai testé avec le magasin de la machine locale, mais ça devrait aussi fonctionner avec le magasin du compte utilisateur SQL Server. A noter que sous Windows Server 2003, je recommande l’utilisation du magasin de la machine locale pour faciliter la manipulation à l’étape suivante.
    • c’est là que les choses changent : il faut vérifier que l’utilisateur SQL Server peut lire la clé privée, ce qui ne semble plus être le cas par défaut. Pour se faire, ou bien on dispose de Windows Server 2008 R2 et cela se fait directement dans la MMC, ou bien on tourne encore sous Windows Server 2003 et il faut faire appel à un outil nommé winhttpcrtcfg disponible dans le Ressource Kit de Windows Server 2003. La commande à taper ressemblera à winhttpcrtcfg -g -c LOCAL_MACHINE\My -s « le.sujet.du.certificat.kveer.com » -a utilisateur_sql_server et on pourra le vérifier avec la commande winhttpcrtcfg -l -c LOCAL_MACHINE\MY -s « le.sujet.du.certificat.kveer.com »
  2. Reconfigurer SQL Server grâce au SQL Server Configuration Manager
    • je ne détaillerai pas cette étape car elle n’a pas changé, et consiste en une dizaine de clics dans le SQL Server Configuration Manager. Se référer aux liens dans la section Source pour la procédure étape par étape.

Voir aussi

Backup par mail

Le pipe (|), opérateur exclusivement Unix, et trop rarement utilisé (tout du moins par moi), m’a permis de réaliser en une seule ligne, une sauvegarde de base de données, compressée, et envoyé par mail.

Voyons la commande finale :

mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | uuencode bdd_mabase_prod_`date +%Y%m%d-%H%M%S`.sql.bz2 | mail -s "Backup BDD" storage_mail@gmail.com

Détaillons cette chaîne :

  1. on dump la ou les bases de données, pour se faire, je conseille fortement l’utilisation d’un utilisateur dédié qui n’aura qu’un accès limité à la lecture et éventuellement à l’utilisation des verrous pour assurer l’intégrité de la sauvegarde
  2. le flux de sortie, un script SQL, est envoyé à bzip pour être compressé
  3. le flux compressé est envoyé à uuencode. Cette opération va encoder avec des caractères ASCII afin d’être pouvoir transmis en pièce jointe et en lui donnant un nom
  4. enfin on expédie le mail avec un sujet et un destinataire

Et si on chiffrait la sauvegarde ?

Il y a plusieurs intérêt à chiffrer la sauvegarde :

  • la sauvegarde peut être placé dans un endroit non sécurisé ou faiblement
  • toute altération sur la sauvegarde sera impossible ou visible

Encore faut-il s’y prendre convenablement. En effet, on a immédiatement 2 façons naïves de chiffrer :

  • soit en utilisant un chiffrage symétrique
  • soit en utilisant un chiffrage asymétrique

Il se trouve que ces deux approches sont après coup débiles. En effet prenons d’abord le chiffrage symétrique ; que se passe-t-il si le serveur qu’on sauvegarde est compromis ? On peut estimer que le contenu des sauvegardes, y compris celles faites AVANT le piratage du serveur ne sont plus sûres, puisque le serveur compromis a non seulement un accès en écriture au site de sauvegarde, mais également la clé de déchiffrage des sauvegardes.

Examinons maintenant le chiffrage asymétrique, qui corrige bien le problème précédent mais présente deux problèmes :

  • le premier est un problème purement pratique : openssl, le couteau suisse du chiffrage pète en rsa lorsque le flux dépasse une certaine taille (très inférieure à 1Mo)
  • le second est d’ordre plus général : les chiffrages asymétriques coûtent très cher en temps processeur (autrement dit un chiffrage asymétrique prendre beaucoup plus de temps qu’un chiffrage symétrique sur le même flux), pour peu que la quantité de données soit « assez » conséquente, le chiffrage pourrait dégrader de façon significative et pendant un temps estimé trop long le serveur sur lequel les calculs s’effectuent.

La méthode que je qualifierais de bonne, (merci à Denis Altudov pour l’astuce), consiste à utiliser se qui se fait déjà dans les mails avec S/MIME : le contenu à protéger est chiffré avec un algorithme symétrique, dont la clé, générée à la demande et donc unique, est chiffrée par un algorithme asymétrique en utilisant la clé privée du destinataire ; ainsi seul le destinataire du mail est capable de lire le contenu protégé.

C’est exactement ce qu’on va faire, en utilisant openssl, et plus spécifiquement la sous-commande smime de openssl.
Il faudra au préalable un certificat (avec sa clé privée), au format PEM pour simplifier l’exemple. Reprenons l’exemple initial en ajoutant du chiffrage :

mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -outform DER yourPrivateKey.crt | uuencode bdd_mabase_prod_`date +%Y%m%d-%H%M%S`.sql.bz2.ssl | mail -s "Backup BDD" storage_mail@gmail.com

# version openssl smime autonome (ou presque)
mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -from sender@kveer.com -to storage_mail@gmail.com -subject "Bacup BDD" yourPrivateKey.crt | sendmail storage_mail@gmail.com

Note : openssl smime est capable de générer un mail lui-même comme on peut le voir dans la seconde commande, mais cela aurait donné un mail avec une pièce jointe nommée smime.p7m, ce qui n’est pas terrible pour identifier ce qui était chiffré, en particulier le type de fichier, c’est pourquoi j’ai préféré rester à utiliser uuencode.

Et voilà, plus besoin d’un script dédié pour des plans de sauvegarde simple, il n’y a plus qu’à cronifier.

Déchiffrage

Par rapport à l’exemple donné, voici la commande miroir pour déchiffrer les pièces jointes :

openssl smime -decrypt -binary -aes128 -inform DER yourPrivateKey.crt -in your_encrypted_file.sql.bz2.ssl -out your_decrypted_file.sql.bz2

Les arguments -aes128  et -binary  sont peut-être superflus, je n’ai pas testé précisément ces points là.

Plusieurs pièces jointes dans un mail

Toujours avec le même exemple, voici comment on peut joindre plusieurs pièces jointes, et même un corps de message à son mail :

(
echo -e $YOUR_MESSAGE;
mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B my_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -outform DER yourPrivateKey.crt | uuencode bdd_mabase_prod_`date +%Y%m%d-%H%M%S`.sql.bz2.ssl;
mysqldump --hex-blob --opt -pyourVerySecretPassword -u backup -B another_database | bzip2 -9 | openssl smime -encrypt -binary -aes128 -outform DER yourPrivateKey.crt | uuencode bdd_another_base_prod_`date +%Y%m%d-%H%M%S`.sql.bz2.ssl
)
| mail -s "Backup BDD" storage_mail@gmail.com

Où sauvegarder

Où vous le souhaitez. Pour ma part, j’ai choisi Google, car il propose 8Go par boîte mail gratuitement et accepte des pièces jointes allant jusqu’à 25Mo et parce que je suis pauvre. Pour une sauvegarde à pas chère, les mails via Google constituent une excellente opportunité.

Les paquets à installer

  • uuencode se trouve dans le paquet app-arch/sharutils
  • mail se trouve dans le paquet mail-client/mailx

Exemple de script

A peu de chose près, voici ce que j’utilise comme script de sauvegarde. Ce script se trouve dans @@/etc/cron.daily@@, ce qui lui permet d’être automatiquement exécuté avec les bons privilèges tous les jours.

#!/bin/bash
MYSQL_PASS=verySecretPassword
MYSQL_USER=backup_user
DATE=`date +%Y%m%d-%H%M%S`
HOSTNAME=`hostname`
RECIPIENT=backup@gmail.com
CERT=/root/backup.gmail.com.crt
WWW_WEB1='/var/www/web1/htdocs/ /var/www/web1/reset_acl.sh'
WWW_WEB2=/var/www/web2/htdocs
WWW_WEB3='/var/www/web3/forum /var/www/web3/www'

MYSQL_CMD="mysqldump --hex-blob --opt -u ${MYSQL_USER} -p${MYSQL_PASS} -B"
OPENSSL_CMD="openssl smime -encrypt -binary -aes128 -outform DER $CERT"

CONF='/etc/bash/bashrc
/etc/ahbot.conf
/etc/bind
/etc/clam*.conf
/etc/conf.d
/etc/courier*
/etc/cron*
/etc/dhcp
/etc/env.d
/etc/fail2ban
/etc/freshclam.conf
/etc/group
/etc/passwd
/etc/shadow
/etc/hosts
/etc/init.d
/etc/ipsec*
/etc/kernels
/etc/layman
/etc/locale.gen
/etc/make.conf
/etc/munin
/etc/mysql
/etc/nginx
/etc/ntp.conf
/etc/opendkim
/etc/openvpn
/etc/pam.d
/etc/php
/etc/postfix
/etc/pureftpd.*
/etc/realmd.conf
/etc/revdep-rebuild
/etc/screenrc
/etc/scriptdev2.conf
/etc/security
/etc/selinux
/etc/sysctl.conf
/etc/syslog-ng
/etc/teamspeak3-server
/etc/unrealircd'

T=$( cat <<EOF
Type your texte here\n
with \n if you want your mail to be readable.
EOF
)

( echo -e $T;
uuencode $CERT my_cert.crt;
$MYSQL_CMD base1 | bzip2 -9 | $OPENSSL_CMD | uuencode ${HOSTNAME}_bdd_base1_${DATE}.sql.bz2.ssl;
$MYSQL_CMD base2 | bzip2 -9 | $OPENSSL_CMD | uuencode ${HOSTNAME}_bdd_base2_${DATE}.sql.bz2.ssl;
$MYSQL_CMD base3 | bzip2 -9 | $OPENSSL_CMD | uuencode ${HOSTNAME}_bdd_base3_${DATE}.sql.bz2.ssl;
tar cj ${WWW_WEB1} | $OPENSSL_CMD | uuencode ${HOSTNAME}_www_web1_${DATE}.tar.bz2.ssl;
tar cj ${WWW_WEB2} | $OPENSSL_CMD | uuencode ${HOSTNAME}_www_web2_${DATE}.tar.bz2.ssl;
tar cj ${WWW_WEB3} | $OPENSSL_CMD | uuencode ${HOSTNAME}_www_web3_${DATE}.tar.bz2.ssl;
tar cj ${CONF} | $OPENSSL_CMD | uuencode ${HOSTNAME}_etc_${DATE}.tar.bz2.ssl
) | mail -s "Backup $HOSTNAME bdd $DATE" $RECIPIENT

Voir aussi

SElinux et cron utilisateurs

Depuis que je suis passé à SELinux sur une Gentoo, beaucoup de problèmes sont apparus. Afin d’avoir un système un minimum utilisable, j’ai passé SELinux en mode permissive, malgré tout, cela ne résout pas tout, notamment des crons utilisateurs qui ne se lancent plus.

Précisons tout d’abord que mon système de cron est vixie-cron, qui semble être le daemon préféré sous Gentoo.

J’ai eu très peu d’informations au début lorsque j’ai voulu trouver pourquoi les crons ne se lançaient plus, que ce soit dans /var/log/kern.log où se trouve les logs de SELinux, ou dans /var/log/syslog. Je savais que ça provenait de SELinux puisque côté ACL, tout était nickel, et puis ça marchait très bien avant. La seule trace concrète du problème apparaît lorsqu’on redémarre le daemon vixie ; on peut lire ceci dans les logs :

root@stormrage:[~]
# zgrep ENTRYPOINT /var/log/syslog-20120318.gz
Mar 17 20:42:01 stormrage cron[2943]: (munin) ENTRYPOINT FAILED (crontabs/munin)
Mar 17 20:42:01 stormrage cron[2943]: (anakin) ENTRYPOINT FAILED (crontabs/anakin)

 

Voyons les permissions SELinux sur les user-crons :

root@stormrage:[~]
# ls -lZ /var/spool/cron/crontabs/
total 12
-rw-------. 1 anakin crontab anakin:object_r:user_cron_spool_t 274 6 nov. 13:54 anakin
-rw-------. 1 munin crontab munin:object_r:user_cron_spool_t 1180 9 janv. 17:31 munin
-rw-------. 1 root crontab root:object_r:user_cron_spool_t 657 17 mars 20:41 root

 

Je suis encore relativement novice à SELinux, mais il est clair que munin et anakin ne sont pas relié explicitement à un utilisateur SELinux, du moins il faut que ce soit une action volontaire. Ainsi, en obtenant la liste des contextes valides pour l’utilisateur Linux munin depuis le contexte dans lequel le daemon s’exécute (voir la commande ci-dessous), on a un seul résultat, qui ne correspond pas au contexte actuel sur les user crontabs.

root@stormrage:[~]
# ps -AfZ | grep cron
system_u:system_r:crond_t root 2521 1 0 Mar17 ? 00:00:00 /usr/sbin/cron
root@stormrage:[~]
# getseuser munin system_u:system_r:crond_t
seuser: user_u, level (null)
Context 0 user_u:user_r:cronjob_t

D’où un chcon -u user_u  sur tous les user crontabs et le tour est joué.

root@stormrage:[~]
# ls -lZ /var/spool/cron/crontabs/
total 12
-rw-------. 1 anakin crontab user_u:object_r:user_cron_spool_t 274 6 nov. 13:54 anakin
-rw-------. 1 munin crontab user_u:object_r:user_cron_spool_t 1180 9 janv. 17:31 munin
-rw-------. 1 root crontab root:object_r:user_cron_spool_t 657 17 mars 20:41 root

Je ne sais pas si user_u est le bon utilisateur SELinux à appliquer, en terme de sécurité, mais au moins les crons se lancent à nouveau.

On notera cependant que restaurer les contextes par défaut avec restorecon ou rlpkg ré-appliquent des contextes invalides. De même, éditer depuis root les crontabs d’autres utilisateur avec un crontab -e  applique un mauvais contexte, il semble préférable de passer par un su/sudo au préalable.
Il faudra donc penser à vérifier spécifiquement les contextes sur ces fichiers à chaque fois que le système de fichier est relabelisé.

Au final, je reste persuadé que SELinux est une bonne technologie mais elle n’est pas prêt à l’emploi (cela vaut également pour Red Hat), même en partant avec une stratégie de base comme celle fournie par Tresys. A moins de faire un serveur très bâteau, il sera certain qu’il faudra auditer et réajuster la stratégie SELinux avant de la valider pour une production.

Voir aussi