====== Serveur chd-tls1 ======
===== Caractéristiques =====
* Machine virtuelle (KVM amd64)
* Installé en Debian 8, migré en Debian 9.4 le 2018-03-12
===== Roles =====
* Outils collaboratif de l'asso
* Appli de gestion des adhérents
* Surveillance (monitoring) des équipements en Comminges
* Tests de débit des liens vers Saint-Gaudens
===== Notes d'installation =====
==== Système / Réseau ====
# Parti d'un template Debian 8 préinstallé sur un disque de 8 giga
editor /etc/hosts /etc/hostname /etc/network/interfaces /etc/resolv.conf
ifup eth0
ping 185.61.116.254
ping 8.8.8.8
ping google.fr
passwd root
reboot
hostname --fqdn
apt-get update
apt-get install openssh-server
deluser temp
editor ~root/.ssh/authorized_keys
editor ~/.bashrc
passwd -dl root
apt-get autoremove --purge rpcbind nfs-common
apt-get install sudo arping ethtool fail2ban iftop iperf lldpd molly-guard nmap ntp powertop procps rdiff-backup rsync screen sshpass strace sysstat tcpdump vim w3m unzip
apt-get install apache2 libapache2-mod-php5 mysql-server automysqlbackup phpmyadmin munin munin-node pdns-recursor
rm /etc/munin/plugins/ntp_kernel_*
rm /etc/munin/plugins/nfs*
service munin-node reload
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename},label=Debian-Security";
};
Unattended-Upgrade::Package-Blacklist {
};
Unattended-Upgrade::Mail "root";
Unattended-Upgrade::Automatic-Reboot "true";
==== Services web ====
apt-get install dokuwiki owncloud cgit
zless /usr/share/doc/owncloud/README.Debian.gz
a2disconf dokuwiki
a2disconf munin
a2disconf cgit
a2disconf owncloud
a2disconf phpmyadmin
a2disconf serve-cgi-bin
editor /etc/apache2/sites-available/000-default.conf
editor /etc/apache2/sites-available/default-ssl.conf
editor /etc/apache2/sites-available/redirect.conf
editor /etc/apache2/sites-available/www.conf
editor /etc/apache2/conf-available/dokuwiki.conf
editor /etc/apache2/conf-available/phpmyadmin.conf
editor /etc/apache2/conf-available/munin.conf
editor /etc/apache2/conf-available/security.conf
editor /etc/cgitrc
a2ensite default-ssl
a2ensite redirect
a2ensite www
a2enmod rewrite
a2enmod cgi
a2enmod fcgid
a2enmod ssl
htpasswd -Bc /etc/apache2/priv.htpasswd admin
chgrp www-data /etc/apache2/priv.htpasswd
chmod 640 /etc/apache2/priv.htpasswd
service apache2 restart
mkdir /var/www/priv
editor /var/www/html/index.html
editor /var/www/priv/index.html
editor /usr/local/bin/tailapache
chmod 755 /usr/local/bin/tailapache
editor /etc/dokuwiki/dokuwiki.php
editor /etc/dokuwiki/mime.php # Ajouter eps (même mimetype que ps)
rm /etc/dokuwiki/local.php
chown www-data /var/lib/dokuwiki/lib/plugins/
mysql --defaults-file=/etc/mysql/debian.cnf
CREATE DATABASE owncloud;
CREATE USER owncloud@localhost IDENTIFIED BY 'monsupermotdepasse';
GRANT ALL PRIVILEGES ON owncloud.* TO owncloud@localhost;
FLUSH privileges;
quit
* le config.php se remplit à partir de [[http://priv.chd.sx/owncloud|http://priv.chd.sx/owncloud]]
* l'initialisation de la base est incluse
==== Certificat SSL LetsEncrypt ====
* Utilisé pour [[https://priv.chd.sx|https://priv.chd.sx]]
* LetsCrypt a été installé en root, il demande sudo de manière inconditionnelle de toutes façons
* Procédure inspirée de la doc officielle [[https://letsencrypt.org/howitworks/|https://letsencrypt.org/howitworks/]]
* Installer l'outil depuis git (pas encore stable / packagé)
cd /root
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help
# Installe toutes les dépendances et fini par afficher l'aide
* Faire de sorte que le binaire ''letsencrypt'' soit dans le path
ln -s /root/.local/share/letsencrypt/bin ~/
editor ~/.profile
# [...]
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ]; then
PATH="$HOME/bin:$PATH"
fi
* Obtention des certificat initiaux
letsencrypt --apache
# Accepter les TOS
# Sélectionner priv.chd.sx et www.priv.chd.sx
* Arranger les vhosts, le comportement par défaut fait une boucle de redirection (sympa)
cat /etc/apache2/sites-available/redirect-le-ssl.conf
rm /etc/apache2/sites-available/redirect-le-ssl.conf
editor /etc/apache2/sites-available/default-ssl.conf
# [...]
SSLCertificateFile /etc/letsencrypt/live/priv.chd.sx/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/priv.chd.sx/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
* Scripter le renewal automatique
editor /etc/cron.monthly/letsencrypt-renew
chmod +x /etc/cron.monthly/letsencrypt-renew
#!/bin/sh
/root/bin/letsencrypt renew --agree-tos > /var/log/letsencrypt/renew.log 2>&1
res=$?
if [ $res -ne 0 ]; then
echo Automated renewal failed:
cat /var/log/letsencrypt/renew.log
exit $res
fi
service apache2 reload
===== Serveur DNS (autorité pour les reverse DNS, secondaire) =====
apt-get install bind9
editor /etc/bind/{named.conf.options,named.conf.local,db.185.131.40,db.185.131.41}
service bind9 restart
===== Appli de gestion =====
* Base créée via phpmyadmin (+ import fichier .sql)
==== Installation et premier CRUD ====
cd /var/www
wget https://getcomposer.org/composer.phar
php composer.phar create-project --prefer-dist cakephp/app chd_gestion''
cd chd_gestion
# Config BDD
editor config/app.php
# Alias /gestion /var/www/chd_gestion/webroot
editor /etc/apache2/sites-enabled/default-ssl.conf
# Ajout RewriteBase /gestion
editor .htaccess webroot/.htaccess
# Test et vérifications embarquées dans Cake
www-browser https://priv.chd.sx/gestion
# Première génération de l'appli par rapport aux tables présentes dans la BDD
for i in adherents equipement_stock equipements ip4privees ip4publiques relais secteurs service_types services villes; do bin/cake bake all $i; done
# Changer la page d'accueil pour arriver directement sur la liste des adhérents
editor config/routes.php
# $routes->connect('/', ['controller' => 'Adherents', 'action' => 'index']);
# Tester l'appli
www-browser https://priv.chd.sx/gestion
==== Ajouter phpunit pour faire des tests ====
[[https://getcomposer.org/doc/03-cli.md#require|Doc de composer]]
php ../composer.phar require --dev phpunit/phpunit:5.*
# Ecrire un premier Test (bake en génère tout plein par ailleurs)
editor tests/TestCase/View/I18nBasicTest
==== Traduire les textes en français ====
=== Générer le fichier modèle de traduction (.pot) ===
bin/cake i18n extract
# Toutes les réponses par défaut. Overwrite : yes.
=== Écrire un fichier po (au bon endroit) ===
root@chd-tls1:/var/www/chd_gestion# find src/Locale/ -ls
395603 4 drwxr-x--- 3 root root 4096 oct. 17 20:01 src/Locale/
406962 36 -rw-r--r-- 1 root root 32982 oct. 17 16:11 src/Locale/default.pot
395531 4 drwxr-xr-x 2 root root 4096 oct. 17 20:15 src/Locale/fr_FR
407961 40 -rw-r--r-- 1 root root 38367 oct. 17 20:15 src/Locale/fr_FR/default.po
=== Ajouter les outils de vérification des fichiers de traductions gettext ===
apt-get install gettext-lint gettext
POFileChecker src/Locale/fr_FR/default.po
msgfmt -v -c src/Locale/fr_FR/default.po
vendor/bin/phpunit --filter testBasicTranslation tests/TestCase/View/I18nBasicTest
=== Export réguliers vers eCampaign ===
editor /etc/cron.daily/ecampaign-export
chmod +x /etc/cron.daily/ecampaign-export
#!/bin/sh
php /root/chd_gestion/api/export_ecampaign_cron.php >/dev/null
===== Système mail =====
editor /etc/mailname
dpkg-reconfigure exim4-config
# Listen 25 : 127.0.0.1, ::1
# Split config : oui
rm /etc/exim4/exim4.conf.template # Pour éviter de se tromper (inutilisé, cf conf.d)
update-exim4.conf
apt-get install sympa
a2disconf sympa
editor /etc/apache2/sites-available/www.conf
editor /etc/apache2/conf-available/sympa.conf
editor /etc/sympa/wwsympa.conf
service apache2 reload
editor /etc/sympa/sympa.conf # Penser notamment a passer use_fast_cgi à 1
editor /etc/sympa/topics.conf # C'est là dedans les catégories moches
service sympa restart
editor /etc/aliases
cp -a /etc/exim4/conf.d/router/{400_exim4-config_system_aliases,450_local-config_sympa-aliases}
editor /etc/exim4/conf.d/router/450_local-config_sympa-aliases
cp -a /etc/exim4/conf.d/router/{450_local-config_sympa-aliases,440_local-config_sympa-global-aliases}
editor /etc/exim4/conf.d/router/440_local-config_sympa-global-aliases
update-exim4.conf
service exim4 reload
www-browser http://chd.sx/sympa
mkdir /etc/sympa/families/village
cp /var/lib/sympa/list_data/adhesion/config /etc/sympa/families/village/config.tt2
editor /etc/sympa/families/village/config.tt2
editor /etc/sympa/families/village/data.sh
editor /etc/sympa/families/village/instantiate.sh
==== Mettre à jour la famille de listes des villages ====
root@chd-tls1:~# cd /etc/sympa/families/village
root@chd-tls1:/etc/sympa/families/village# ./instantiate.sh
err Family::_load_param_constraint_conf() No file /etc/sympa/families/village/param_constraint.conf. Assuming no constraints to apply.
******************************************************************************
******************** INSTANTIATION of village FAMILY ********************
******************************************************************************
These lists have been created and aliases are ok :
ardiege, clarac, estancarbon, figarol, huos, labarthe-inard, labarthe-riviere, lalouret-laffiteau, landorthe, larcan, le-cuing, lieoux, lodes, martres-de-riviere, miramont-de-comminges, montespan, pointis-de-riviere, pointis-inard, saint-gaudens, saint-ignan, saux-et-pomarede, savarthes, villeneuve-de-riviere
==== Limiter le Spam ====
=== Exploitation ===
Les fichiers pour pourvoir ajouter des exceptions au filtrage sont :
/etc/exim4/host_local_deny_exceptions
/etc/exim4/local_domain_dnsbl_whitelist
/etc/exim4/local_helo_blacklist
/etc/exim4/local_host_blacklist
/etc/exim4/local_sender_blacklist
/etc/exim4/sender_local_deny_exceptions
/etc/spamassassin/local.cf
=== SPF ===
Le filtre SPF regarde l'expéditeur d'un mail, cherche dans le DNS quelles machines ont le droit d'envoyer un mail pour ce domaine et décide si le mail est acceptable ou non.
# test avant SPF depuis une connexion quelconque (hors serveur pouzenc.fr)
lpouzenc@lud-x200s:~$ dig +short TXT pouzenc.fr
"v=spf1 +mx -all"
# Seul le serveur MX du domaine pouzenc.fr est autorisé à envoyer des mail from ...@pouzenc.fr
lpouzenc@lud-x200s:~$ dig +short MX pouzenc.fr
10 mail.pouzenc.fr.
# Le MX de pouzenc.fr est mail.pouzenc.fr
lpouzenc@lud-x200s:~$ dig +short A mail.pouzenc.fr
185.61.116.42
lpouzenc@lud-x200s:~$ dig +short AAAA mail.pouzenc.fr
lpouzenc@lud-x200s:~$
# mail.pouzenc.fr a pour IP 185.61.116.42 (et n'a pas d'IPv6)
# Test de mail depuis une IP autre que mail.pouzenc.fr vers le serveur mail de CHD :
lpouzenc@lud-x200s:~$ swaks --to sympa@chd.sx --from ludovic@pouzenc.fr
=== Trying chd-tls1.chd.sx:25...
=== Connected to chd-tls1.chd.sx.
<- 220 chd-tls1.chd.sx ESMTP Exim 4.84_2 Sun, 10 Sep 2017 10:13:57 +0200
-> EHLO lud-x200s
<- 250-chd-tls1.chd.sx Hello 40-128.ipv4.commingeshautdebit.fr [185.131.40.128]
<- 250-SIZE 52428800
<- 250-8BITMIME
<- 250-PIPELINING
<- 250 HELP
-> MAIL FROM:
<- 250 OK
-> RCPT TO:
<- 250 Accepted
-> DATA
<- 354 Enter message, ending with "." on a line by itself
-> Date: Sun, 10 Sep 2017 10:13:57 +0200
-> To: sympa@chd.sx
-> From: ludovic@pouzenc.fr
-> Subject: test Sun, 10 Sep 2017 10:13:57 +0200
-> X-Mailer: swaks v20130209.0 jetmore.org/john/code/swaks/
->
-> This is a test mailing
->
-> .
<- 250 OK id=1dqxNN-0006et-Bo
-> QUIT
<- 221 chd-tls1.chd.sx closing connection
=== Connection closed with remote host.
# Le mail a été accepté.
apt-get install spf-tools-perl
cd /etc/exim4/conf.d
editor main/00_exim4-localmacros # Nouveau fichier, attention le début du nom est significatif
CHECK_RCPT_POSTMASTER = true # Ne jamais bloquer de mail destiné à postmaster
CHECK_RCPT_SPF = true
update-exim4.conf
# Vérifier que la directive a bien été prise en compte dans la configuration générée
grep RCPT_SPF /var/lib/exim4/config.autogenerated
# CHECK_RCPT_SPF = true
# .ifdef CHECK_RCPT_SPF
service exim4 reload
# Test de mail depuis une IP autre que mail.pouzenc.fr vers le serveur mail de CHD :
lpouzenc@lud-x200s:~$ swaks --to sympa@chd.sx --from ludovic@pouzenc.fr
=== Trying chd-tls1.chd.sx:25...
=== Connected to chd-tls1.chd.sx.
<- 220 chd-tls1.chd.sx ESMTP Exim 4.84_2 Sun, 10 Sep 2017 10:25:55 +0200
-> EHLO lud-x200s
<- 250-chd-tls1.chd.sx Hello 40-128.ipv4.commingeshautdebit.fr [185.131.40.128]
<- 250-SIZE 52428800
<- 250-8BITMIME
<- 250-PIPELINING
<- 250 HELP
-> MAIL FROM:
<- 250 OK
-> RCPT TO:
<** 550-[SPF] 185.131.40.128 is not allowed to send mail from pouzenc.fr. Please
<** 550 see http://www.openspf.org/Why?scope=mfrom;identity=ludovic@pouzenc.fr;ip=185.131.40.128
-> QUIT
<- 221 chd-tls1.chd.sx closing connection
=== Connection closed with remote host.
=== Reverse DNS destinataire ===
=== DNS Blacklist ===
On peut demander à exim de consulter une liste noire (du pt de vue du spam) d'IP et de domaines d'où proviennent les mails entrants. Ajoute un entête X-Warning dans le mail en question (cf ''acl/30_exim4-config_check_rcpt'').
cd /etc/exim4/conf.d
editor main/00_exim4-localmacros
#Ajouter 2 lignes
CHECK_RCPT_IP_DNSBLS = zen.spamhaus.org
CHECK_RCPT_DOMAIN_DNSBLS = dbl.spamhaus.org/$sender_address_domain
Provoquer un test par un robot dont l'IP est blacklistée (il suffit de lui envoyer un mail pour qu'il vienne en retour faire un test)
tail -f /var/log/exim4/mainlog &
mail -s test nelson-sbl-test@crynwr.com
Subject: test
CC:
# Attendre un peu
# kill %1 # tue le tail
L'admin du serveur mail aura une copie du message de test + un rapport de test. Dans le mail de test, un header doit s'être ajouté :
X-Warning: 192.203.178.107 is listed at zen.spamhaus.org (127.0.0.2: https://www.spamhaus.org/sbl/query/SBL230)
Pour bloquer purement et simplement, modifier "warn" par "deny" dans le block .ifdef CHECK_RCPT_IP_DNSBLS
editor ./acl/30_exim4-config_check_rcpt
Pour tester la blacklist par domaines, laisser la configuration en "warn" puis lancer un mail de test depuis une machine de test :
swaks --to sympa@chd.sx --from ludovic@dbltest.com
Dans le log, on doit voir :
2017-09-10 11:11:09 H=40-128.ipv4.commingeshautdebit.fr (lud-x200s) [185.131.40.128] Warning: dbltest.com is listed at dbl.spamhaus.org (127.0.1.2: https://www.spamhaus.org/query/domain/dbltest.com)
Passer en deny dans la config
editor ./acl/30_exim4-config_check_rcpt
[...]
.ifdef CHECK_RCPT_DOMAIN_DNSBLS
deny # <-- mettre deny plutôt que warn
!senders = ${if exists{CONFDIR/local_domain_dnsbl_whitelist}\
{CONFDIR/local_domain_dnsbl_whitelist}\
{}}
# Noter qu'on peut mettre un fichier de config pour dé-blacklister manuellement des domaines listés dans la blacklist
[...]
=== SpamAssassin ===
apt-get install spamassassin perl-doc
systemctl enable spamassassin.service
editor ./main/02_exim4-config_options
# décommenter la ligne suivante
# spamd_address = 127.0.0.1 783
editor ./acl/40_exim4-config_check_data
# Ajouter après l'exemple de spam =...
[...]
# http://www.exim.org/exim-html-current/doc/html/spec_html/ch44.html
deny
# Ne pas scanner les mails de + de 50k
condition = ${if < {$message_size}{50K}}
# Pas de profilage par utilisateur, laisser passer si spamassassin est en panne
spam = debian-spamd/defer_ok
message = This message was detected as spam ($spam_score).
[...]
perldoc Mail::SpamAssassin::Conf
editor /etc/spamassassin/init.pre
# Commenter (car exim le fait avant)
# loadplugin Mail::SpamAssassin::Plugin::URIDNSBL
# loadplugin Mail::SpamAssassin::Plugin::SPF
editor /etc/spamassassin/v320.pre
# Décommenter
loadplugin Mail::SpamAssassin::Plugin::Shortcircuit
editor /etc/spamassassin/local.cf
# Décommenter et modifier
# required_score 8.0
# Décommenter 3 lignes :
# shortcircuit USER_IN_WHITELIST on
# shortcircuit USER_IN_BLACKLIST on
# shortcircuit USER_IN_BLACKLIST_TO on
# ajouter :
# Exemple d'expéditeurs toujours considérés comme SPAM
blacklist_from spam@pouzenc.fr
# Exemple d'expéditeurs toujours considérés comme non-SPAM
whitelist_from *@pouzenc.fr
# Exemple de destinataire (enveloppe-to, To: Cc:... possiblement fake) toujours considéré comme SPAM
blacklist_to service@free.fr