Outils pour utilisateurs

Outils du site


www_apache2

Ceci est une ancienne révision du document !


Apache2

Catch-all

Lien: http://michauko.org/blog/2012/03/28/catch-all-dns-virtualhost-et-on-fait-mumuse-avec-les-noms-de-sous-domaines/

“ Catch-all DNS, VirtualHost et on fait mumuse avec les noms de sous-domaines ” … a suivre.

Stress avec Curl-Loader

Liens:

$ cd /usr/local/src
$ wget http://downloads.sourceforge.net/project/curl-loader/curl-loader-stable/curl-loader-0.54/curl-loader-0.54.tar.gz
$ tar xvzf curl-loader-0.54.tar.gz

Dependances

# aptitude install make gcc openssl libssl-dev 

mais aussi:

# aptitude install bzip2 patch

Compilation

$ cd /usr/local/src/curl-loader-0.54
$ make cleanall
$ make optimize=1 debug=0
$ su
# make install

Hu?

mkdir -p /usr/bin 
mkdir -p /usr/share/man/man1
mkdir -p /usr/share/man/man5
mkdir -p /usr/share/doc/curl-loader/
cp -f curl-loader /usr/bin
cp -f doc/curl-loader.1 /usr/share/man/man1/  
cp -f doc/curl-loader-config.5 /usr/share/man/man5/
cp -f doc/* /usr/share/doc/curl-loader/ 
cp -rf conf-examples /usr/share/doc/curl-loader/

… passons.

Environment and System

Running hundreds and thousands of clients, please, do not forget:
- to increase limit of descriptors (sockets) by running e.g.
 #ulimit -n 10000;
- optionally, to set reuse of sockets in time-wait state: by setting
 #echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
and/or
 #echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse;

A defaut:

# ulimit -a
...
open files                      (-n) 1024
...

Ce qui est peu. Donc:

# ulimit -n 10000

Exemples de conf

En pratique:

J'ai fait des tests en utilisant des machines virtuels, dans un reseau virtualisé avec des interfaces “dummy”.

Les principaux interets:

  • le reseau est hyper rapide (estimé à 10Gb/s!) puisque tout passe en RAM
  • ce reseau etant vierge, je suis libre d'y mettre n'importe quoi, y compris 2000 IPs :)

Voici une conf de test, largement inspiré de l'exemple “10K.conf”.

########### GENERAL SECTION ################################
BATCH_NAME= test  
CLIENTS_NUM_MAX=10000
CLIENTS_NUM_START=50
CLIENTS_RAMPUP_INC=25
INTERFACE=eth1    
NETMASK=17  
IP_ADDR_MIN= 192.168.128.32
IP_ADDR_MAX= 192.168.191.255  #Actually - this is for self-control
CYCLES_NUM= 5
URLS_NUM= 3

########### URL SECTION ####################################

URL=http://www.thierry-jaouen.fr/index.html
URL_SHORT_NAME="www-index"
REQUEST_TYPE=GET
TIMER_URL_COMPLETION = 1500      # In msec. When positive, Now it is enforced by cancelling url fetch on timeout
TIMER_AFTER_URL_SLEEP = 20

###

URL=http://www.thierry-jaouen.fr/cgi-bin/agenda?action=query&year=2012&month=-1&style=gogol-the-first
URL_SHORT_NAME="www-agenda"
REQUEST_TYPE=GET
TIMER_URL_COMPLETION = 5000      # In msec. When positive, Now it is enforced by cancelling url fetch on timeout
TIMER_AFTER_URL_SLEEP = 2500

###

URL=http://www.thierry-jaouen.fr/music/Devin_Townsend/Devin_Townsend_-_2011_-_Contain_Us/CD1/01_Synchronicity_Freaks.mp3
URL_SHORT_NAME="www-music"
REQUEST_TYPE=GET
TIMER_URL_COMPLETION = 5000      # In msec. When positive, Now it is enforced by cancelling url fetch on timeout
TIMER_AFTER_URL_SLEEP = 500

###

Donc, on va faire notre test en communicant via eth1 , avec beaucoup d'IP.

# curl-loader test.conf

Voila.

Log Syslog

Liens:

Envoyer les logs apache ailleurs…

On suppose qu'on a deja une conf qui envoi les logs ailleurs, par exemple, un fichier /etc/rsyslog.d/maconf.conf avec dedans:

*.*                             @<IP_DU_SERVEUR_DE_LOG>

Si on utilise “syslog-ng” ou tout autre service de log qui accepte le tcp (au lieu d'udp):

*.*                             @@<IP_DU_SERVEUR_DE_LOG>

Error

Envoyer les ERROR dans les logs:

#ErrorLog /var/log/apache2/error.log
ErrorLog syslog:local1

Et pour quand même les renvoyer, aussi, en local dans le fichier “error.log”, ajouter dans un fichier, par exemple /etc/rsyslog.d/apache-error.conf avec dedans:

local1.* /var/log/apache2/error.log
# /etc/init.d/rsyslog restart
# apache2ctl graceful

Access

Dans la conf apache:

  CustomLog /var/log/apache2/access.log combined
  # ---- envoi des logs ailleurs...
  CustomLog |/usr/local/bin/apache_syslog combined

Et le script “apache_syslog” contenant:

#!/usr/bin/perl

use Sys::Syslog qw( :DEFAULT setlogsock );

setlogsock('unix');
openlog('apache', 'cons', 'pid', 'local2');

while ($log = <STDIN>) {
            syslog('notice', $log);
}
closelog

Et relancer apache:

# apache2ctl graceful

nginx

Installation

Vite dit:

Installer:

# aptitude install nginx

Configurer:

# cd /etc/nginx/conf.d
# vi proxy.conf

Et mettre dedans: (adapter)

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
client_header_buffer_size 64k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size       16k;
proxy_buffers           32   16k;
proxy_busy_buffers_size 64k;

Dans /etc/nginx/nginx.conf , apporter les modifs suivantes (adapter!) :

# TJ --------------------
# Pour info, source:
# http://blog.crifo.org/post/2010/03/11/Nginx-en-reverse-proxy
# -----------------------

http {
  include       /etc/nginx/mime.types;

  access_log  /var/log/nginx/access.log;

  sendfile        on;
  # TJ -------------------
  #tcp_nopush     on;
  tcp_nopush     on;
  # ---------------------

  #keepalive_timeout  0;
  keepalive_timeout  65;
  tcp_nodelay        on;

  gzip  on;
  gzip_disable "MSIE [1-6]\.(?!.*SV1)";

  # TJ -------------------
  gzip_comp_level 5;
  gzip_http_version 1.0;
  gzip_types text/plain text/xml text/xhtml text/css image/x-icon application/x-javascript;
  gzip_buffers 16 8k;
  gzip_min_length 0;
  gzip_vary on;

  server_tokens off;
  # ---------------------

  include /etc/nginx/conf.d/*.conf;
  include /etc/nginx/sites-enabled/*;
}

Editer le fichier (par exemple, et adapté) /etc/nginx/sites-enabled/default , pour avoir:

# TJ --------------------

server {
listen 80;
server_name thierry-jaouen.fr www.thierry-jaouen.fr;

location / {
  proxy_pass http://127.0.0.1:8080/;
  access_log off;
}

location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|txt|xml|pdf|PDF)$ {
  root /var/www/thierry-jaouen.fr;
  access_log /var/log/nginx/thierry-jaouen.fr.access.log;
  error_log /var/log/nginx/thierry-jaouen.fr.errors.log;
  expires 30d;
}

location ~ /\.ht {
  deny all;
}

# redirect server error pages to the static page /50x.html
error_page   500 502 503 504  /50x.html;
location = /50x.html {
  root   /var/www/nginx-default;
}
}

# -------------------------
...

L'idée:

  • apache ecoutera sur le port 8080, en local.
  • nginx prend la place d'apache en ecoutant tout sur le port 80
  • tout ce qui n'est pas caché par nginx et envoyer a apache.
# mkdir /var/www/nginx-default

Créer un fichier 50x.html , contenant par exemple:

<h3>Nginx Error: 50x</h3>

Modifier la conf apache afin qu'il n'ecoute que sur le port 8080 en local. Dans /etc/apache2/port.conf , par exemple:

# TJ ------------
#NameVirtualHost *:80
#Listen 80
# pour nginx
NameVirtualHost 127.0.0.1:8080
Listen 127.0.0.1:8080
# ---------------

Et pour le VirtualHost , par ailleurs:

<VirtualHost 127.0.0.1:8080>
... etc...

Pour que les logs Apache reporte l'IP du client final (et non pas 127.0.0.1):

# aptitude install libapache2-mod-rpaf

Et voila:

# /etc/init.d/apache2 restart
# /etc/init.d/nginx restart

Avec “rpaf”, il faut modifier l'adresse local du proxy en editant “rpaf.conf” , pour par exemple:

RPAFproxy_ips <IP_DU_PROXY>

Logs

Voir plus loin avec webalizer.

Tweaks et bugs

Too many open files

Liens: http://www.cyberciti.biz/faq/linux-unix-nginx-too-many-open-files/

Voyons les limites actuelles de “www-data” (ou plutot: de l'utilisateur qui execute “nginx”) :

# su - www-data
$ ulimit -a
time(seconds)        unlimited
file(blocks)         unlimited
data(kbytes)         unlimited
stack(kbytes)        8192
coredump(blocks)     0
memory(kbytes)       unlimited
locked memory(kbytes) 64
process              unlimited
nofiles              1024
vmemory(kbytes)      unlimited
locks                unlimited

Il faut faire au moins faire ça:

Augmenter les limites imposés dans /etc/security/limits.conf , par exemple:

# TJ ---------------
www-data        hard    nofile   30000
www-data        soft    nofile   10000
# ------------------

Si on veut voir le resultat avec un shell (pas indispensable), faire aussi ça, dans /etc/pam.d/common-session afin d'ajouter:

# TJ ------------
session required        pam_limits.so
# ---------------

… Mais ce n'est pas indispensable pour nginx.

On peut vérifier les limits en cours pour un process comme ça:

Exemple avec le “pid” de nginx:

# cat /proc/<pid_nginx_worker_process>/limits
...
Max open files            1024                 1024                 files
...

Mais il faut encore faire 2 modifs dans /etc/nginx/nginx.conf :

worker_rlimit_nofile 30000;

Et dans la section “events”:

events {
  # TJ ------------
  #worker_connections  1024;
  worker_connections 10000;
  # ---------------
  # multi_accept on;
}

Voila.

https reverse proxy

Liens:

Soit un domain: toto.mondomain.fr

export NAME=toto.mondomain.fr

openssl genrsa -des3 -out $NAME.key 1024

(entrer une passe phrase provisoire)

openssl req -new -key $NAME.key -out $NAME.csr

CN:toto.mondomain.fr

Virer la pass-phrase:

cp $NAME.key $NAME.key.bak
openssl rsa -in $NAME.key.bak -out $NAME.key

1 domaine

Un seul domaine

openssl x509 -req -days 3650 -in $NAME.csr -signkey $NAME.key -out $NAME.crt

Les clefs sont prêtes.

multi-domaine

Lien: http://thomaswabner.wordpress.com/2009/11/17/create-self-signed-multi-domain-certificate/

Il faut mettre plusieurs domaines dans le certificat de la facon suivante:

Créer un fichier “$NAME.domain_extensions.txt” contenant :

[ mydomain_http ]
nsCertType      = server
keyUsage        = digitalSignature,nonRepudiation,keyEncipherment
extendedKeyUsage        = serverAuth
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid,issuer
subjectAltName          = @mydomain_http_subject
[ mydomain_http_subject ]
DNS.1 = sub1.mondomain.fr
DNS.2 = sub2.mondomain.fr
... etc ...
DNS.x = xxxx.mondomain.fr

Et enfin

openssl x509 -req -days 3650 -in $NAME.csr -signkey $NAME.key -out $NAME.crt -extfile $NAME.domain_extensions.txt -extensions mydomain_http

Et voila: tout les domaines “DNS.1” a “DNS.x” sont associés aux clefs.

:!: Il serai aussi possible d'utiliser “*.mondomain.fr”

nginx

Apache HA

Apache Load balancing

Optimiser

auth

Plein de bonne manière de s'authentifier sur apache, en francais:

PAM

mod-auth-pam

Liens:

# aptitude install libapache2-mod-auth-pam

Comme ce n'est pas dit dans la doc, je le dis ici: Il faut ajouter “www-data” dans le group shadow:

# adduser www-data shadow

… afin qu'il puisse lire (peut être pas directement) le fichier /etc/shadow .

:!: “mod-auth-pam” serait déprécié, du fait de son accès trop direct a “shadow”: mais pour l'heure, pas de remplacant !

Pas besoin d'activer ce module, il l'est automatiquement…

Directory

 <Directory /var/www/les-plans-secret-de-la-soucoupe-volante>
      AuthType Basic
      AuthName "Restricted area for My Server"
      AuthPAM_Enabled On
      AuthPAM_FallThrough off
      AuthBasicAuthoritative off
      AuthUserFile /dev/null
      Require valid-user
      Satisfy All
  </Directory>

Ne pas oublier: Require valid-user :))

Aprés un apache2ctl graceful ,

:!: ATTENTION :!:

C'est l'ensemble des comptes qui vont être autorisé a se connecter … !

Et ça ne me plait pas !!! voir la section suivante…

PAM et group

On va autoriser uniquement certains groupes, mais surement pas tous.

Pour cela, il faut d'abord changer la conf dans /etc/pam.d/apache2 , afin d'avoir:

# TJ ------------
auth       required     pam_listfile.so onerr=fail item=group sense=allow file=/etc/login-pam-apache-group.allowed
# ---------------
@include common-auth
@include common-account

… et il faut creer un fichier contenant la liste des groupes, là: /etc/login-pam-apache-group.allowed , avec dedans:

users
webfriends
nolife

Je n'autorise que ces 3 groups.

Installation

avec Perl

# aptitude update
# aptitude install apache2 libapache2-mod-perl2

apache2 et inetd

Aprés lecture, il s'avere qu'Apache2 ne peut que fonctionner en “daemon”. Cela viendrait du “Prefork” et autres pour optimiser le temps de reponse.
On ne peut que limiter les ressources utiliser par le daemon.

logs

# mkdir logs
# chown www-data: logs

Perl Templates

Lien: http://perl.enstimac.fr/ModulesFr/Html-Template.html

Pour HTML::Template

# aptitude install libhtml-template-perl

C'est quoi la version:

$ perl -MHTML::Template -e 'print $HTML::Template::VERSION'
2.9

Perl CGI Plugin

:!: Preferer l'installation par cpan ! version moins buggée
# apt-get install libcgi-application-plugins-perl

Ou plus simplement:

# aptitude install libcgi-session-perl

Ce qui installe (entre autres!) CGI::Session :

$ perl -MCGI::Session -e 'print $CGI::Session::VERSION'
4.20

CGI::Carp::DebugScreen

# cpan -i CGI::Carp::DebugScreen

Version installé (applicable a d'autres modules bien sur):

$ perl -MCGI::Carp::DebugScreen -e 'print $CGI::Carp::DebugScreen::VERSION'
0.14

Desinstaller

Desinstaller le module cpan…

D'abord, trouver où ils sont installé (compilé en fait).
Moi c'est la:

/root/.cpan

On va dans:

# cd /root/.cpan/build/CGI-Carp-DebugScreen-0.14

Et puis:

# make uninstall
:!: En fait, ca ne marche pas … il faut bricoler!

mod_perl 1 puis 2

Renommage de “mod_perl” pour “Apache2”.

Solution:

Dans httpd.conf ou ailleurs, ajouter:

# TJ
# --------
PerlModule Apache2::compat
# --------

Dans les scripts Perl, mettre en commentaire les chargements de package “Apache.pm” et mettre plutot:

#use Apache ();
#use Apache::Constants qw( OK );
#use Apache2::compat;
use Apache2::Const qw( OK );

Il ne faut pas rever: On ne compile pas avec “use Apache2::compat” a cause de recurrent:

Can't locate object method "header_in" via package "Apache2::RequestRec" ...

evasive

webalizer

Installation

webalizer.conf

# aptitude install webalizer

Configurer en adaptant le fichier /etc/webalizer/webalizer.conf :

En dehors du “hostName”, on ajoute:

# TJ -------------
#Incremental    no
Incremental     yes
# ----------------

Afin qu'on puisse faire plusieurs traitements sur des gros logs, quotidiennement.

On a rien d'autres a faire pour l'instant et le fichier /var/log/apache2/access.log.1 existe et “attend” son traitement.

# /etc/cron.daily/webalizer

Et voila. Le répertoire /var/www/webalizer contient des fichiers.

Apache

La racine du site est dans /var/www/webalizer .

Dans la conf apache, on peut ajouter un truc comme ça:

      # Webalizer --------------

      Alias /webalizer               /var/www/webalizer

      <Directory /var/www/webalizer/>
              Options +FollowSymLinks
              AllowOverride None

              order deny,allow
              deny from all
              allow from 127.
              allow from <IP_DE_CONFIANCE_SI_CA_EXISTE>

              AuthName    "access restreint"
              AuthUserFile /var/lib/passwd-www/webalizer_htpasswd
              AuthGroupFile /dev/null
              AuthType Basic
              require valid-user

              # soit "allow" , soit "Auth" est suffisant pour autoriser l'acces...
              Satisfy Any
      </Directory>
    
# mkdir -p /var/lib/passwd-www

(Avec -c en option la 1er fois pour créer le fichier)

# htpasswd -c /var/lib/passwd-www/webalizer_htpasswd <my_account>
New password: 
Re-type new password: 
Adding password for user <my_account>
# apache2ctl graceful

Mais la 1er fois, il est vide ce répertoire: donc on le remplir avec un 1er traitement des logs.

Mais d'abord: configurer “webalizer” himself.

Log Apache et nginx

vite dit

# aptitude install awstats

Pour récuperer le scripte:

/usr/share/awstats/tools/logresolvemerge.pl

Donc:

# ln -s /usr/share/awstats/tools/logresolvemerge.pl /usr/local/bin

On doit merger les logs nginx et apache pour que webalizer soit juste correct.

Exemple:

# mkdir <SOMEWHERE_FOR_TESTING_PURPOSE>/labo
# cd <SOMEWHERE_FOR_TESTING_PURPOSE>/labo
# cp /etc/webalizer/webalizer.conf .

Modifier webalizer.conf et commenter la ligne “LogFile”.

# logresolvemerge.pl /var/log/nginx/thierry-jaouen.fr.access.log.1 /var/log/apache2/access.log.1 | webalizer -

Et voila.

On a merge et on envoyer directement le flow en traitement pour webalizer…

:!: les fichiers mergés doivent couvrir la même période de temps !!!

… la dernière date traité faisant office de point de départ pour le fichier suivant. (toutes les dates anterieures étant ignoré)

en pratique

Soit les rotations de logs nginx et apache en “daily” (ou en weekly, mais identique)

Soit :

  1. nginx qui génère des logs, et a la rotation quotidienne: /var/log/nginx/thierry-jaouen.fr.access.log.1
  2. apache qui génère des logs, et à la rotation quotidienne: /var/log/apache2/access.log.1

Soit dans webalizer.conf dans /usr/local/etc et contenant essentiennellement.

# pas de ligne "LogFile"
Incremental yes

Soit dans /etc/cron.daily/ un fichier nommé webalizer-update et contenant:

#!/bin/sh
/usr/local/bin/webalizer-update

Soit un script nommé webalizer-update dans /usr/local/bin et contenant:

#!/bin/sh

# --------------------------------------------
# - La conf est dans /etc/webalizer/webalizer.conf !!!
# - La ligne "LogFile" est ignoré au profit de STDIN
# - Desactiver/modifier le "cron.daily/webalizer" afin d'executer ce script
# --------------------------------------------

NAME=`basename $0`

WEBALIZER=/usr/local/bin/webalizer
MERGE=/usr/share/awstats/tools/logresolvemerge.pl

STAT=/usr/bin/stat
AWK=/usr/bin/awk

# ------------------------------------
# Les fichiers de LOGS a "merger"
# ------------------------------------

LOGS="/var/log/nginx/thierry-jaouen.fr.access.log.1 /var/log/apache2/access.log.1"

logger -t ${NAME} "start ..."

# Verifions l'existance des binaires principaux 

if [ ! -x ${WEBALIZER} ] || [ ! -x ${MERGE} ] ; then
  echo "${WEBALIZER} or ${MERGE} missing" >&2
  exit 1
fi

# Verifier l'ecart de temps entre les 2 (premiers?) fichiers (2?)

if ! EPOCHs="$( ${STAT} --printf='%Z ' ${LOGS} )" ; then
  echo "ERREUR: MERGE webalizer non effectué" >&2
  exit 1
fi

# ecart en secondes entre les dates de modifications des 2 fichiers (valeur absolue)
DIFFS=$( echo ${EPOCHs} | ${AWK} -F' ' '{ diff=$2-$1; diff=(diff<0?-diff:diff); printf "%ld", diff; }' )

# On tolere 120 secondes, soit 2 minutes

if [ ${DIFFS} -ge 120 ]; then
  echo -e "ERREUR!\nEcart de ${DIFFS} secondes entre les fichiers:\n${LOGS}\nMERGE webalizer non effectué\n" >&2
  exit 1
fi

# Sinon Ok.

logger -t ${NAME} "running... ${LOGS}"

${MERGE} ${LOGS} | ${WEBALIZER} -c /usr/local/etc/webalizer.conf -

logger -t ${NAME} "end."

# --------------
# EOF

Que fait ce script ?

  1. il verifie que l'essentiel pour s'executer est en place
  2. que l'ecart de date de modification entre les 2 fichiers n'est pas énorme (sinon, y a surement une rotation qui ne se fait pas)
  3. merge et import des données dans webalizer

Compilation

Suite a un bug curieux, reproductible a volonté, me voila a chercher une version “recente” de webalizer.

D'abord, virer la version installé:

:!: Faire des copies de sauvegarde de

/etc/webalizer/*conf
/var/www/webalizer

Tout va disparaitre:

# dpkg -P webalizer

Télécharger la dernière version “stable”:

$ cd /usr/local/src
$ wget ftp://ftp.mrunix.net/pub/webalizer/webalizer-2.23-05-src.tgz
$ tar xvzf webalizer-2.23-05-src.tgz
$ cd webalizer-2.23-05

Dépendances:

$ su
# aptitude install gcc make libz-dev libpng-dev libgd2-noxpm-dev

# exit
$ ./configure
$ make
$ su
# make install

L'executable s'installe dans :

/usr/local/bin

On mettra la conf dans:

/usr/local/etc

Et voila ?

Bug corrigé.

Music

Permettre l'accés a ma musique, juste pour moi bien sur.

module

package

# aptitude install libapache2-mod-musicindex
...
Les NOUVEAUX paquets suivants vont être installés :
libapache2-mod-musicindex libarchive1 libflac7 libid3tag0 libmad0 libogg0 libvorbis0a libvorbisfile3
mod-musicindex-common
...
Paramétrage de libapache2-mod-musicindex (1.1.3-4) ...

Activer

# a2enmod musicindex

site www

Composer un hôte virtuel comme ca (exemple) :

<VirtualHost *:80>
      ServerName music.thierry-jaouen.fr

      ServerAdmin webmaster@localhost

      DocumentRoot /mnt/music

      <Directory />
              Order deny,allow
              deny from all
      </Directory>

      <Directory /mnt/music/>
          Order deny,allow
          deny from all
          allow from .thierry-jaouen.local

          AuthName    "access restreint"
          AuthUserFile <FICHIER_DE_MOTS_DE_PASSE>
          AuthGroupFile /dev/null
          AuthType Basic
          require valid-user

          # soit "allow" , soit "Auth" est suffisant pour autoriser l'acces...
          Satisfy Any

          Options             Indexes MultiViews FollowSymlinks
          AllowOverride       Indexes
          MusicSortOrder      album disc track artist title length bitrate freq filet$
          MusicFields         title artist length bitrate
          # ------------ voir commentaire ---------
          MusicLister         On
          MusicAllowDownload  Off
          MusicAllowStream    On
          MusicAllowSearch    On
          #    MusicRssItems       Off
          # ---------------------------------------
          MusicPageTitle      titi
          #MusicCssDefault     musicindex.css
          #MusicCachePath      /tmp/musicindex
          #    MusicIceServer     [ice.domain.my]:8000
          #    MusicCookieLife    300
      </Directory>

      ErrorLog /var/log/apache2/error.log

      # Possible values include: debug, info, notice, warn, error, crit,
      # alert, emerg.
      LogLevel warn

      CustomLog /var/log/apache2/access.log combined
      ServerSignature On
  </VirtualHost>
:!: Depuis “Debian Lenny” , le module “musicindex” a changé

Dans le cas de “Lenny” et “musicindex version 1.2.2-3”, il faut plutot mettre certains paramètres comme cela:

MusicIndex On +Stream +Search +Download -Rss -Tarbal

Au lieu de :

MusicLister         On
etc...

Le <FICHIER_DE_MOTS_DE_PASSE> est composé avec htpasswd et ce place, là ou vous pouvez.

Ensuite, on active le nouveau site:

# a2ensite 220-titi-music.conf

Et on relance apache2:

# apache2ctl graceful

Et on regarde dans http://music.thierry-jaouen.fr

Rewrite

Invalid command 'RewriteEngine'

Il faut activer le module:

# a2enmod rewrite

Proxy

http

Invalid command 'ProxyRequests'

En conséquence:

# a2enmod proxy_http
Enabling proxy as a dependency
Module proxy installed; run /etc/init.d/apache2 force-reload to enable.
Module proxy_http installed; run /etc/init.d/apache2 force-reload to enable.

html

Liens:

On utilise: libapache2-mod-proxy-html 3.0.0-1 … et non pas “3.1”…

Donc là: http://apache.webthing.com/mod_proxy_html30/config.html

“If you are using a mod_proxy_html version older than 3.1, there is no ProxyHTMLEnable directive, and you'll have to insert the filter with Apache's standard directives: for example
SetOutputFilter proxy-html
” C'est bon a savoir!

le module “deflate” peut poser un problème, et il y a plusieurs solutions:

  • soit le desactiver sur le serveur 'zm' : a2dismod deflate
  • soit l'activer sur tout les serveurs ( a2enmod deflate ) et mettre: SetOutputFilter INFLATE;proxy-html;DEFLATE (en lieu et place de SetOutputFilter proxy-html)
  • soit modifier l'entête en faisant: a2enmod headers et dans la conf: RequestHeader unset Accept-Encoding

Une conf complète, qui fonctionne, dans la mesure ou le html n'est pas trop tordu :-?

ProxyRequests Off

<Proxy *>
  Order deny,allow
  Allow from all
</Proxy>

RedirectMatch ^/zm$ /zm/

# Simple 1
#  ProxyPass /zm/ http://192.168.6.12/
#  ProxyPassReverse /zm/ http://192.168.6.12/

# Simple 2
# http://wiki.uniformserver.com/index.php/Reverse_Proxy_Server_2
ProxyPass /zm/ http://192.168.6.12/
ProxyHTMLURLMap http://192.168.6.12 /zm

<Location /zm/>
  ProxyPassReverse http://192.168.6.12/

  # methode 1
  #SetOutputFilter proxy-html

  # methode 2
  #SetOutputFilter INFLATE;proxy-html;DEFLATE

  # methode 3
  # avec: # a2enmod headers
  SetOutputFilter proxy-html
  RequestHeader unset Accept-Encoding

  ProxyHTMLURLMap / /zm/
  #ProxyHTMLURLMap /zm /zm

  #ProxyHTMLExtended On
</Location>

Expires

Perl

Un scripte perl qui retourne un “gif” (ou autres choses), et on ne veut pas que ce soit caché:
(En reponse dans le entête HTTP)

print "Cache-Control: max-age=0\n";

Module

Lien: http://httpd.apache.org/docs/1.3/mod/mod_expires.html

En activant un module apache

# a2enmod expires

Modifier dans l'hôte virtuel (par exemple)

ExpiresActive On
ExpiresDefault "access plus 1 hour"
ExpiresByType image/gif "access plus 0 second"

Par defaut, on cache 1 heure (ce qui n'est pas beaucoup en fait).
Mais pour les “gif”, on ne cache jamais.

Fast CGI

Quoi

C'est un CGI qui est chargé 1 fois, puis execute les requetes au fur et a mesure…

Comment

mod

Installer le module “fastcgi”

# apt-get install libapache2-mod-fastcgi

Si nécessaire, activer le module avec:
(En passant, on jettera un oeil dans fastcgi.conf)

# a2enmod fastcgi

Si nécessaire, redémarrer apache :

# apache2ctl graceful

Perl

Installer

Installer le module Perl “CGI::Fast”

# apt-get install libcgi-fast-perl

Exemple

$ vi /var/lib/cgi-bin/example.fcgi
#!/usr/bin/perl -w

use CGI::Fast qw( :standard );

my $COUNTER = 0;

{
    while( my $q = new CGI::Fast )
    {
        print STDOUT $q->header();
        print STDOUT "<h3>Hello World</h3><br>\n";
        print STDOUT "$COUNTER<br>";

        $COUNTER++;
    }
}

La 1er requete /cgi-bin/example.fcgi charge le scripte et pas les suivantes.

Probleme

  • Prendre garde aux fuites de mémoires
  • Il faut redemarrer apache pour changer les versions des CGI

SSI ou SHTML ou INCLUDE

Lien: http://httpd.apache.org/docs/2.0/howto/ssi.html

(Existe aussi pour Apache1)
Rendre “dynamique” le html, en activant la fonctionnalité SSI (Server Side Includes).

shtml

Par defaut, Apache2 est presque prêt…

Dans des “Directory/Location” de son choix, ajouter:

Options +Includes

Verifier qu'on a quand même quelque part dans 'apache2.conf':

AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

Donc, maintenant, les fichiers ayant l'extension “.shtml” sont parsé à la recherche de “commande/include” SSI.

XBitHack

Mais, on prèfere ne pas changer l'extention de “.html”, sans, toutefois, activer le SSI pour tout les fichiers “.html” (c'est vivement déconseillé).

Dans son “VirtualHost” ou des “Directory/Location” de son choix, ajouter:

XBitHack on

(Sans oublier le “Options +Includes” comme vu ci-dessus)

Activer le module “Include” :

# a2enmod include

Et maintenant, tout fichier “.html” ayant le bit “X” (eXecute) d'activé, seront parsé à la recherche d'instruction SSI.

Exemple:

<code><!--#exec cmd="date +\"%T %D\"" --></code><br>
<code><!--#exec cmd="uname -s -r" --></code>

Apache2 et SSL

Certificat

 Vite dit: il y aurait beaucoup plus simple avec: make-ssl-cert /usr/share/ssl-cert/ssleay.cnf apache.pem
NAME=le nom que vous voulez

Choisissez convenablement le Common Name, afin qu'il soit le nom du site. Exemple:

www.mon_site_en_https.com

Créer la clef:

$ openssl req -new > $NAME.csr

Enlever la passphrase: (sinon, elle sera demandé au demarrage d'apache)

$ openssl rsa -in privkey.pem -out $NAME.key

Creation du certificat (.crt) et de la clef (.key):

$ openssl x509 -in $NAME.csr -out $NAME.crt -req -signkey $NAME.key -days 3650

Valable pour moins de 10 ans… Et voila, on a:

  1. $NAME.crt
  2. $NAME.key

Copier les clefs quelques parts (et effacer les relicats de la création):

# mkdir /etc/apache2/ssl.crt
# mkdir /etc/apache2/ssl.key
# chmod 700 /etc/apache2/ssl.key
# mv ..../$NAME.crt /etc/apache2/ssl.crt/
# mv ..../$NAME.key /etc/apache2/ssl.key/

module SSL

Si nécessaire, activer le module SSL en faisant:

# a2enmod ssl

Ou en creant les liens symboliques qui vont bien pour avoir:

/etc/apache2/mods-enabled# ls -lart
...
lrwxrwxrwx 1 root root   26 2007-07-28 16:56 ssl.load -> ../mods-available/ssl.load
lrwxrwxrwx 1 root root   26 2007-07-28 16:56 ssl.conf -> ../mods-available/ssl.conf
...

Sauf erreur, rien a toucher dans ssl.conf .

https

Activer l'ecoute sur le port 443 , c'est dire https .

# vi /etc/apache2/ports.conf

Et ajouter:

Listen 443

VirtualHost

vite

Créer un VirtualHost, en prenant garde d'avoir ça (si necessaire):

NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost _default_:80>
  # FACULTATIF
  #
  # Si declaré, c'est l'hote par defaut si aucun autre ne correspond
  #
  # Sinon, c'est le 1er "virtualhost" qui recupere la requete.
  #
  # NE PAS METTRE DE "servername" ou "serveralias"

  ... etc...    
</VirtualHost>

# www via http
<VirtualHost *:80>
  ServerName www.thierry-jaouen.fr
  ServerAlias thierry-jaouen.fr tjaouen.fr www.tjaouen.fr

  ServerAdmin webmaster@localhost
  DocumentRoot /...
  ... etc ...
</VirtualHost>

<VirtualHost *:80>
  ServerName myblog.thierry-jaouen.fr

  ... etc ...
</VirtualHost>

<VirtualHost *:80>
  ServerName blackhole.thierry-jaouen.fr

  ... etc ...
</VirtualHost>

# www via https
<IfModule mod_ssl.c>
  <VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl.crt/$NAME.crt
    SSLCertificateKeyFile /etc/apache2/ssl.key/$NAME.key
  
    ServerAdmin webmaster@localhost
    DocumentRoot /...
    ... etc ...
  </VirtualHost>
</IfModule>

IP

Toutefois, il semblerait que l'emploi du joker “*” est inapproprié si on a une IP fixe…

Ok, mais dans ce cas, la notion de “VirtualHost _default_” disparait, ou dumoins, ne fonctionne plus.
Il faut alors créer , en tête de configuration, un “VirtualHost” comme ca:

NameVirtualHost 192.168.0.123:80

<VirtualHost 192.168.0.123:80>
# "_default_" en quelque sorte...
... etc ...
</VirtualHost>

<VirtualHost 192.168.0.123:80>
  ServerName www.thierry-jaouen.fr 
...etc...
</VirtualHost>

Il m'a fallu quelques heures pour comprendre… :-x

ImageMagick

PerlMagick

install

# aptitude install perlmagick

STDOUT

La doc donne cette manière d'envoyer l'image dans STDOUT:

binmode STDOUT;
print STDOUT "Content-type: image/jpeg\r\n\r\n";
$image->Write( 'jpeg:-' );

Mais dans un cgi, et peut être a cause de “Mod Perl” (d'aprés cette note), ca ne fonctionnera pas, et de façon sournoise.

La solution: Utiliser les “Blob” !

binmode STDOUT;
print STDOUT "Content-type: image/jpeg\r\n\r\n";
print STDOUT ( $image->ImageToBlob() )[0];

ou en plus lisible:

my @blobs = $image->ImageToBlob();

binmode STDOUT;
print STDOUT "Content-type: image/jpeg\r\n\r\n";
print STDOUT $blobs[0];

:!: En fait, “binmode STDOUT” est superflu dans un cgi

:!: Préablement à génération du “blob”, il peut être necessaire de préciser le format et les attributs souhaités !

$image->Set( quality=>85, magick => 'jpeg' ); 
www_apache2.1335109215.txt.gz · Dernière modification : 2012/04/22 15:40 de thierry