1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
#!/bin/bash
# This file is part of Take It Easy Linux.
# Take It Easy Linux is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Take It Easy Linux is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with Take It Easy Linux. If not, see <https://www.gnu.org/licenses/>.
# Copyright © 2019 Ludovic Pouzenc <ludovic@pouzenc.fr>
# Fonctions utilitaires pour tracer, installer, télécharger, configurer
t() {
echo -n "[ ] ${BASH_LINENO[0]} $*"
out=$($* 2>&1)
if [ $? -eq 0 ]
then echo -e "\r[\e[32m OK \e[0m]"
else echo -e "\r[\e[1m\e[31mFAILED\e[0m]"
echo "$out"
fi
}
inst() {
touch /tmp/installed
if grep -q -- "$*" /tmp/installed
then echo 'Already installed'
else t apt-get install --quiet --yes $* && echo $* >> /tmp/installed
fi
}
get() {
filename=$1
baseurl=$2
if [ -f /tmp/$filename ]
then echo 'Already downloaded'
else t wget -O /tmp/$filename $baseurl/$filename
fi
}
link() {
target=$1
linkpath=$2
[ -L $linkpath ] || ln -sf $target $linkpath
}
confwrite() {
file=$1
[ -s $file ] && cp -a $file $file.tmp
cat > $file
if [ -f $file.tmp ]
then if diff -q $file $file.tmp
then rm $file.tmp
else mv $file.tmp $file.orig
fi
fi
}
confset() {
file=$1
conf_keyword=$2
conf_valuematch=$3
conf_newvalue=$4
sed --in-place -e 's#^\(\s*\)\#\?\(\s*'$conf_keyword'\s*[ =]\+\s*\)'$conf_valuematch'\(.*\)$#\1\2'$conf_newvalue'\3#' $file
}
confenable() {
file=$1
conf_keyword=$2
sed --in-place -e 's#^\(\s*\)\#\?\(\s*'$conf_keyword'\s*[ =]\+\s*'$conf_valuematch'.*\)$#\1\2#' $file
}
confappend() {
file=$1
shift
line=$*
grep -q -- "$line" $file || echo $line >> $file
}
# Vérifications d'environnement
if [ $UID -ne 0 ]
then echo "Ce script est prévu pour être lancé par root uniquement"
echo "Utilisez 'su -' ou 'sudo -i' pour obtenir un shell root"
exit 1
fi
# Paramètres détéectés et utilisés par la suite du script
set -x
host=$(hostname)
domain=$(dnsdomainname)
lang=${LANG%.*}
set +x
echo 'Saisissez un mot de passe admin pour le webmail et rspamd ou ctrl+C pour annuler'
read -rsp 'Password: ' adminpass
echo
# Ajout des dépôts nécessaires et les clés GPG pour valider les paquets reçus
t confwrite /etc/apt/sources.list.d/backports.list <<"EOT"
deb http://ftp.debian.org/debian stretch-backports main
EOT
t confwrite /etc/apt/sources.list.d/rspamd.list <<"EOT"
deb [arch=amd64] http://rspamd.com/apt-stable/ stretch main
EOT
t get gpg.key https://rspamd.com/apt-stable
t apt-key add /tmp/gpg.key
# Prise en compte des nouveaux dépots
t apt-get update
# Préremplissage des questions posées à l'installation de certains paquets
t debconf-set-selections <<"EOT"
exim4-config exim4/dc_eximconfig_configtype select internet site; mail is sent and received directly using SMTP
exim4-config exim4/use_split_config boolean true
EOT
# Installation des paquets nécessaires
# Obtention de certificat TLS gratuits
t inst -t stretch-backports python-certbot-apache
# Redis utilisé par rainloop et rspamd (et la version 3 buggue avec rspam, "127.0.0.1: connection refusée")
t inst -t stretch-backports redis-server
# Programmes pour traiter et stocker les mails
t inst dovecot-lmtpd dovecot-imapd dovecot-sieve dovecot-managesieved exim4-daemon-heavy rspamd clamav-daemon
# Prérequis webmail RainLoop
t inst libapache2-mod-php php-curl php-iconv php-sqlite3 php-xml unzip
# Système, sécurité, monitoring
t inst apachetop fail2ban munin-node liblwp-useragent-determined-perl
read -t10 -p 'Installation de paquets terminée, configuration dans 10 secondes (ctrl+C pour annuler)' garbage
echo
# Configuration munin-node
rm /etc/munin/plugins/ntp_kernel_* 2>/dev/null
t link /usr/share/munin/plugins/netstat /etc/munin/plugins/
t link /usr/share/munin/plugins/apache_accesses /etc/munin/plugins/
t link /usr/share/munin/plugins/apache_processes /etc/munin/plugins/
t link /usr/share/munin/plugins/apache_volume /etc/munin/plugins/
t service munin-node restart
# Configuration redis (base de données mémoire simple pour webmail et rspamd)
t confset /etc/redis/redis.conf maxmemory '<bytes>' 500mb
t confset /etc/redis/redis.conf maxmemory-policy 'noeviction' volatile-ttl
t confwrite /etc/sysctl.d/50-redis-overcommit_memory.conf <<"EOT"
vm.overcommit_memory = 1
EOT
echo 1 > /proc/sys/vm/overcommit_memory
t service redis-server restart
# Configuration apache2 (serveur web)
t confset /etc/apache2/mods-enabled/mpm_prefork.conf MaxRequestWorkers '[0-9]\+' 20
t confwrite /etc/apache2/sites-available/000-default.conf <<EOT
<VirtualHost *:80>
ServerAdmin postmaster@$domain
DocumentRoot /var/www/html
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
# Gère les redirections depuis http vers https sur le nom canonique
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/
RewriteRule ^/(.*) https://$host.$domain/\$1 [L,R=301]
</IfModule>
# Accepte les requêtes challenge LetsEncrypt
<Directory /var/www/html/.well-known/acme-challenge>
Options None
AllowOverride None
Require all granted
</Directory>
# Ne pas publier les données du webmail (si mod_rewrite n'est pas actif)
<Directory /var/www/html/webmail/data>
Options None
AllowOverride None
Require all denied
</Directory>
</VirtualHost>
EOT
t confwrite /etc/apache2/sites-available/default-ssl.conf <<EOT
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin postmaster@$domain
ServerName $host.$domain
DocumentRoot /var/www/html
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
<Directory /var/www/html>
Options None
AllowOverride None
Require all granted
</Directory>
# Ne pas publier les données du webmail
<Directory /var/www/html/webmail/data>
Options None
AllowOverride None
Require all denied
</Directory>
# Renvoi par défaut sur le webmail et (spam,rspamd) -> rspamd/
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^/$ https://$host.$domain/webmail/ [L,R=302]
RewriteRule ^/spam$ https://$host.$domain/rspamd/ [L,R=302]
RewriteRule ^/rspamd$ https://$host.$domain/rspamd/ [L,R=302]
</IfModule>
# Exposer l'interface de rspamd en https
<IfModule mod_proxy_http.c>
ProxyPass /rspamd/ http://127.0.0.1:11334/
ProxyPassReverse /rspamd/ http://127.0.0.1:11334/
ProxyRequests Off
</IfModule>
# Paramètres TLS de LetsEncrypt
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/$domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/$domain/privkey.pem
</VirtualHost>
</IfModule>
EOT
t a2enmod proxy_http rewrite ssl
t a2ensite default-ssl
t confset /etc/php/7.0/apache2/php.ini upload_max_filesize '[0-9M]\+' 26M
t confset /etc/php/7.0/apache2/php.ini post_max_size '[0-9M]\+' 30M
# Pré-configuration certificats TLS (initialement : auto-signés, mais prêt pour LetsEncrypt)
t mkdir -p /etc/letsencrypt/live/$domain/
t cp -a /usr/lib/python3/dist-packages/certbot_apache/options-ssl-apache.conf /etc/letsencrypt/
t link /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/letsencrypt/live/$domain/fullchain.pem
t link /etc/ssl/private/ssl-cert-snakeoil.key /etc/letsencrypt/live/$domain/privkey.pem
t service apache2 restart
# Déploiement webmail RainLoop
t get rainloop-community-latest.zip https://www.rainloop.net/repository/webmail
t mkdir -p /var/www/html/webmail
t unzip -qnd /var/www/html/webmail /tmp/rainloop-community-latest.zip
t chown -R root: /var/www/html/webmail
t mkdir -p /var/www/html/webmail/data/_data_/_default_/logs/fail2ban/
t touch /var/www/html/webmail/data/_data_/_default_/logs/fail2ban/auth-empty.txt
# Configuration webmail Rainloop
t php -- "$domain" "$lang" "$adminpass" "(autoconfig webmail)" <<"EOT"
<?php
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
include '/var/www/html/webmail/index.php';
$oConfig = \RainLoop\Api::Config();
$oConfig->Set('webmail', 'title', 'Webmail ' . $argv[1]);
$oConfig->Set('webmail', 'language', $argv[2]);
$oConfig->Set('webmail', 'attachment_size_limit', 25);
$oConfig->Set('contacts', 'enable', 'On');
$oConfig->SetPassword($argv[3]);
$oConfig->Set('login', 'default_domain', $argv[1]);
$oConfig->Set('logs', 'enable', 'On');
$oConfig->Set('logs', 'write_on_error_only', 'On');
$oConfig->Set('logs', 'filename', 'syslog');
$oConfig->Set('logs', 'auth_logging', 'On');
$oConfig->Set('cache', 'fast_cache_driver', 'redis');
echo 'Config ' . ( $oConfig->Save() ? 'Saved' : 'Error') . "\n";
?>
EOT
t confwrite /var/www/html/webmail/data/_data_/_default_/domains/$domain.ini <<EOT
imap_host = "localhost"
imap_port = 143
imap_secure = "TLS"
imap_short_login = Off
sieve_use = On
sieve_allow_raw = Off
sieve_host = "localhost"
sieve_port = 4190
sieve_secure = "TLS"
smtp_host = "localhost"
smtp_port = 587
smtp_secure = "TLS"
smtp_short_login = Off
smtp_auth = On
smtp_php_mail = Off
white_list = ""
EOT
t chown -R www-data: /var/www/html/webmail/data
t chmod -R o= /var/www/html/webmail/data
t confwrite /etc/cron.daily/rainloop-auth-log-purge.sh <<"EOT"
#!/bin/sh
find /var/www/html/webmail/data/_data_/_default_/logs/fail2ban/ -type f -mtime +365 -print0 | xargs -r0 rm
EOT
chmod +x /etc/cron.daily/rainloop-auth-log-purge.sh
t link /var/www/html/webmail/data/_data_/_default_/logs/fail2ban/ /var/log/rainloop-fail2ban
t link /var/www/html/webmail/data/_data_/_default_/ /etc/rainloop
# Configuration fail2ban (auto-bannir les IP qui essayent des mots de passes sur le webmail)
t confwrite /etc/fail2ban/filter.d/rainloop.conf <<"EOT"
[Definition]
failregex = : Auth failed: ip=<HOST> user=.* host=.* port=.*$
ignoreregex =
EOT
t confwrite /etc/fail2ban/jail.local <<"EOT"
[rainloop]
enabled = true
banaction = iptables-multiport
filter = rainloop
port = http,https
logpath = /var/www/html/webmail/data/_data_/_default_/logs/fail2ban/auth-*.txt
maxretry = 5
findtime = 1500
bantime = 900
EOT
t service fail2ban restart
# Configuration Dovecot (serveur IMAP de consultation mail, filtres sieve)
t confset /etc/dovecot/dovecot.conf verbose_proctitle '[a-z]\+' yes
t confset /etc/dovecot/conf.d/10-auth.conf disable_plaintext_auth '[a-z]\+' yes
t confset /etc/dovecot/conf.d/10-auth.conf auth_username_format '[%A-Za-z]\+' '%Ln'
t confenable /etc/dovecot/conf.d/10-logging.conf mail_log_events '\S\+'
t confenable /etc/dovecot/conf.d/10-logging.conf mail_log_fields '\S\+'
t confset /etc/dovecot/conf.d/10-mail.conf mail_location '\S\+' 'mdbox:~/mail'
t confset /etc/dovecot/conf.d/10-ssl.conf ssl 'no' required
t confset /etc/dovecot/conf.d/10-ssl.conf ssl_cert '[a-z/<.]\+' "</etc/letsencrypt/live/$domain/fullchain.pem"
t confset /etc/dovecot/conf.d/10-ssl.conf ssl_key '[a-z/<.]\+' "</etc/letsencrypt/live/$domain/privkey.pem"
t confwrite /etc/dovecot/conf.d/10-master.local.conf <<"EOT"
service auth {
unix_listener auth-client {
mode = 0660
group = Debian-exim
}
}
EOT
t confwrite /etc/dovecot/conf.d/20-lmtp.conf <<"EOT"
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
EOT
t confwrite /etc/dovecot/conf.d/20-managesieve.conf <<"EOT"
protocols = $protocols sieve
service managesieve-login {
inet_listener sieve {
}
}
service managesieve {
process_limit = 16
}
protocol sieve {
}
EOT
t confset /etc/dovecot/conf.d/90-sieve.conf sieve_before '\S\+' /etc/dovecot/sieve-global/before.d
mkdir -p /etc/dovecot/sieve-global/before.d
t confwrite /etc/dovecot/sieve-global/before.d/spam-into-junk.sieve <<"EOT"
require ["fileinto"];
if header :is "X-Spam" "Yes" {
fileinto "Junk";
stop;
}
EOT
t sievec /etc/dovecot/sieve-global/before.d/spam-into-junk.sieve
t service dovecot restart
# Configuration rspamd (anti-spam qui appelle l'antivirus ClamAV)
t confwrite /etc/rspamd/local.d/redis.conf <<"EOT"
write_servers = "localhost";
read_servers = "localhost";
EOT
t confwrite /etc/rspamd/local.d/classifier-bayes.conf <<"EOT"
backend = "redis";
new_schema = true;
expire = 8640000;
autolearn = true
EOT
t confwrite /etc/rspamd/local.d/antivirus.conf <<"EOT"
clamav {
servers = "/var/run/clamav/clamd.ctl";
}
EOT
t confwrite /etc/rspamd/local.d/worker-controller.inc <<EOT
password = "$(rspamadm pw -p $adminpass | grep '^\$')";
EOT
t service clamav-daemon restart
t service rspamd restart
# Configuration exim4 (serveur de mail, MTA, connecté à dovecot et rspamd)
t confwrite /etc/exim4/exim4.conf.template <<"EOT"
# This file is NOT used by exim because of :
# dc_use_split_config='true' (in update-exim4.conf.conf)
#
# See conf.d folder
# use "update-exim4.conf" command before "service exim4 reload"
EOT
t confappend /etc/default/exim4 "SMTPLISTENEROPTIONS='-oX 25:587 -oP /run/exim4/exim.pid'"
t adduser Debian-exim ssl-cert
t confwrite /etc/exim4/local_macros.conf <<EOT
# acl/30_exim4-config_check_rcpt
CHECK_RCPT_VERIFY_SENDER = yes
# acl/40_exim4-config_check_data
CHECK_DATA_VERIFY_HEADER_SYNTAX = yes
CHECK_DATA_VERIFY_HEADER_SENDER = yes
# main/02_exim4-config_options
MESSAGE_SIZE_LIMIT = 25M
MAIN_HARDCODE_PRIMARY_HOSTNAME=$domain
MAIN_SPAMD_ADDRESS = 127.0.0.1 11333 variant=rspamd
# main/03_exim4-config_tlsoptions
MAIN_TLS_ENABLE = yes
MAIN_TLS_CERTIFICATE = /etc/letsencrypt/live/$domain/fullchain.pem
MAIN_TLS_PRIVATEKEY = /etc/letsencrypt/live/$domain/privkey.pem
# router/900_exim4-config_local_user
LOCAL_DELIVERY = dovecot_lmtp
EOT
t link /etc/exim4/local_macros.conf /etc/exim4/conf.d/main/00_local_macros
t confwrite /etc/exim4/conf.d/acl/40_exim4-config_check_data <<"EOT"
### acl/40_exim4-config_check_data
#################################
# This ACL is used after the contents of a message have been received. This
# is the ACL in which you can test a message's headers or body, and in
# particular, this is where you can invoke external virus or spam scanners.
acl_check_data:
# Deny if the message contains an overlong line. Per the standards
# we should never receive one such via SMTP.
#
.ifndef IGNORE_SMTP_LINE_LENGTH_LIMIT
deny message = maximum allowed line length is 998 octets, \
got $max_received_linelength
condition = ${if > {$max_received_linelength}{998}}
.endif
# Deny unless the address list headers are syntactically correct.
#
# If you enable this, you might reject legitimate mail.
.ifdef CHECK_DATA_VERIFY_HEADER_SYNTAX
deny
message = Message headers fail syntax check
!acl = acl_local_deny_exceptions
!verify = header_syntax
.endif
# require that there is a verifiable sender address in at least
# one of the "Sender:", "Reply-To:", or "From:" header lines.
.ifdef CHECK_DATA_VERIFY_HEADER_SENDER
deny
message = No verifiable sender address in message headers
!acl = acl_local_deny_exceptions
!verify = header_sender
.endif
# Deny if the message contains malware. Before enabling this check, you
# must install a virus scanner and set the av_scanner option in the
# main configuration.
#
# exim4-daemon-heavy must be used for this section to work.
#
# deny
# malware = *
# message = This message was detected as possible malware ($malware_name).
# Actually scan message agaist spam (and malware trough rspamd)
warn
logwrite = spam-check: starting
spam = Debian-exim:true
logwrite = spam-check: ending
# Defer message if spam scanner is not available
defer
condition = ${if eq{$spam_action}{}}
message = Please try again later, spam scanner unavailable
# FROM https://rspamd.com/doc/integration.html (+custom rule for classfied as virus)
# use greylisting available in rspamd v1.3+
defer message = Please try again later
condition = ${if eq{$spam_action}{soft reject}}
# Reject message that have classified as virus
deny message = Message classified as virus
condition = ${if and { { eq{$spam_action}{reject} } { match {$spam_report}{CLAM_VIRUS} } } }
# Reject message that have high-probability to be spam
deny message = Message classified as spam
condition = ${if eq{$spam_action}{reject}}
# Remove foreign headers
warn
remove_header = x-spam-bar : x-spam-score : x-spam-report : x-spam-status
# add spam-score and spam-report header when "add header" action is recommended by rspamd
warn
condition = ${if eq{$spam_action}{add header}}
add_header = X-Spam-Score: $spam_score ($spam_bar)
add_header = X-Spam-Report: $spam_report
# add x-spam-status header if message is not ham
warn
! condition = ${if match{$spam_action}{^no action\$|^greylist\$}}
add_header = X-Spam-Status: Yes
# This hook allows you to hook in your own ACLs without having to
# modify this file. If you do it like we suggest, you'll end up with
# a small performance penalty since there is an additional file being
# accessed. This doesn't happen if you leave the macro unset.
.ifdef CHECK_DATA_LOCAL_ACL_FILE
.include CHECK_DATA_LOCAL_ACL_FILE
.endif
# accept otherwise
accept
EOT
t confwrite /etc/exim4/conf.d/auth/50_dovecot_auth <<"EOT"
dovecot_authplain:
driver = dovecot
public_name = PLAIN
server_advertise_condition = ${if def:tls_cipher}
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth1
EOT
t confwrite /etc/exim4/conf.d/transport/50_dovecot_lmtp <<"EOT"
dovecot_lmtp:
driver = lmtp
socket = /var/run/dovecot/lmtp
#maximum number of deliveries per batch, default 1
batch_max = 200
#allow suffixes/prefixes (default unset)
rcpt_include_affixes
EOT
t confset /etc/exim4/conf.d/main/02_exim4-config_options spamd_address '\S\+\s[0-9]\+' MAIN_SPAMD_ADDRESS
t service exim4 restart
# Afficher un texte explicatif en fin d'exécution
iface=$(ip -o r | sed -ne 's/^default .* dev \(\S\+\).*$/\1/p')
ip=$(ip -o a s dev $iface | sed -ne 's/^.*inet \([0-9.]\+\).*/\1/p')
cat <<EOT
Le script a terminé son exécution. Tout devrait être en "OK", sinon, voir le numéro de ligne indiqué dans le script.
(Pour remonter dans le terminal, utiliser Shift + PageUp)
Les certificats TLS sont prévus avec LetsEncrypt mais n'est pas lancé par ce script.
Pré-requis : le serveur soit joignable depuis internet avec son DNS public (celui retourné par hostname --fqdn).
Pour obtenir les certificats, lancer :
# certbot --apache certonly
Pour ajouter des utilisateurs / boites mails utilisez :
adduser <login>
URL mises en place :
https://$host.$domain/webmail/
https://$host.$domain/webmail/?admin
https://$host.$domain/rspamd/
Il est possible d'utiliser l'IP aussi (si le DNS n'est pas configuré)
https://$ip/webmail/
EOT
|