Table des matières
Apache2
Catch-all
“ 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
: Un exemple, mais je n'ai pas tout compris…
server { listen 443; server_name .thierry-jaouen.fr .tjaouen.fr; ssl on; ssl_certificate /etc/nginx/ssl/thierry-jaouen.fr.crt; ssl_certificate_key /etc/nginx/ssl/thierry-jaouen.fr.key; keepalive_timeout 60; location / { proxy_pass http://wwwcave.local.eez.fr:80/; access_log off; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; ### Set headers #### proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ### Most PHP, Python, Rails, Java App can use this header ### proxy_set_header X-Forwarded-Proto https; ### By default we don't want to redirect it #### proxy_redirect off; } }
Le “https” est alors géré entre le client et nginx
.
MAIS , entre nginx
et le serveur apache, ce n'est que du http
.
C'est pour cela que le flag “X-Forwarded-Proto https” est fixé.
Ainsi, pour vos règles de rewrite
, par exemple:
Remplacer:
RewriteCond %{SERVER_PORT} !^443$ |
par
RewriteCond %{HTTP:X-Forwarded-Proto} !^https$ |
Apache HA
Apache haute-disponibilité ?
Liens:
Apache Load balancing
Liens:
Optimiser
Liens:
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" ...
Anti DoS ou evasive
Protection contre DoS, etc …
Liens:
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 :
nginx
qui génère des logs, et a la rotation quotidienne:/var/log/nginx/thierry-jaouen.fr.access.log.1
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 ?
- il verifie que l'essentiel pour s'executer est en place
- 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)
- 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 deSetOutputFilter 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
Lien:
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
Liens:
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:
- $NAME.crt
- $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…
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' );