8 views
# Installation du serveur yeswiki.pro On est connecté en tant que root, une petite mise en bouche ``` apt update apt upgrade -y dpkg-reconfigure locales # cocher fr_fr.UTF8 et en_US.UTF8, puis en_US.UTF8 par défaut apt install tree curl wget htop vim parted mc lshw git tmux -y # quelques paquets essentiels cd /usr/local/bin ;curl https://getmic.ro | bash # un editeur de texte sympa ``` On met le bon host `sudo hostnamectl set-hostname yeswiki.pro --static` `sudo vim /etc/hosts` mettre `yeswiki.pro` pour les ip4 et ip6 `reboot` ## Config disques RAID software `lshw -class disk -short` donne : ``` H/W path Device Class Description ====================================================== /0/100/1f.2/0 /dev/sda disk 480GB SAMSUNG MZ7LM480 /0/100/1f.2/1 /dev/sdb disk 480GB SAMSUNG MZ7LM480 /0/100/1f.2/2 /dev/sdc disk 6001GB HGST HUS726060AL /0/100/1f.2/3 /dev/sdd disk 6001GB HGST HUS726060AL ``` Oh surprise d'Hetzner ``` root@yeswiki ~ # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 447.1G 0 disk ├─sda1 8:1 0 4G 0 part │ └─md0 9:0 0 4G 0 raid1 [SWAP] ├─sda2 8:2 0 1G 0 part │ └─md1 9:1 0 1022M 0 raid1 /boot └─sda3 8:3 0 442.1G 0 part └─md2 9:2 0 442G 0 raid1 / sdb 8:16 0 447.1G 0 disk ├─sdb1 8:17 0 4G 0 part │ └─md0 9:0 0 4G 0 raid1 [SWAP] ├─sdb2 8:18 0 1G 0 part │ └─md1 9:1 0 1022M 0 raid1 /boot └─sdb3 8:19 0 442.1G 0 part └─md2 9:2 0 442G 0 raid1 / sdc 8:32 0 5.5T 0 disk ├─sdc1 8:33 0 4G 0 part │ └─md0 9:0 0 4G 0 raid1 [SWAP] ├─sdc2 8:34 0 1G 0 part │ └─md1 9:1 0 1022M 0 raid1 /boot └─sdc3 8:35 0 442.1G 0 part └─md2 9:2 0 442G 0 raid1 / sdd 8:48 0 5.5T 0 disk ├─sdd1 8:49 0 4G 0 part │ └─md0 9:0 0 4G 0 raid1 [SWAP] ├─sdd2 8:50 0 1G 0 part │ └─md1 9:1 0 1022M 0 raid1 /boot └─sdd3 8:51 0 442.1G 0 part └─md2 9:2 0 442G 0 raid1 / ``` ### Réparation de la config d'Hetzner qui fait un RAID 1 sur 4 disques... ``` mdadm --detail /dev/md0 # pour voir les infos détaillées mdadm --manage /dev/md0 --fail /dev/sdc1 mdadm --manage /dev/md0 --fail /dev/sdd1 mdadm --manage /dev/md0 --remove /dev/sdc1 mdadm --manage /dev/md0 --remove /dev/sdd1 mdadm --grow /dev/md0 --raid-devices=2 mdadm --manage /dev/md1 --fail /dev/sdc2 mdadm --manage /dev/md1 --fail /dev/sdd2 mdadm --manage /dev/md1 --remove /dev/sdc2 mdadm --manage /dev/md1 --remove /dev/sdd2 mdadm --grow /dev/md1 --raid-devices=2 mdadm --manage /dev/md2 --fail /dev/sdc3 mdadm --manage /dev/md2 --fail /dev/sdd3 mdadm --manage /dev/md2 --remove /dev/sdc3 mdadm --manage /dev/md2 --remove /dev/sdd3 mdadm --grow /dev/md2 --raid-devices=2 ``` On fait une grosse partition pour les homes, prete pour du RAID 1, et en ext4 ``` parted -a optimal /dev/sdc mklabel gpt parted -a optimal /dev/sdd mklabel gpt parted -a optimal /dev/sdc mkpart primary ext4 0% 100% parted -a optimal /dev/sdd mkpart primary ext4 0% 100% parted -a optimal /dev/sdc set 1 raid on parted -a optimal /dev/sdd set 1 raid on mdadm --create /dev/md4 --level=1 --raid-devices=2 /dev/sd[cd]1 mkfs.ext4 /dev/md4 mount /dev/md4 /home ``` `vi /etc/fstab` ``` /dev/md4 /home ext4 defaults 0 0 ``` On sauve la conf `mdadm --detail --scan >> /etc/mdadm/mdadm.conf` Mise à jour filesystem `update-initramfs -u` Checker `cat /proc/mdstat` `update-grub2` ## Sécurité ### SSH `apt install sudo openssh-server -y` on change de mot de passe root `passwd` on crée le user admin avec les droits sudo ``` adduser admin # ajouter un user admin usermod -a -G sudo admin # ajouter le user admin au groupe sudo ``` on met les clés publiques de personnes ayant un droit d'acces au compte admin `vi /home/admin/.ssh/authorized_keys` on configure ssh pour interdire l'acces root, n'autoriser que l'acces par clé ssh, et on change de port ssh standard par 4222 `vi /etc/ssh/sshd_config` ``` Port 4222 PermitRootLogin no MaxAuthTries 3 PasswordAuthentication no PubkeyAuthentication yes X11Forwarding no ``` On redémarrer le service pour prendre en compte les changements `service sshd restart` ### Firewall `apt install ufw -y` on n'autorise que les ports web 80 443 et ssh 4222 ``` ufw allow 80 #http ufw allow 443 #https ufw allow 4222 #ssh ufw enable # demarre le service ufw logging on # garde les logs ufw status verbose #infos precises ``` ### Fail2ban `apt install fail2ban sendmail-bin sendmail -y` `cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local` `vi /etc/fail2ban/jail.local` ``` bantime = 720m findtime = 120m maxretry = 3 banaction = ufw banaction_allports = ufw destemail = contact@yeswiki.pro sender = fail2ban@yeswiki.pro ``` On relance le service `fail2ban-client reload` ### Quota système pour les users cf. <https://wiki.archlinux.org/title/Disk_quota> et <https://www.drydeadfish.co.uk/linux_disk_quotas/> `apt install quota -y` `vi /etc/fstab` ``` # /dev/md/4 /dev/md4 /home ext4 defaults,usrjquota=quota.user,grpjquota=quota.group,jqfmt=vfsv0 0 0 ``` `mount -o remount /home` `quotacheck -cgum /home` `quotaon /home` pour mémoire, vue d'ensemble des quatos : `repquota -a` pour 2Go de quota pour le user toto `setquota -u toto 2000000 2000000 0 0 -a /dev/loop0` > ask mose if ca fait grincer les dents ## Install lemp server `apt-get install apt-transport-https gnupg2 ca-certificates -y` le dépot Sury permet d'avoir des versions récentes de php et de multiples versions `wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'` `apt-get update -y` `apt-get install nginx mariadb-server mariadb-client php php-cli php-curl php-common php-mysql php-xml php-gd php8.1-opcache php-fpm php-mbstring php-tokenizer php-json php-mcrypt php-imagick php-bcmath php-zip wget unzip curl -y` ### Configurer Nginx cf. <https://github.com/h5bp/server-configs-nginx> : un ensemble de bonnes pratiques de configuration de nginx ``` service nginx stop cd /etc mv nginx nginx-origin git clone https://github.com/h5bp/server-configs-nginx.git nginx service nginx start ``` on change le fichier des certificats de base pour yeswiki.pro `vi /etc/nginx/h5bp/tls/certificate_files.conf` ``` ssl_certificate /etc/letsencrypt/live/yeswiki.pro/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yeswiki.pro/key.pem; ssl_trusted_certificate /etc/letsencrypt/live/yeswiki.pro/ca.pem; ``` On crée un template nginx de base pour les domaines en "domaine.yeswiki.pro" `vi /etc/nginx/conf.d/templates/domain.yeswiki.pro.conf` ``` # ---------------------------------------------------------------------- # | Config file for example.com host | # ---------------------------------------------------------------------- server { listen [::]:80; listen 80; server_name example.com www.example.com; return 301 https://example.com$request_uri; } server { listen [::]:443 ssl http2; listen 443 ssl http2; server_name www.example.com; include h5bp/tls/ssl_engine.conf; include h5bp/tls/certificate_files.conf; include h5bp/tls/policy_strict.conf; return 301 $scheme://example.com$request_uri; } server { # listen [::]:443 ssl http2 accept_filter=dataready; # for FreeBSD # listen 443 ssl http2 accept_filter=dataready; # for FreeBSD listen [::]:443 ssl http2; listen 443 ssl http2; # The host name to respond to server_name example.com; include h5bp/tls/ssl_engine.conf; include h5bp/tls/certificate_files.conf; include h5bp/tls/policy_strict.conf; # Path for static files root /home/userexample/example.com; # Custom error pages include h5bp/errors/custom_errors.conf; # Include the basic h5bp config set include h5bp/basic.conf; access_log /var/log/nginx/example.com-access.log; error_log /var/log/nginx/example.com-error.log error; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php-fpm-userexample.sock; fastcgi_index index.php; include fastcgi.conf; } } ``` tweak nginx.conf keepalive_timeout 40s; client_max_body_size 1G; acme.sh pour les certificats ssl infos cf. <https://kb.virtubox.net/knowledgebase/how-to-issue-wildcard-ssl-certificate-with-acme-sh-nginx/> `curl https://get.acme.sh | sh -s email=contact@yeswiki.pro` puis sortir de la session bash et revenir pour avoir acces à la commande bash un certificat wildcard `acme.sh --issue -d yeswiki.pro -d *.yeswiki.pro --dns -k ec-384 \ --yes-I-know-dns-manual-mode-enough-go-ahead-please ` mettre les 2 entrées DNS txt demandées pour la domaine TODO: automatiser avec l'API Gandi <https://github.com/acmesh-official/acme.sh/wiki/dnsapi#18-use-gandi-livedns-api> `acme.sh --renew -d yeswiki.pro \ --yes-I-know-dns-manual-mode-enough-go-ahead-please --ecc --force ` On converti en certificats utilisables pour nginx `mkdir -p /etc/letsencrypt/live/yeswiki.pro` `acme.sh --install-cert -d yeswiki.pro --ecc \ --cert-file /etc/letsencrypt/live/yeswiki.pro/cert.pem \ --key-file /etc/letsencrypt/live/yeswiki.pro/key.pem \ --fullchain-file /etc/letsencrypt/live/yeswiki.pro/fullchain.pem \ --ca-file /etc/letsencrypt/live/yeswiki.pro/ca.pem \ --reloadcmd "systemctl restart nginx.service"` pour installer un nouveau site ``` cd /etc/nginx/conf.d/ cp templates/domain.yeswiki.pro.conf <mondomaine.ext>.conf sed -i 's/example.com/<mondomaine.ext>/g' <mondomaine.ext>.conf sed -i 's/userexample/<monuser>/g' <mondomaine.ext>.conf service nginx reload ``` pour désactiver un site, il faut mettre un point devant le nom du site ``` cd /etc/nginx/conf.d/ cp <mondomaine.ext>.conf .<mondomaine.ext>.conf # cf le point . devant service nginx reload ``` ### Configurer php `vi /etc/php/8.1/fpm/php.ini` changer : ``` cgi.fix_pathinfo=0 date.timezone = Europe/Paris max_execution_time = 90 max_input_time = 90 max_input_vars = 10000 upload_max_filesize = 1G post_max_size = 1G memory_limit = 1G ``` On redémarre le service pour prendre en compte les changements `service php8.1-fpm restart` Ajout de composer ``` php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" php composer-setup.php php -r "unlink('composer-setup.php');" sudo mv composer.phar /usr/local/bin/composer ``` ### Tuning mariadb `mysql_secure_installation` empècher l'acces root depuis l'extérieur, passer en socket et virer les base et comptes de test. Augmenter la taille max des paquets mysql (pour matomo) `vi /etc/mysql/mariadb.conf.d/50-server.cnf` ``` [mysqld] max_allowed_packet = 1G # décommenter cette valeur ``` ### Installation de nodejs (pour yarn) ``` curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - apt-get install -y nodejs corepack enable # apparement suffirait pour yarn curl --compressed -o- -L https://yarnpkg.com/install.sh | bash ``` ### Installer phpmyadmin On ajoute un user pour cloisonner ``` groupadd phpmyadmin useradd -g phpmyadmin phpmyadmin ``` #### Installation de phpmyadmin dans /opt/phpmyadmin ``` cd /opt wget https://files.phpmyadmin.net/phpMyAdmin/5.2.0/phpMyAdmin-5.2.0-all-languages.zip unzip phpMyAdmin-5.2.0-all-languages.zip mv phpMyAdmin-5.2.0-all-languages phpmyadmin rm phpMyAdmin-5.2.0-all-languages.zip chown phpmyadmin:phpmyadmin phpmyadmin -R sudo -u phpmyadmin cp config.sample.inc.php config.inc.php vi config.inc.php # mettre une passphrase de 32 chars ``` #### Config php-fpm vi /etc/php/8.1/fpm/pool.d/phpmyadmin.conf ``` [phpmyadmin] user = phpmyadmin group = phpmyadmin listen = /var/run/php-fpm-phpmyadmin.sock listen.owner = www-data listen.group = www-data pm = dynamic pm.max_children = 75 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20 pm.process_idle_timeout = 10s ``` `service php8.1-fpm restart` #### Config nginx ``` cd /etc/nginx/conf.d/ cp templates/domain.yeswiki.pro.conf sql.yeswiki.pro.conf sed -i 's/example.com/sql.yeswiki.pro/g' sql.yeswiki.pro.conf sed -i 's/userexample/phpmyadmin/g' sql.yeswiki.pro.conf ## changer le root pour /opt/phpmyadmin au lieu de /home/phpmyadmin/sql.yeswiki.pro service nginx reload ``` ### Installer Matomo On ajoute un user pour cloisonner ``` groupadd matomo useradd -g matomo matomo ``` #### Installation de matomo dans /opt/matomo ``` cd /opt wget https://builds.matomo.org/matomo.zip unzip matomo.zip rm matomo.zip rm 'How to install Matomo.html' chown matomo:matomo matomo -R ``` #### Config php-fpm `vi /etc/php/8.1/fpm/pool.d/matomo.conf` ``` [matomo] user = matomo group = matomo listen = /var/run/php-fpm-matomo.sock listen.owner = www-data listen.group = www-data pm = dynamic pm.max_children = 75 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 20 pm.process_idle_timeout = 10s ``` `service php8.1-fpm restart` #### Config nginx ``` cd /etc/nginx/conf.d/ cp templates/domain.yeswiki.pro.conf stats.yeswiki.pro.conf sed -i 's/example.com/stats.yeswiki.pro/g' stats.yeswiki.pro.conf sed -i 's/userexample/matomo/g' stats.yeswiki.pro.conf ## changer le root pour /opt/matomo au lieu de /home/matomo/sql.yeswiki.pro ``` ajout de la config nginx recommandée <https://github.com/matomo-org/matomo-nginx#readme> ``` add_header Referrer-Policy origin always; # make sure outgoing links don't show the URL to the Matomo instance add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; ## only allow accessing the following php files location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs)\.php$ { include fastcgi.conf; try_files $fastcgi_script_name =404; # protects against CVE-2019-11043. If this line is already included in your snippets/fastcgi-php.conf you can comment it here. fastcgi_param HTTP_PROXY ""; # prohibit httpoxy: https://httpoxy.org/ fastcgi_pass unix:/var/run/php-fpm-matomo.sock; } ## deny access to all other .php files location ~* ^.+\.php$ { deny all; return 403; } ## serve all other files normally location / { try_files $uri $uri/ =404; } ## disable all access to the following directories location ~ ^/(config|tmp|core|lang) { deny all; return 403; # replace with 404 to not show these directories exist } location ~ /\.ht { deny all; return 403; } location ~ js/container_.*_preview\.js$ { expires off; add_header Cache-Control 'private, no-cache, no-store'; } location ~ \.(gif|ico|jpg|png|svg|js|css|htm|html|mp3|mp4|wav|ogg|avi|ttf|eot|woff|woff2|json)$ { allow all; ## Cache images,CSS,JS and webfonts for an hour ## Increasing the duration may improve the load-time, but may cause old files to show after an Matomo upgrade expires 1h; add_header Pragma public; add_header Cache-Control "public"; } location ~ ^/(libs|vendor|plugins|misc|node_modules) { deny all; return 403; } ## properly display textfiles in root directory location ~/(.*\.md|LEGALNOTICE|LICENSE) { default_type text/plain; } ``` `service nginx reload` #### Config DB `mysql -u root -p` ``` CREATE USER 'matomo'@'localhost' IDENTIFIED BY '<mot de passe>'; GRANT CREATE, ALTER, DROP, INSERT, UPDATE, DELETE, SELECT ON matomo.* TO 'matomo'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES; ``` > Suivre l'installateur depuis <https://stats.yeswiki.pro> #### Config matomo force ssl `vi /opt/matomo/config/config.ini.php` ``` [General] force_ssl = 1 ``` Cron `touch /var/log/matomo-archive.log` `chown matomo:matomo /var/log/matomo-archive.log` `vi /etc/cron.d/matomo-archive` ``` MAILTO="contact@yeswiki.pro" 5 * * * * matomo /usr/bin/php /opt/matomo/console core:archive --url=http://stats.yeswiki.pro/ > /var/log/matomo-archive.log ``` ### Application qui genere les yeswiki On ajoute la source pour tous les wikis dans /opt/yeswiki , avec git histoire de pouvoir changer de version facilement ``` cd /opt/ git clone https://github.com/YesWiki/yeswiki.git cd yeswiki git checkout tags/v4.2.4 # derniere version de production make install ``` https://codeberg.org/YesWiki-Pro/yeswiki-installer ### Backup MYSQL local cf. https://tzanalastuce.com/automysqlbackup-sauvegarde-automatique-dune-base-de-donnees-mariadb-ou-mysql/ ``` apt install automysqlbackup -y vi /etc/default/automysqlbackup ```