Un Electron Libre...

Aller au contenu | Aller au menu | Aller à la recherche

samedi 11 octobre 2008

Suite de "Apache : authentification intégrée sauf pour certains clients dont on ne connait pas la provenance réseau"

Dans le billet Apache : authentification intégrée sauf pour certains clients dont on ne connait pas la provenance réseau, je pensais arriver au résultat de ne pouvoir déclarer que les IP des filiales en SSO pour que le reste du monde puisse se connecter en anonyme. Grave erreur et elle était même inscite dès le départ dans ma configuration.

Cette méthode, même si elle a le mérite de montrer comme utiliser mod_setenvif, ne répond pas à mon besoin dans la mesure où elle me force en fait à déclarer tout le monde. Déclarer le réseau de chaque filiale dans un groupe qui est présent dans 54 pays et ensuite maintenir ces déclarations à chaque évolution du réseau est clairement rédibitoire pour l'exploitabilité de la solution.

La solution, certes moins élégante, mais qui marche a été de mettre en place deux virtual hosts au niveau d'apache qui consulte la même instance eZ Publish. Le premier sur le port 80 n'est paramétré que pour accéder avec une authentification SSO et le second en anonyme. Pour faire la répartition des filiales suivant si elles doivent attaquer une instance SSO ou anonyme se fait au niveau des routeurs internes vu que des règles similaires étaient déjà en place pour une autre application.

Dès lors, l'exploitabilité est simplifiée et en plus centralisée au niveau des routeurs. Cela évitera/limitera des oublis à l'avenir...

Pour revenir à ce que je voulais faire dans Apache, je pense que cela n'est pas possible à peu de choses près en l'état actuel. Peut être que l'évolution de la directive Require et de mod_authz_host dans Apache 2.3 aurait pu me fournir ce qu'il me manquait pour tout gérer au niveau d'apache et n'avoir qu'un seul virtual host en place.

mardi 16 septembre 2008

Mercurial 1.0.x - supprimer les hgweb.cgi ou hgwebdir.cgi des urls

Petite astuce du jour pour mercurial si votre dépôt mercurial que vous mettez à disposition via http propose des urls contenant des hgweb.cgi ou hgwebdir.cgi, il vous suffit d'ajout dans votre fichier de configuration hgweb.conf (si vous partez de ce tutoriel.

Dans la section web, il vous faut rajouter le paramètre baseurl :

[web]
style = gitweb
baseurl =

Plus d'info sur le paramètre base url dans la documentation mercurial intitulée Publishing repositories

Et voilà, je passe donc d'url de type http://hg.mondomaine.com/hgwebidr.cgi/monprojet à http://hg.mondomaine.com/monprojet.

Optimisation apache (mod_deflate, mod_expires, ETag)

Pour un projet interne JCDecaux, je me suis penché sur les optimisations du serveur afin d'améliorer ses performances.

Ci-après les résultats fournis par YSlow :

Pour le chargement de la page d'accueil, en version non optimisée :

  • Sans cache (Empty cache) :
    • Taille 223.7K
    • Requêtes HTTP : 48
  • Avec cache navigateur (Primed cache) :
    • Taille : 53.5K
    • Requêtes HTTP : 48

Pour le chargement de la page d'accueil, en version optimisée :

  • Sans cache (Empty cache) :
    • Taille 160K
    • Requêtes HTTP : 48
  • Avec cache navigateur (Primed cache) :
    • Taille : 7K
    • Requêtes HTTP : 8

Sur une RHEL 5.1, dotée de Apache 2.2, PHP 5.2.6 + APC, MySQL 5.0.x, cela donne les éléments suivants :

/etc/httpd/conf.d/mod_deflate.conf :

#
## Mod Deflate - http://httpd.apache.org/docs/2.2/mod/mod_deflate.html
#

LoadModule headers_module modules/mod_headers.so
LoadModule deflate_module modules/mod_deflate.so

<IfModule mod_deflate.c>
        <Location />
                # Insert filter
                SetOutputFilter DEFLATE

                # Netscape 4.x has some problems...
                BrowserMatch ^Mozilla/4 gzip-only-text/html

                # Netscape 4.06-4.08 have some more problems
                BrowserMatch ^Mozilla/4\.0[678] no-gzip

                # MSIE masquerades as Netscape, but it is fine
                BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

                # Don't compress images
                SetEnvIfNoCase Request_URI \
                \.(?:gif|jpe?g|png)$ no-gzip dont-vary

                # Make sure proxies don't deliver the wrong content
                Header append Vary User-Agent env=!dont-vary
        </Location>
</IfModule>

/etc/httpd/conf.d/disable_etag.conf :

#
## Disable ETags as caching & co is handled by mod_expires & mod_deflate
## /!\ Gzipped items will not have the same etags (even if the content did not change).
## So they're useless in our configuration
# 

# Remote ETag from headers - http://www.askapache.com/htaccess/apache-speed-etags.html
Header unset ETag
# Disable ETag for files
FileETag None

/etc/httpd/conf.d/mod_expires.conf :

#
## Mod Expires - http://httpd.apache.org/docs/2.2/mod/mod_expires.html
#
LoadModule expires_module modules/mod_expires.so

<IfModule mod_expires.c>
        # enable expirations
        ExpiresActive On

        # Default rule
        ExpiresDefault "access plus 1 week"

        # expire images after a month in the client's cache
        ExpiresByType image/* "access plus 1 month"

        # expire video after a month in the client's cache
        ExpiresByType video/* "access plus 1 month"

        # expire audio after a month in the client's cache
        ExpiresByType audio/* "access plus 1 month"

        # expire application after a month in the client's cache
        ExpiresByType application/* "access plus 1 month"

        # HTML documents are good for a week from the time they were changed
        ExpiresByType text/html "modified plus 1 week"
        ExpiresByType text/css  "modified plus 1 week"
        ExpiresByType text/javascript "modified plus 1 week"
</IfModule>

L'arbitrage entre access et modified est à voir selon vos besoins et le choix présenté ci-dessus est largement discutable. Il doit également être possible d'aller plus loin dans les optimisations mais dans mon cas d'espèce, le mieux étant l'ennemi du bien, je préfère m'arrêter là pour le moment.

Sauf erreur, la notation de votre site dans YSlow devrait significativement s'améliorer (dans mon cas d'exemple, passage de F à C et ce sans toucher à l'applicatif).

D'autres astuces à partager ?

jeudi 21 août 2008

Apache : authentification intégrée sauf pour certains clients dont on ne connait pas la provenance réseau

Cas d'étude : une application auxquels les collaborateurs d'une entreprise accèdent via une authentification intégrée. Pour les filliales ne disposant pas du SSO ou pour permettre à des utilisateurs extérieurs de se connecter à l'application, une connexion anonyme doit être mise en place.

Solution retenue :

Principe : par défaut, le serveur va chercher à authentifier l'utilisateur par authentification intégrée.

Exception : pour l'indexation de l'application, il faut autoriser l'accès anonyme au serveur

Problématique : seuls les plages IP des pays utilisant l'authentification intégrée est connue. Il faut donc permettre l'accès en anonyme à tout le monde sauf ces IP là.

L'importance ici tient dans la directive Order, Allow , Deny, Satisfy et SetEnvIf.

LoadModule auth_ntlm_winbind_module modules/mod_auth_ntlm_winbind.so
LoadModule setenvif_module modules/mod_setenvif.so
 
<Location />
    Order Deny,Allow
    Deny From All
 
    <IfModule mod_auth_ntlm_winbind.c>
        AuthName "NTLM Authentification"
        NTLMAuth on
        NTLMAuthHelper "/usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp"
        NTLMBasicAuthoritative on
        AuthType NTLM
    </IfModule>
 
    Require valid-user
	<fModule mod_setenvif.c>
		# Declaration des clients utilisant l'authentification intégrée
		SetEnvIf Remote_Addr "10\.(10|13|14|19|20|44|45|49)\.[0-9]{1,3}\.[0-9]{1,3}" pays # Pays 1
		SetEnvIf Remote_Addr "10\.(70|18|48)\[0-9]{1,3}\.[0-9]{1,3}" pays # Pays 2
 
		# Declaration de l'IP du robot indexant le site
		SetEnvIf Remote_Addr "10\.135\.255\.(1|44|35|244)" indexation
	
		# Declaration de la machine pour generation du cache statique
		SetEnvIf Remote_Addr "(127\.0\.0\.1|10\.135\.255\.45)" local
		
		# Sont autorises en anonyme "tout le monde" sauf les pays avec authentification intégrée.
		Allow from env=local env=indexation !env=pays
	</IfModule>
	Satisfy any
</Location>

mercredi 2 juillet 2008

Backup-Manager 0.7.7 : Bug fix sur la version FC9/i386

Une petite erreur sur la définition d'un chemin...

La version FC9/x86_64 n'est pas touchée.

N'ayant plus de FC8 sous le coude, je n'ai pas regardé et j'ai donc supprimé les paquets en conséquence.

lundi 2 juin 2008

RPM FC8 & FC9 : Backup-Manager

Juste pour indiquer qu'après les PKGBUILD d'Archlinux, je me mets au RPM de Fedora Core.

Pour mon premier paquet, je me suis attaqué à Backup-Manager dont j'ai besoin pour mon serveur dédié.

Attention, il a été compilé sur une machine en x86_64 (ne fonctionnera donc pas en i386) sous FC9

La version i386 et pour FC8 devrait arriver prochainement... est arrivée :

La version i386 et pour FC9 est arrivée :

Edit du 02/06 : ajout de la version FC8/i386

Edit du 09/06 : Restauration des commentaires suite à un petit problème sur postgresql + ajout des dépendances pour FC9 :

yum install -y perl-File-Slurp perl-XML-LibXML perl-CPAN
cpan
cpan> install Net::Amazon::S3
(répondre la valeur par défaut à toutes les questions)

Edit du 14/06 : Ajout de la version FC9/i386

jeudi 15 mai 2008

Quand l'interface graphique tue et que la restauration de JungleDisk fonctionne à souhait...

J'ai voulu tester l'autre soir CentOS 5.1, qui se veut une RHEL5 gratuite (en gros, elle est reconstruite à partir des src.rpm de RHEL5 et en enlevant les logo & autres éléments spécifiques à Red Hat). Raison de ce test : mon employeur a choisit RHEL et Slackware comme distributions et donc je souhaite me familiariser un peu avec ces environnements (et puis c'était l'occasion de voir de nouvelles choses).

Bref, je récupère le DVD, lance l'installateur et passe au gré des écrans... sur le partitionnement, je suis allé un peu vite et j'avais pas vu que le RAID était activé par défaut. Du coup, mon /home que je pensais protégé sur mon second disque a mouru. Donc 80 Go de données perso parties en fumée.

Je me réinstalle une Debian de base, repartitionne le tout et me lance à l'assaut de mes données sauvegardées sur Amazon S3 via JungleDisk. La version 2.0 bêta est d'ailleurs sorti pile au bon moment puisqu'elle inclut une fonction de restauration. J'avais essayé dans un premier temps d'accéder à mes données via webdav mais dès lors qu'il y a un accent ou un espace ou je sais pas quoi, konqueror n'a pas réussi à copier des centaines de fichiers.

Avant la crise de nerfs, je replonge dans JungleDisk et découvre cette option. Bien que l'ergonomie de la fonctionnalité soit discutable, j'ai pu réstaurer mes documents perso, ma musique et mes photos à 100% (et même un peu plus, certains vieux documents effacés étaient encore sur mon espace S3).

Les pertes se résument donc aux sources des films de famille (mais j'ai encore les cassettes, faut jusque que je refasse la phase d'acquisition) et à quelques images VMWare. Il me manque aussi des films réalisés par ma soeur mais elle va pouvoir me les fournir.

Donc plus de peur que de mal au final pour un petit manque d'attention. Furieux et énervé contre moi-même et ayant de toutes façons un problème d'espace disque, je n'en ai pas moins acheté un disque dur externe raid que je devrais recevoir sous peu...

mercredi 14 mai 2008

Sécurité quand tu nous tiens...

Pensez à mettre vos serveurs / applications à jour et ce assez rapidement...

Procédure de vérification (issu d'un mail de Gandi)

Récupérer le script dowkd.pl :

$ cd /tmp
$ wget http://security.debian.org/project/extra/dowkd/dowkd.pl.gz
$ wget http://security.debian.org/project/extra/dowkd/dowkd.pl.gz.asc
$ gpg --keyserver subkeys.pgp.net --recv-keys 02D524BE
$ gpg --verify dowkd.pl.gz.asc
$ gunzip dowkd.pl.gz

L'appliquer sur des clés de machine (host key) :

$ perl dowkd.pl host localhost
# localhost SSH-2.0-OpenSSH_4.3p2 Debian-9
# localhost SSH-2.0-OpenSSH_4.3p2 Debian-9
localhost: weak key
localhost: weak key

Le message "weak key" indique que la clef est faible et donc vulnérable.

L'appliquer sur les clés des utilisateurs :

# perl dowkd.pl user
/home/someuser/.ssh/authorized_keys:1: warning: unparsable line
/home/someuser/.ssh/authorized_keys:3: warning: unparsable line
/home/someuser/.ssh/authorized_keys:4: weak key
/home/someuser/.ssh/authorized_keys:5: weak key

Pour les certificats, utiliser une procédure de révocation/regénération de certificats.

Pour le reste, voir la page SSLKey sur le wiki de Debian

Edit : Ajout du lien pour l'annonce d'OpenSSH Edit 2 : ajout du lien vers http://wiki.debian.org/SSLkeys

vendredi 9 mai 2008

Chaudron.UnElectronLibre.Info prend le soleil, il a la "mine rouge" (Trac vs Redmine inside)

Pour tout ceux qui ont un DNS à jour, mon chaudron est désormais propulsé par Redmine en lieu et place de Trac.

Je n'ai pas encore le plaisir d'avoir fait tout le tour du propriétaire de redmine, mais voici pour moi ses principales qualités et défauts :

Qualités :

  • Gestion du multi-projet au sein d'une seule instance (grosse faiblesse de Trac à ce niveau) - je peux ainsi diminuer le nombre d'instances Trac à faire tourner et maintenir...
  • Gestion des projets publics et privés (inexistant dans Trac, sauf à ne pas communiquer l'url du site...)
  • Ensemble de fonctionnalités natives (alors que pour Trac, on doit rapidement utliser des plugins pour arriver au même niveau de fonctionnalités)
  • Gestion native de nombreux gestionnaire de version (dont mercurial) alors que Trac gère nativement subversion et pour les autres, cela se fait via des plugins (s'ils existent)
  • Gestion des permissions : elles sont basées directement sur des rôles et non unitaire (je sais que l'on peut reproduire le mécanisme de groupe avec Trac)
  • Composants plus structurés et évolués : Redmine incorpore plus de composants que Trac (espace de documents, gestion des fichiers, forums, différents trackers; etc) et permet ainsi de ne plus avoir à bidouiller le wiki de trac ou mettre en place un webdav ou ... pour avoir des fonctionnalités similaires. Cela permet en outre de mieux structurer son espace projet.
  • Le process de mise à jour est très simple (merci rails pour le coup)

Défauts :

  • Déploiement d'une instance ( faut installer rails, mongrel, etc)
  • Faiblesse du nombre de plugins (compensé par les fonctionnalités nativement embarquées).
  • Ajout de ruby/rails sur mon serveur, j'aurais préférer rester en python mais bon faut savoir être pragmatique :-)

Par la même occasion et n'arrivant pas à trouver comment publier mes dépots mercurial via nginx, ceux-ci ne sont pour le moment consultables que via l'instance redmine.

jeudi 1 mai 2008

Nginx, Redmine et PostgreSQL

Cela a été testé sur une Ubuntu "Hardy 08.04" & Debian "Testing/Lenny". Les utilisateurs d'Ubuntu rajouteront un sudo aux endroits qui vont bien :-)

Pré-requis

Installons le socle de base

aptitude install nginx ruby rubygems ruby-pkg-tools ruby1.8-dev build-essential postgresql

Utilisons ensuite les gems pour installer les "paquets" ruby dont on a besoin :

gem install rails mongrel mongrel_cluster postgres-pr --include-dependencies

Dans ~/.bash_profile ou ailleurs (/etc/profile, /etc/environment, etc) tant qu'au final, ce bout de chemin soit ajouté à votre PATH.

export PATH="$PATH:/var/lib/gems/1.8/bin"

Création de la base postgresql

Nous allons d'abord changer un paramètre d'authentification de postgres en éditant le fichier @@ /etc/postgresql//8.3/main/pg_hba.conf@@ afin d'avoir la ligne suivante :

local   all         all                               md5

Redémarrez ensuite postgresql pour que votre modification soit prise en compte :

/etc/init.d/postgresql-8.3 restart

En root, devenez l'utilisateur "postgres", compte technique d'administration de postgres :

su postgres

Créer un utilisateur redmine et une base redmine

createuser redmine --no-superuser --no-createdb --no-createrole --login --pwprompt --encrypted
(pour le tutoriel, j'ai pris le mot de passe redmine)
createdb --owner=redmine --encoding=utf-8 redmine
exit

Pour tester votre compte :

psql -U redmine redmine

Installation de Redmine

Récupération de Redmine

Même si la version 0.7 de Redmine est sortie il y a quelques jours, un bug fait qu'il vaut mieux attendre la version 0.7.1...

J'utilise donc la branche 0.6-stable pour ce tutoriel et je récupère le tout par svn. A vous d'adapter selon votre besoin et votre expérience

cd /srv/rails/ 
(adapter ce chemin à l'endroit où vous voulez mettre redmine, pas besoin que ce soit dans /var/www)
svn co http://redmine.rubyforge.org/svn/branches/0.6-stable redmine-0.6

Configuration de la base de données

Créer le fichier config/database.yml...

cp config/database.yml.example config/database.yml

... avec le contenu suivant :

production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: redmine
  password: "redmine"

Remplissez la base

Au niveau du répertoire de redmine :

rake db:migrate RAILS_ENV="production"
rake redmine:load_default_data RAILS_ENV="production"

Test de bon fonctionnement

Toujours depuis le répertoire de redmine :

mongrel_rails start --environment=production

En vous rendant sur http://localhost:3000/, vous devriez voir une instance redmine tourner et pouvoir vous y connecter avec les identifiants admin/admin.

Mise en place du cluster mongrel

Note : je voulais faire tourner redmine via fastcgi mais j'ai rien trouvé à ce sujet. Tous les tutoriels sont basés sur mongrel donc je fais comme les autres...

Créer le fichier config/mongrel_cluster.yml dans le répertoire Redmine :

user: vous
cwd: /srv/rails/redmine-0.6
port: "9000"
environment: production
group: vous
address: 0.0.0.0
pid_file: log/mongrel.pid
servers: 2

et lancer le cluster :

mongrel_rails cluster::start

Vous devriez pouvoir accéder à votre instance redmine via http://localhost:9000/ et http://localhost:9001/

Faire en sorte que le cluster démarre lors du démarrage de votre pc/serveur :

mkdir /etc/mongrel_cluster
ln -s /srv/rails/redmine-0.6/config/mongrel_cluster.yml /etc/mongrel_cluster/redmine.yml
cp /var/lib/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d/
chmod +x /etc/init.d/mongrel_cluster
update-rc.d mongrel_cluster defaults

Configuration de nginx

Dernière étape, accéder à votre instance redmine sur le port 80 via nginx :

Dans /etc/nginx/sites-available/ ajouter un fichier "redmine" par ex contenant :

server {
        listen 80;
        server_name localhost;
        root /srv/rails/redmine-0.6/public;

        location / {
                proxy_set_header  X-Real-IP  $remote_addr;
                proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect false;
                proxy_read_timeout 300;

                if (-f $request_filename/index.html) {
                        rewrite (.*) $1/index.html break;
                }

                if (-f $request_filename.html) {
                        rewrite (.*) $1.html break;
                }

                if (-f $request_filename.txt) {
                        rewrite (.*) $1.txt break;
                }

                proxy_pass http://127.0.0.1:9000/;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root html;
        }

        access_log /var/log/nginx/redmine.access.log;
        error_log /var/log/nginx/redmine.error.log;
}

Activez le site :

ln -s /etc/nginx/sites-available/redmine /etc/nginx/sites-enabled/redmine

et relancer nginx :

/etc/init.d/nginx restart

En vous rendant sur http://localhost/ vous devez avoir accès à votre instance redmine...

Connaissant pas du tout rails et mongrel, il y a peut être des améliorations à apporter. Pour nginx, idem. Je suis preneur d'améliorations :-)

Maintenant, il me reste à étudier la migration de Trac vers Redmine...

Liens utiles :

- page 1 de 6