====== Libretime dans container LXC sans privilèges ====== Pour faire cohabiter différentes instances de Libretime, installation de chacune dans un container LXC sans privilèges pour plus de sécurité ... ===== Installer LXC et créer un premier container ===== Sur une base d'Ubuntu 18.04 sudo apt-get install lxc Créer un utilisateur spécifique pour exécuter les containers adduser lxcrunner Permettre à cet utilisateur de créer des devices réseau virtuels nano /etc/lxc/lxc-usernet y ajouter lxcrunner veth lxcbr0 10 Se logguer en tant que user adduser lxcrunner Fix environmental variables. Otherwise you might have issues creating containers later lxcrunner> unset XDG_RUNTIME_DIR XDG_SESSION_ID Find out the namespaces allowed for the user lxc. The wildcard in the command below will match both suid and guid files. We will map the LXC container to these regions. lxcrunner> cat /etc/s*id|grep $USER lxcrunner:624288:65536 lxcrunner:624288:65536 From the output, we can see that both assigned suid and guid values start at 624288 and runs through the next 65536 integers. Let us set up configuration files as required by LXC before starting a container. The required file is in ~/.config/lxc/default.conf. lxcrunner> mkdir -p ~/.config/lxc/ lxcrunner> vim ~/.config/lxc/default.conf Add in the following lines. Notice that the syntax might be different from what you find online. I am using the latest version of LXC, v3.0.3. We are setting the network interface type to be veth and creating a new bridge lxcbr0. We will come back to these later. Your hwaddr may differ; you can see the default values in /etc/lxc/default.conf. . lxc.net.0.type = veth lxc.net.0.link = lxcbr0 lxc.net.0.flags = up lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx lxc.idmap = u 0 624288 65536 lxc.idmap = g 0 624288 65536 ==== Création du premier container ==== Créer le container en tant qu'utilisateur lxcrunner lxcrunner>lxc-create -n musique -t download Choisir ubuntu bionic amd64 ou faire directement : lxcrunner>lxc-create -n musique -t download -- -d ubuntu -r bionic -a amd64 A noter pour le backup que les containers sont stockés à cet emplacement : /home/lxcrunner/.local/share/lxc/musique (pour le container musique) A cet endroit, on trouve le fichier config propre au container et le répertoire rootfs qui contient le filesystem habituel d'un linux Le démarrer lxcrunner>lxc-start musique Vérifier que ça marche lxcrunner>lxc-ls -f ==== Autostart du container ==== Visiblement, il ne suffit pas d'ajouter le paramètre lxc.start.auto = 1 pour que le unpriviledged container démarre, a priori possible d'ajouter une instruction dans le contrab du user qui lance les containers : crontab -e and add the following line: @reboot lxc-autostart * voir https://serverfault.com/questions/620709/how-to-auto-start-unprivileged-lxc-containers ===== Installer Libretime dans le container ===== Entrer dans le container lxcrunner>lxc-attach musique On obtient un shell root, installer quelques outils : apt update apt upgrade apt install git nano nload htop locate nmap Lancer l'installation de Libretime cd /home/ubuntu/ git clone https://github.com/LibreTime/libretime cd libretime ./install -fiap Une fois l'installation finie, sortir du container exit ===== Créer les vhost apache pour proxy le traffic vers le container ===== Identifier l'IP du container : lxc-ls -f NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED musique RUNNING 1 - 10.0.3.116 - true Pour que le apache du serveur principal renvoie le traffic vers le container, il faut créer les vhost correspondants nano /etc/apache2/sites-available/musique.domaine.org.conf ServerAdmin mail@domaine.org ServerName musique.domaine.org ErrorLog ${APACHE_LOG_DIR}/musique.domaine.org-error.log CustomLog ${APACHE_LOG_DIR}/musique.domaine.org-access.log combined ProxyPreserveHost On ProxyPass / http://10.0.3.116/ ProxyPassReverse / http://10.0.3.116/ Order deny,allow Allow from all RewriteEngine on RewriteCond %{SERVER_NAME} =musique.domaine.org RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent] Et pour le https nano /etc/apache2/sites-available/musique.domaine.org-le-ssl.conf ServerAdmin mail@domaine.org ServerName musique.domaine.org ErrorLog ${APACHE_LOG_DIR}/musique.domaine.org-error.log CustomLog ${APACHE_LOG_DIR}/musique.domaine.org-access.log combined ProxyPreserveHost On ProxyPass / http://10.0.3.116/ ProxyPassReverse / http://10.0.3.116/ Order deny,allow Allow from all SSLEngine on SSLProxyEngine On SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off SSLProxyCheckPeerExpire off SSLCertificateFile /etc/letsencrypt/live/musique.domaine.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/musique.domaine.org/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf Ajouter ces vhost aux sites activés a2ensite musique.domaine.org.conf musique.domaine.org-le-ssl.conf Relancer Apache systemctl reload apache2 ===== Créer les certificats ssl pour le https ===== En utilisant [[https://certbot.eff.org/|certbot]] Le principe est de générer le certificat avec le vhost apache du host par défaut adapté au domaine du site, puis de remettre en place les vhost proxy vers le container avec l'adresse du certificat précédemment généré. A priori, une fois le premier certificat généré, le renouvellement peut se faire avec les vhost proxy. Pour mémoire, pistes pour autres méthodes de validation du certificat par certbot avec un proxy : * Force http-01 webroot authentication https://community.letsencrypt.org/t/using-certbot-behind-an-ssl-reverse-proxy/36783 * ProxyPass /.well-known ! https://bendellar.com/apache-as-reverse-proxy-for-letsencrypt-free-https-certificates/ * Activer un vhost https dans le container et y forwarder le traffic Validation manuelle après [[https://www.configserverfirewall.com/ubuntu-linux/ubuntu-disable-ipv6/|désactivation de ipv6]] (à adapter avec l'ip du serveur) en [[https://community.letsencrypt.org/t/connection-error-with-http-challenges/46795/10|forçant l'écoute de certbot en ipv4]] : certbot certonly --manual --preferred-challenges http --http-01-address 163.172.20.20 -d musique.domaine.org --verbose Voir aussi la config du renouvellement du certificat si problème dans /etc/letsencrypt/renewal/ ===== Libretime + https ===== La page d'accueil de Libretime mixe du contenu http et https quand consulté via https, du coup des éléments sont bloqués par le navigateur. Pour palier cela, on peut rajouter une règle de substitution dans le vhost de Libretime dans le container : Activer le mod substitute a2enmod substitute Editer le vhost dans le container nano /etc/apache2/sites-available/airtime.conf # Quick fix for iframes that reference hard coded 'localhost' in paths. # BEGIN:LOCALHOSTFIX-- SetOutputFilter SUBSTITUTE;DEFLATE AddOutputFilterByType SUBSTITUTE text/html Substitute "s|http://radio.domaine.org//|/|ni" Substitute "s|https://radio.domaine.org//|/|ni" Substitute "s|http://radio.domaine.org/|/|ni" Substitute "s|https://radio.domaine.org/|/|ni" Il reste le problème de l'appel du stream sur la page d'accueil qui se fait sur du https avec config de port dans Libretime qui doit être sur du http ... Test de passage au port 443 dans /etc/airtime/airtime.conf pour un résultat flou (pas de son dans le stream de sortie, comment passer le stream de sortie de libretime en https ? Voir aussi à propos de Libretime vs https dans un container : * https://discourse.libretime.org/t/lt-behind-a-proxy/ * https://github.com/LibreTime/libretime/issues/515 * https://discourse.libretime.org/t/adding-ssl-to-libretime-icecast/347/12 ===== Finaliser l'installation de Libretime ===== Pour ce faire, il faut se rendre à l'adresse web définie : http://musique.domaine.org et suivre la procédure proposée : création de la base de donnée, config rabbitmq, définition de l'url et du port puis relancer les services depuis l'intérieur du container lxc-attach musique systemctl start libretime-playout systemctl start libretime-liquidsoap systemctl start libretime-analyzer systemctl start libretime-celery Si tout va bien on atterit sur la page d'accueil de Libretime, pour se logguer la première fois : admin / admin (ne pas oublier de changer ce mdp) {{media_08:libretimeaccueil.png|}} ===== Mettre à jour les containers de la machine via un script ===== Le script /lxc-_all-update.sh : #!/bin/bash # Get the vm list vms="$(lxc-ls --active)" # Update each vm update_vm(){ local vm="$1" echo "*** [VM: $vm [$(hostname) @ $(date)] ] ***" /usr/bin/lxc-attach -n "$vm" apt-get -- -qq update /usr/bin/lxc-attach -n "$vm" apt-get -- -qq -y upgrade /usr/bin/lxc-attach -n "$vm" apt-get -- -qq -y clean /usr/bin/lxc-attach -n "$vm" apt-get -- -qq -y autoclean echo "-----------------------------------------------------------------" } # Do it for v in $vms do update_vm "$v" done Lancer le script en tant que lxcrunner lxcrunner@server6:~$ ./lxc-_all-update.sh ===== Sauvegarde de Libretime ===== * [[https://libretime.org/docs/backing-up-the-server|Suivre cette documentation]] ====== Troubleshooting ====== ===== Désactiver ipv6 si ping images.linuxcontainers.org est résolu en ipv6 ===== * https://linuxconfig.org/how-to-disable-ipv6-address-on-ubuntu-18-04-bionic-beaver-linux ===== Désactiver le serveur icecast dans les containers si pas utilisés ===== root@musique:~# systemctl stop icecast2 root@musique:~# systemctl disable icecast2 ===== Réglages apparmor ===== Corriger les erreurs dans syslog server6 kernel: [12869825.600469] audit: type=1400 audit(1604160574.292:860): apparmor="DENIED" operation="mount" info="failed flags match" error=-13 profile="lxc-container-default-cgns" name="/" pid=24470 comm="(pachectl)" flags="rw, rslave" : il faut ajouter dans la configuration de chaque container : nano /home/lxcrunner/.local/share/lxc/atelier/config lxc.apparmor.profile = unconfined ===== Réglages lxc-net vs bind9 named sur ubuntu 18.04 après update ===== Si lxc-net[17399]: dnsmasq: failed to create listening socket for Address already in use ça a l'air d'être le port 53 la source du conflit, désactiver bind9 (named) pour l'interface 10.0.5.0/24 nano /etc/bind/named.conf.options Ajouter dans le fichier : allow-transfer { ... ... // lxc-container 10.0.5.0/24 }; Ensuite : sudo systemctl restart bind9 sudo systemctl restart lxc-net.service Pour debug lxc-start musique --logfile /home/lxcrunner/logup.txt --logpriority DEBUG * cf https://discuss.linuxcontainers.org/t/solved-dnsmasq-failed-to-create-listening-socket-for-192-150-0-1-address-already-in-use/3006 Test occupation port lsof -i ===== Installation du 12 mars 2022 mars ===== ==== Faire un backup ==== https://libretime.org/docs/admin-manual/backup/ mkdir /home/lxcrunner/backupmigration/ && cd /home/lxcrunner/backupmigration/ sudo -u postgres pg_dumpall | gzip -c > airtime-backup.gz tar -zcvpf airtime-backup-imported-atelier12032022.tgz /srv/airtime/stor/imported/ tar -zcvpf airtime-etc-atelier12032022.tgz /etc/airtime/ tar -zcvpf airtime-all-musique-12032022.tgz /home/lxcrunner/backupmigration/ ==== Sur le host ==== a2ensite musique.radiocampus.org.conf musique.radiocampus.org-le-ssl.conf radio.radiocampus.org.conf radio.radiocampus.org-le-ssl.conf a2enmod proxy proxy_http proxy_wstunnel ssl http2 rewrite headers systemctl restart apache2 ==== Dans le container en tant que root ==== Installation à partir du dépôt git, la communauté Libretime a fait des paquets debian et ubuntu mais ils ne marchent pas avec la debian 11 et ubuntu 20.04, donc git ... https://github.com/LibreTime/libretime apt install nano htop nload python3 git curl wget nmap net-tools locate adduser lxcrunner cd /home/lxcrunner/ git clone https://github.com/LibreTime/libretime cd libretime ./install -fiap Libretime installé ! sudo systemctl start libretime-analyzer sudo systemctl start libretime-api sudo systemctl start libretime-celery sudo systemctl start libretime-liquidsoap sudo systemctl start libretime-playout Utilisation d'un serveur icecast externe apt remove --purge icecast2 ==== Restaurer le backup ==== tar -xpvf airtime-backup-imported-musique12032022.tgz mv srv/airtime/stor/imported/ /srv/airtime/stor/imported/ gunzip airtime-db-backup-12032022.gz sudo -u postgres dropdb airtime sudo -u postgres psql -f airtime-backup-atelier12032022 apt remove --purge icecast2 ==== Passer Libretime en https ==== Notamment si un fichier importé reste en "pending import", il faut changer airtime.conf comme cela : nano /etc/airtime/airtime.conf [general] api_key = ************************ protocol = https base_url = radio.monserveur.org base_port = 443 base_dir = / force_ssl = true cache_ahead_hours = 1 ====== Ressources ====== * Site du [[https://libretime.org/|projet Libretime]], [[https://libretime.org/install|documentation de l'installation]], [[https://discourse.libretime.org/|forum d'entre-aide]] * LXC container unpriviledged https://blog.warmwolf.com/2020/04/securing-wordpress-unprivileged-lxc-container-on-ubuntu/2/ * Créer un répertoire partagé entre les containers https://askubuntu.com/questions/691039/adding-a-shared-host-directory-to-an-lxc-lxd-container * Documentation éparse liquidsoap libretime et + https://gitlab.com/guifi-exo/wiki/-/blob/master/howto/radio-audio-streaming.md {{tag>bj linux lxc libretime}}