diff options
-rw-r--r-- | etc/nginx/sites-enabled/chat.exemple.fr.conf | 96 | ||||
-rw-r--r-- | etc/nginx/sites-enabled/exemple.fr.conf | 15 | ||||
-rw-r--r-- | etc/nginx/sites-enabled/f.exemple.fr.conf | 37 | ||||
-rw-r--r-- | etc/prosody.cfg.lua | 196 | ||||
-rwxr-xr-x | usr/local/sbin/maj_prosodymods.sh | 10 | ||||
-rwxr-xr-x | usr/local/sbin/update_conversejs.sh | 36 | ||||
-rw-r--r-- | var/www/chat.exemple.fr/index.html | 67 | ||||
-rw-r--r-- | xmpp_iptables.sh | 29 |
8 files changed, 486 insertions, 0 deletions
diff --git a/etc/nginx/sites-enabled/chat.exemple.fr.conf b/etc/nginx/sites-enabled/chat.exemple.fr.conf new file mode 100644 index 0000000..bc3f462 --- /dev/null +++ b/etc/nginx/sites-enabled/chat.exemple.fr.conf @@ -0,0 +1,96 @@ +server { + listen 80; + server_name chat.exemple.fr; + + location / { + return 301 https://$host$uri; + } +} + +server { + listen 443 ssl http2; + ssl_certificate /etc/letsencrypt/live/chat.exemple.fr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/chat.exemple.fr/privkey.pem; + + root /var/www/chat.exemple.fr; + index index.html; + + # XMPP BOSH + location ^~ /http-bind { + proxy_pass https://exemple.fr:5281/http-bind; + proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP HTTP-Upload + location ^~ /upload { + proxy_pass https://f.exemple.fr; proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP Websockets + location /xmpp-websocket { + proxy_pass http://exemple.fr:5280/xmpp-websocket; + proxy_http_version 1.1; + proxy_buffering off; + proxy_set_header Connection "Upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 900s; + } + + # XMPP Account invite + location ^~ /invite { + proxy_pass https://exemple.fr:5281/invite; + proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # XMPP account register + location ^~ /register { + proxy_pass https://exemple.fr:5281/register; + proxy_http_version 1.1; + proxy_set_header Host exemple.fr; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_buffering off; + tcp_nodelay on; + } + + # sur mon vps debian j'ai eu besoin de ça pour + # que les pages d'invitation soit bien + # formatées + location = /share/bootstrap4/css/bootstrap.min.css { + alias /usr/lib/nodejs/bootstrap/dist/css/bootstrap.min.css; + } + + location = /share/jquery/jquery.min.js { + alias /usr/lib/nodejs/jquery/dist/jquery.min.js; + } + + location = /share/bootstrap4/js/bootstrap.min.js { + alias /usr/lib/nodejs/bootstrap/dist/js/bootstrap.min.js; + } + +} diff --git a/etc/nginx/sites-enabled/exemple.fr.conf b/etc/nginx/sites-enabled/exemple.fr.conf new file mode 100644 index 0000000..29daea1 --- /dev/null +++ b/etc/nginx/sites-enabled/exemple.fr.conf @@ -0,0 +1,15 @@ +server { + listen 80; + server_name exemple.fr; + + location / { + return 301 https://$host$uri; + } +} + +server { + listen 443 ssl; + server_nam exemple.fr; + ssl_certificate /etc/letsencrypt/live/exemple.fr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/exemple.fr/privkey.pem; +} diff --git a/etc/nginx/sites-enabled/f.exemple.fr.conf b/etc/nginx/sites-enabled/f.exemple.fr.conf new file mode 100644 index 0000000..6e31a5c --- /dev/null +++ b/etc/nginx/sites-enabled/f.exemple.fr.conf @@ -0,0 +1,37 @@ +perl_modules /usr/local/lib/perl; # Path to upload.pm. +perl_require upload.pm; + +server { + listen 80; + server_name f.exemple.fr; + location / { + return 301 https://$host$request_uri; + } +} + +server { + # Specify directives such as "listen", "server_name", and TLS-related + # settings for the "server" that handles the uploads. + listen 443 ssl http2; + server_name f.exemple.fr; + ssl_certificate /etc/letsencrypt/live/f.exemple.fr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/f.exemple.fr/privkey.pem; + + + # Uploaded files will be stored below the "root" directory. To minimize + # disk I/O, make sure the specified path is on the same file system as + # the directory used by Nginx to store temporary files holding request + # bodies ("client_body_temp_path", often some directory below /var). + + root /var/www/upload; + index index.html; + + # Specify this "location" block (if you don't use "/", see below): + location / { + perl upload::handle; + } + + # Upload file size limit (default: 1m), also specified in your XMPP + # server's upload module configuration (see below): + client_max_body_size 100m; +} diff --git a/etc/prosody.cfg.lua b/etc/prosody.cfg.lua new file mode 100644 index 0000000..ced3f74 --- /dev/null +++ b/etc/prosody.cfg.lua @@ -0,0 +1,196 @@ +admins = { "vous@exemple.fr" } + +-- For more information see: https://prosody.im/doc/libevent +-- use_libevent = true + +plugin_paths = { "/usr/lib/prosody/modules" } + +modules_enabled = { + + -- Generally required + "roster"; -- Allow users to have a roster. Recommended ;) + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "tls"; -- Add support for secure TLS on c2s/s2s connections + "dialback"; -- s2s dialback support + "disco"; -- Service discovery + + -- Not essential, but recommended + "carbons"; -- Keep multiple clients in sync + "carbons_copies"; + "carbons_copies_adhoc"; + "pep"; -- Enables users to publish their avatar, mood, activity, playing music and more + "private"; -- Private XML storage (for room bookmarks, etc.) + "blocklist"; -- Allow users to block communications with other users + "vcard4"; -- User profiles (stored in PEP) + "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard + "smacks"; + "bookmarks"; -- vieux module mais compatible avec la + -- majorité des clients XMPP contrairement + -- à bookmarks2 + --"bookmarks2"; + "presence"; -- voir l'état de l'utilisateur (en ligne, hors + -- ligne, etc...) + "offline"; + + -- Nice to have + "version"; -- Replies to server version requests + "uptime"; -- Report how long server has been running + "time"; -- Let others know the time here on this server + "ping"; -- Replies to XMPP pings with pongs + "register"; -- Allow users to register on this server using a client and change passwords + "mam"; -- Store messages in an archive and allow users to access it + "csi"; + "csi_simple"; -- Simple Mobile optimizations + "csi_battery_saver"; + "vjud"; -- recherche d'utilisateurs dans les salons + + -- Admin interfaces + "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands + + -- HTTP modules + "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP" + "websocket"; -- XMPP over WebSockets + + -- Other specific functionality + "posix"; -- POSIX functionality, sends server to background, enables syslog, etc. + "limits"; -- Enable bandwidth limiting for XMPP connections + "groups"; -- Shared roster support + "server_contact_info"; -- Publish contact information for this service + "announce"; -- Send announcement to all online users + "welcome"; -- Welcome users who register accounts + "watchregistrations"; -- Alert admins of registrations + "motd"; -- Send a message to users when they log in + --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots. + --"proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use + } + + -- These modules are auto-loaded, but should you want + -- to disable them then uncomment them here: + modules_disabled = { + -- "offline"; -- Store offline messages + -- "c2s"; -- Handle client connections + -- "s2s"; -- Handle server-to-server connections +} + +motd_text = [[Bonjour à tous ! Bienvenue sur mon serveur XMPP. Clavardez heureux !]] +welcome_message = "C'est ta première connexion, $username. Bienvenue à toi." + +daemonize = false; +pidfile = "/run/prosody/prosody.pid"; +trusted_proxies = { "127.0.0.1", "::1" } + +-- Force certificate authentication for server-to-server connections +c2s_require_encryption = true -- chiffrement requis pour connexion client à serveur +s2s_require_encryption = true -- chiffrement requis pour connexion entre serveurs +s2s_secure_auth = true +authentication = "internal_hashed" + +-- mam settings +archive_expires_after = "never" -- historique permanent des chats + +log = { + -- Log files (change 'info' to 'debug' for debug logs): + info = "/var/log/prosody/prosody.log"; + error = "/var/log/prosody/prosody.err"; + -- Syslog: + { levels = { "error" }; to = "syslog"; }; +} + +-- http and certificate shenanigans +certificates = "certs" + +-- Include "conf.d/*.cfg.lua" + +legacy_ssl_ports = { 5223 } +-- http_ports = { 5280 } +-- http_interface = { "*" } +-- https_ports = { 5281 } +-- https_interfaces { "*" } + + +cross_domain_bosh = { "https://chat.exemple.fr" } +cross_domain_websocket = { "https://chat.exemple.fr" } +consider_bosh_secure = true +consider_websocket_secure = true +allow_registration = true -- nécessaire pour mod_invites +registration_invite_only = true -- inscription autorisé seulement avec les invitations +vjud_mode = "opt-in" -- l'utilisateur doit consentir pour que la recherche vjud +-- le fasse remonter dans les résultats. + +-- https://prosody.im/security/advisory_20210512/ +gc = { + speed = 500; +} +c2s_stanza_size_limit = 256 * 1024 +s2s_stanza_size_limit = 512 * 1024 + +limits = { + c2s = { + rate = "10kb/s"; + }; + s2sin = { + rate = "3kb/s"; + }; +} +-- https://prosody.im/security/advisory_20210512/ + +ssl = { + key = "certs/exemple.fr.key"; + certificate = "certs/exemple.fr.crt"; +} + +VirtualHost "exemple.fr" + invites_page = "https://chat.exemple.fr/invite?{invite.token}" + webchat_url = "https://chat.exemple.fr/" + http_external_url = "https://chat.exemple.fr/" + invite_expiry = 86400 * 7 -- 7 jours avant qu'un lien d'invitation expire + http_paths = { + invites_page = "/invite"; + invites_register_web = "/register"; + } + + modules_enabled = { + "invites"; + "invites_adhoc"; + "invites_page"; + "invites_register"; + "invites_register_web"; + "http_libjs"; + } + + contact_info = { + abuse = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + admin = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + security = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + support = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" }; + }; + + https_certificate = "certs/exemple.fr.crt"; + ssl = { + key = "certs/exemple.fr.key"; + certificate = "certs/exemple.fr.crt"; + } + + Component "f.exemple.fr" "http_upload_external" + http_upload_external_base_url = "https://f.exemple.fr/" + http_upload_external_secret = "its-a-secret" + http_upload_external_file_size_limit = 104857600 -- limite de à 100Mo pour les envois de pjs + ssl = { + key = "certs/f.exemple.fr.key"; + certificate = "certs/f.exemple.fr.crt"; + } + + Component "salons.exemple.fr" "muc" + name = "Salons (chatrooms) chez exemple.fr" + modules_enabled = { "muc_mam", "vcard_muc" } + muc_room_default_language = "fr" + muc_log_expires_after = "never" -- histo permanent des groupes de + -- chats + log_all_rooms = true + muc_log_by_default = true + muc_log_presences = false + restrict_room_creation = "admin" -- seul l'admin peut créer des salons + ssl = { + key = "certs/salons.exemple.fr.key"; + certificate = "certs/salons.exemple.fr.crt"; + } diff --git a/usr/local/sbin/maj_prosodymods.sh b/usr/local/sbin/maj_prosodymods.sh new file mode 100755 index 0000000..c7ffaed --- /dev/null +++ b/usr/local/sbin/maj_prosodymods.sh @@ -0,0 +1,10 @@ +#!/bin/sh +MODDIR="/usr/lib/prosody/modules/" + +if test -d $MODDIR; then + cd $MODDIR + hg pull --update +else + mkdir -p /usr/lib/prosody + hg clone https://hg.prosody.im/prosody-modules/ $MODDIR +fi diff --git a/usr/local/sbin/update_conversejs.sh b/usr/local/sbin/update_conversejs.sh new file mode 100755 index 0000000..971d980 --- /dev/null +++ b/usr/local/sbin/update_conversejs.sh @@ -0,0 +1,36 @@ +#!/bin/sh +TEMPDIR="$(mktemp -d)" +LOG=/var/log/update_conversejs.log +WWWDIR='/var/www/chat.exemple.fr' +WWWUSER='www-data' # this value will differ on the + # distro you're using: it'll be 'http' on + # Arch Linux nginx for example. + +mkdir -p $WWWDIR/dist +cd $TEMPDIR +printf "\n\n$(date) - INFO - Starting updating conversejs..." | tee -a $LOG +CURL_ERR=$(curl -s \ # let's grab latest release tarball of converse.js + https://api.github.com/repos/conversejs/converse.js/releases/latest | \ + grep -o "https://.*\.tgz" | \ + grep converse\.js- | \ + xargs curl -fsOJL) || \ + (printf "\n$(date) - ERR - Updating conversejs failed." | tee -a $LOG && exit) + +# we download the OMEMO library to use it in converse +if test -e "$WWWDIR/dist/libsignal-protocol.min.js"; then + printf "\n$(date) - TOK - Libsignal already installed, skipping." | tee -a $LOG +else + curl -fsOJL \ + https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js || \ + (printf "\n$(date) - ERR - Updating libsignal-protocol-javascript failed." | \ + tee -a $LOG) + cp libsignal*.js $WWWDIR/dist/ +fi + +tar xzf *.tgz +cp -rf package/dist $WWWDIR/ +sed "s/fullscreen\.html/index\.html/g" package/manifest.json > $WWWDIR/manifest.json +chown $WWWUSER:$WWWUSER -R $WWWDIR/ +chmod 755 -R $WWWDIR/ +rm -rf $TEMPDIR +printf "\n$(date) - TOK - Done." | tee -a $LOG diff --git a/var/www/chat.exemple.fr/index.html b/var/www/chat.exemple.fr/index.html new file mode 100644 index 0000000..410f94c --- /dev/null +++ b/var/www/chat.exemple.fr/index.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<html class="no-js" lang="en"> +<head> + <title>Converse</title> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <meta name="description" content="Converse XMPP/Jabber Chat"/> + <meta name="keywords" content="xmpp chat webchat converse.js" /> + <link rel="manifest" href="/manifest.json"> + <link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" /> + <script src="/dist/libsignal-protocol.min.js"></script> + <script src="/dist/converse.min.js"></script> +</head> +<body class="converse-fullscreen"> + <noscript>You need to enable JavaScript to run the Converse.js chat app.</noscript> + <div id="conversejs-bg"></div> + <script> + /* + @licstart + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to <http://unlicense.org/> + @licend + */ + converse.initialize({ + auto_away: 300, //absent au bout de 5minutes + auto_list_rooms: true, + auto_reconnect: true, + auto_xa: 600, //absence prolongée au bout de 10minutes + bosh_service_url: 'https://chat.exemple.fr/http-bind/', + csi_waiting_time: 60, + enable_smacks: true, + i18n: 'fr', // pour avoir l'interface en français + locked_domain: exemple.fr, // on verouille le domaine autoriséà se connecter + message_archiving: 'always', + persistent_store: 'IndexedDB', // jcbrand a dit qu'en 8.0.0 + // omemo_default: true, + play_sounds: true, + // ça va aller plus vite avec l'IndexedDB + theme: 'concord', + view_mode: 'fullscreen', + websocket_url: 'wss://chat.exemple.fr/xmpp-websocket', + }); + </script> +</body> +</html> diff --git a/xmpp_iptables.sh b/xmpp_iptables.sh new file mode 100644 index 0000000..557b1b2 --- /dev/null +++ b/xmpp_iptables.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT # on accepte les connexions client à serveur +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT # pareil que le dessus mais celles qui sont chiffrés. +iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT # connexions serveur à serveur. +iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # HTTP pour l'interface web +iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS +iptables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # pour envoyer des requête DNS +iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # en output aussi si des serveurs utilisant l'HTTP upload pour les pjs +iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT + +iptables-save > /etc/iptables/iptables.rules + + +# pareil pour l'ipv6 +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT +ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT +ip6tables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # HTTP +ip6tables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS +ip6tables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # HTTP pour l'interface web +ip6tables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS +ip6tables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # pour envoyer des requête DNS +ip6tables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # en output aussi si des serveurs utilise l'HTTP upload pour les pjs +ip6tables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT + +ip6tables-save > /etc/iptables/ip6tables.rules +systemctl enable --now iptables # activation du service iptables si pas +# déjà fait pour garder la config du pare-feu après reboot. |