summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Luevano Alvarado <david@luevano.xyz>2021-06-08 23:25:06 -0600
committerDavid Luevano Alvarado <david@luevano.xyz>2021-06-08 23:25:06 -0600
commitf39af47eb03343dadf2c646dc43c8b8e131e427a (patch)
tree8777b3255f29a597f5ac30f3aa703a3afe7b6bc8
parent5415f37e8da7615b524173f2bb6968be46128d20 (diff)
add xmpp server entry
-rw-r--r--blog/dst/a/acomodada_la_pagina_de_arte.html24
-rw-r--r--blog/dst/a/asi_nomas_esta_quedando.html24
-rw-r--r--blog/dst/a/el_blog_ya_tiene_timestamps.html24
-rw-r--r--blog/dst/a/first_blog_post.html18
-rw-r--r--blog/dst/a/git_server_with_cgit.html26
-rw-r--r--blog/dst/a/mail_server_with_postfix.html28
-rw-r--r--blog/dst/a/new_blogging_system.html24
-rw-r--r--blog/dst/a/website_with_nginx.html26
-rw-r--r--blog/dst/a/xmpp_server_with_prosody.html636
-rw-r--r--blog/dst/index.html1
-rw-r--r--blog/dst/rss.xml513
-rw-r--r--blog/dst/sitemap.xml20
-rw-r--r--blog/dst/tag/@english.html4
-rw-r--r--blog/dst/tag/@server.html4
-rw-r--r--blog/dst/tag/@tools.html4
-rw-r--r--blog/dst/tag/@tutorial.html4
-rw-r--r--blog/plt/page.html3
-rw-r--r--blog/plt/page_nav.html28
-rw-r--r--blog/src/.files7
-rw-r--r--blog/src/a/git_server_with_cgit.md4
-rw-r--r--blog/src/a/mail_server_with_postfix.md20
-rw-r--r--blog/src/a/website_with_nginx.md12
-rw-r--r--blog/src/a/xmpp_server_with_prosody.md579
-rw-r--r--blog/xmpp_server_with_prosody.md189
-rw-r--r--gb/index.html130
-rw-r--r--luevano/contact.html2
-rw-r--r--static/css/gb.css27
-rw-r--r--static/css/style.css56
-rw-r--r--static/css/theme.css25
29 files changed, 2173 insertions, 289 deletions
diff --git a/blog/dst/a/acomodada_la_pagina_de_arte.html b/blog/dst/a/acomodada_la_pagina_de_arte.html
index 489c7ea..63edc40 100644
--- a/blog/dst/a/acomodada_la_pagina_de_arte.html
+++ b/blog/dst/a/acomodada_la_pagina_de_arte.html
@@ -82,6 +82,30 @@
<p>Este pedo fue gracias a que me reescribí la forma en la que <code>pyssg</code> maneja los templates, ahora uso el sistema de <code>jinja</code> en vez del cochinero que hacía antes.</p>
<p>Y pues nada más eso, aquí está el <a href="https://art.luevano.xyz/a/elephant_octopus.html">primer post</a> y por supuesto acá está el link del RSS <a href="https://art.luevano.xyz/rss.xml">https://art.luevano.xyz/rss.xml</a>.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/asi_nomas_esta_quedando.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
diff --git a/blog/dst/a/asi_nomas_esta_quedando.html b/blog/dst/a/asi_nomas_esta_quedando.html
index 4ad042d..6098c6f 100644
--- a/blog/dst/a/asi_nomas_esta_quedando.html
+++ b/blog/dst/a/asi_nomas_esta_quedando.html
@@ -84,6 +84,30 @@
<p>Si bien aún quedan cosas por hacer sobre estos dos servers que me acomodé (además de hacerles unas entradas para documentar cómo lo hice), quiero moverme a otra cosa que sería acomodar una sección de dibujos, lo cual en teoría es bien sencillo, pero como quiero poder automatizar la publicación de estos, quiero modificar un poco el <a href="https://github.com/luevano/pyssg">pyssg</a> para que jale chido para este pex.</p>
<p>Ya por último también quiero moverle un poco al CSS, porque lo dejé en un estado muy culerón y quiero meterle/ajustar unas cosas para que quede más limpio y medianamente bonito&hellip; <em>dentro de lo que cabe porque evidentemente me vale verga si se ve como una página del 2000</em>.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/acomodada_la_pagina_de_arte.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/new_blogging_system.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
diff --git a/blog/dst/a/el_blog_ya_tiene_timestamps.html b/blog/dst/a/el_blog_ya_tiene_timestamps.html
index b18fa71..9511899 100644
--- a/blog/dst/a/el_blog_ya_tiene_timestamps.html
+++ b/blog/dst/a/el_blog_ya_tiene_timestamps.html
@@ -83,6 +83,30 @@
<p>El <code>ssg</code> modificado está en mis <a href="https://git.luevano.xyz/.dots">dotfiles</a> (o directamente <a href="https://git.luevano.xyz/.dots/tree/.local/bin/ssg">aquí</a>).</p>
<p>Por último, también quité las extensiones <code>.html</code> de las URLs, porque se veía bien pitero, pero igual los links con <code>.html</code> al final redirigen a su link sin <code>.html</code>, así que no hay rollo alguno.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/website_with_nginx.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/first_blog_post.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
diff --git a/blog/dst/a/first_blog_post.html b/blog/dst/a/first_blog_post.html
index a4327e2..ed5dbcd 100644
--- a/blog/dst/a/first_blog_post.html
+++ b/blog/dst/a/first_blog_post.html
@@ -82,6 +82,24 @@
<p>At the moment, I&rsquo;m not satisfied because there&rsquo;s no automatic date insertion into the 1) html file, 2) the blog post itself and 3) the listing system in the <a href="https://blog.luevano.xyz/">blog homepage</a> (and there&rsquo;s also the problem with the ordering of the entries&hellip;). And all of this just because I didn&rsquo;t want to use <a href="https://github.com/LukeSmithxyz/lb">Luke&rsquo;s</a> solution (don&rsquo;t really like that much how he handles the scripts&hellip; <em>but they just work</em>).</p>
<p>Hopefully, for tomorrow all of this will be sorted out and I&rsquo;ll have a working blog system.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/el_blog_ya_tiene_timestamps.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
diff --git a/blog/dst/a/git_server_with_cgit.html b/blog/dst/a/git_server_with_cgit.html
index 64cd553..b43d38f 100644
--- a/blog/dst/a/git_server_with_cgit.html
+++ b/blog/dst/a/git_server_with_cgit.html
@@ -197,11 +197,35 @@ exec highlight --force --inline-css -f -I -O xhtml -S &quot;$EXTENSION&quot; 2&g
</code></pre>
<p>That would be everything. If you need support for more stuff like compressed snapshots or support for markdown, check the optional dependencies for <code>cgit</code>.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/new_blogging_system.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
<p>Created: Sun, Mar 21, 2021 @ 19:00 UTC</p>
- <p>Modified: Tue, Jun 08, 2021 @ 06:53 UTC</p>
+ <p>Modified: Tue, Jun 08, 2021 @ 07:27 UTC</p>
<div class="article-tags">
<p>Tags:
<a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a> </p>
diff --git a/blog/dst/a/mail_server_with_postfix.html b/blog/dst/a/mail_server_with_postfix.html
index 04a1b54..1cdb78d 100644
--- a/blog/dst/a/mail_server_with_postfix.html
+++ b/blog/dst/a/mail_server_with_postfix.html
@@ -187,7 +187,7 @@ cp /usr/share/doc/dovecot/example-config/dovecot.conf /etc/dovecot/dovecot.conf
cp -r /usr/share/doc/dovecot/example-config/conf.d /etc/dovecot
</code></pre>
<p>As Luke stated, <code>dovecot</code> comes with a lot of &ldquo;modules&rdquo; (under <code>/etc/dovecot/conf.d/</code> if you copied that folder) for all sorts of configurations that you can include, but I do as he does and just edit/create the whole <code>dovecot.conf</code> file; although, I would like to check each of the separate configuration files <code>dovecot</code> provides I think the options Luke provides are more than good enough.</p>
-<p>I&rsquo;m working with an empty <code>dovecot.conf</code> file. Add the following lines for SSL and login configuration (also replace <code>{yourcertdir}</code> with the same certificate directory described in the <a href="#postfix">Postfix</a> section above, note that the <code>&lt;</code> is required):</p>
+<p>I&rsquo;m working with an empty <code>dovecot.conf</code> file. Add the following lines for SSL and login configuration (also replace <code>{yourcertdir}</code> with the same certificate directory described in the Postfix section above, note that the <code>&lt;</code> is required):</p>
<pre><code class="language-apache">ssl = required
ssl_cert = &lt;{yourcertdir}/fullchain.pem
ssl_key = &lt;{yourcertdir}/privkey.pem
@@ -434,11 +434,35 @@ systemctl enable spamassassin.service
</figure>
<p>Finally, that&rsquo;s actually it for this entry, if you have any problem whatsoever you can <a href="https://luevano.xyz/contact.html">contact me</a>.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/website_with_nginx.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
<p>Created: Sun, Mar 21, 2021 @ 04:05 UTC</p>
- <p>Modified: Tue, Jun 08, 2021 @ 06:27 UTC</p>
+ <p>Modified: Tue, Jun 08, 2021 @ 07:29 UTC</p>
<div class="article-tags">
<p>Tags:
<a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a> </p>
diff --git a/blog/dst/a/new_blogging_system.html b/blog/dst/a/new_blogging_system.html
index c52ba09..210f15e 100644
--- a/blog/dst/a/new_blogging_system.html
+++ b/blog/dst/a/new_blogging_system.html
@@ -85,6 +85,30 @@
<p>It might sound convoluted, but it works pretty well, with of course room to improve; I&rsquo;m open to suggestions, issue reporting or direct contributions <a href="https://github.com/luevano/pyssg">here</a>. BTW, it only works on Linux for now (and don&rsquo;t think on making it work on windows, but feel free to do PR for the compatibility).</p>
<p>That&rsquo;s it for now, the new RSS feed is available here: <a href="https://blog.luevano.xyz/rss.xml">https://blog.luevano.xyz/rss.xml</a>.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/asi_nomas_esta_quedando.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
diff --git a/blog/dst/a/website_with_nginx.html b/blog/dst/a/website_with_nginx.html
index caf756f..dea1fba 100644
--- a/blog/dst/a/website_with_nginx.html
+++ b/blog/dst/a/website_with_nginx.html
@@ -198,11 +198,35 @@ systemctl restart nginx
<p>And a file will be opened where you need to add a new rule for Certbot, just append the line: <code>1 1 1 * * certbot renew</code> (renew on the first day of every month) and you&rsquo;re good. Alternatively use <code>systemd</code> timers as stated in the <a href="https://wiki.archlinux.org/title/Certbot#Automatic_renewal">Arch Linux Wiki</a>.</p>
<p>That&rsquo;s it, you now have a website with SSL certificate.</p>
+ <div class="page-nav">
+ <span class="next">
+ <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/el_blog_ya_tiene_timestamps.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
<hr>
<div class="article-info">
<p>By David Luévano</p>
<p>Created: Fri, Mar 19, 2021 @ 02:58 UTC</p>
- <p>Modified: Tue, Jun 08, 2021 @ 06:11 UTC</p>
+ <p>Modified: Tue, Jun 08, 2021 @ 07:27 UTC</p>
<div class="article-tags">
<p>Tags:
<a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a> </p>
diff --git a/blog/dst/a/xmpp_server_with_prosody.html b/blog/dst/a/xmpp_server_with_prosody.html
new file mode 100644
index 0000000..d25de3f
--- /dev/null
+++ b/blog/dst/a/xmpp_server_with_prosody.html
@@ -0,0 +1,636 @@
+<!DOCTYPE html>
+<html class="theme-dark" lang="en"
+ prefix="og: https://ogp.me/ns#">
+ <head>
+ <base href="https://static.luevano.xyz">
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Create an XMPP server with Prosody compatible with Conversations and Movim -- Luévano's Blog</title>
+ <meta name="description" content"How to create an XMPP server using Prosody on a server running Nginx. This server will be compatible with at least Conversations and Movim."/>
+ <link rel="alternate" type="application/rss+xml" href="https://blog.luevano.xyz/rss.xml" title="Luévano's Blog RSS">
+ <link rel="icon" href="images/icons/favicon.ico">
+
+ <!-- general style -->
+ <link rel="stylesheet" type="text/css" href="css/style.css">
+ <link rel="stylesheet" type="text/css" href="fork-awesome/css/fork-awesome.min.css">
+ <link rel="stylesheet" type="text/css" href="font-awesome/css/all.min.css">
+
+ <!-- highlight support for code blocks -->
+ <script type="text/javascript" src="hl/highlight.min.js"></script>
+ <!--<script type="text/javascript" src="hl/highlight-ln.min.js"></script>-->
+ <script type="text/javascript">
+ hljs.initHighlightingOnLoad();
+ // hljs.initLineNumbersOnLoad();
+ </script>
+
+ <!-- theme related -->
+ <script type="text/javascript" src="scripts/theme.js"></script>
+ <link id="theme-css" rel="stylesheet" type="text/css" href="css/theme.css">
+ <link id="code-theme-css" rel="stylesheet" type="text/css" href="hl/styles/nord.min.css">
+
+ <!-- og meta -->
+ <meta property="og:title" content="Create an XMPP server with Prosody compatible with Conversations and Movim -- Luévano's Blog"/>
+ <meta property="og:type" content="article"/>
+ <meta property="og:url" content="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html"/>
+ <meta property="og:image" content="https://static.luevano.xyz//images/b/default.png"/>
+ <meta property="og:description" content="How to create an XMPP server using Prosody on a server running Nginx. This server will be compatible with at least Conversations and Movim."/>
+ <meta property="og:locale" content="en"/>
+ <meta property="og:site_name" content="Luévano's Blog"/>
+ </head>
+
+ <body>
+ <header>
+ <nav>
+ <ul>
+ <li>
+ <a href="https://luevano.xyz/"><i class="fas fa-home" alt="Home"></i><span>Home</span></a>
+ </li>
+
+ <li>
+ <a href="https://blog.luevano.xyz/"><i class="fas fa-book-open" alt="Blog"></i><span>Blog</span></a>
+ </li>
+
+ <li>
+ <a href="https://art.luevano.xyz/"><i class="fas fa-paint-brush" alt="Art"></i><span>Art</span></a>
+ </li>
+
+ <li><i class="fab fa-git" alt="Git"></i><span>Git</span>
+ <ul>
+ <li><a href="https://git.luevano.xyz/" target="_blank"><i class="fab fa-git-alt" alt="Git-alt"></i></a></li>
+
+ <li><a href="https://github.com/luevano" target="_blank"><i class="fab fa-github" alt="Github"></i></a></li>
+
+ <li><a href="https://gitlab.com/dluevano" target="_blank"><i class="fab fa-gitlab" alt="Gitlab"></i></a></li>
+ </ul>
+ </li>
+
+ <li><i class="fas fa-box-open" alt="Stuff"></i><span>Stuff</span>
+ <ul>
+ <li><a href="https://gb.luevano.xyz/"><i class="fas fa-gamepad" alt="Gameboy"></i><span>Gameboy</span></a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+
+ <button class="theme-switcher" onclick="toggleTheme()"><i class="fas fa-moon"></i><i class="fas fa-sun"></i></button>
+ </header>
+
+ <main>
+ <h1>Create an XMPP server with Prosody compatible with Conversations and Movim</h1>
+
+ <p>Recently I set up an XMPP server (and a Matrix one, too) for my personal use and for friends if they want one; made one for <mark><a href="https://lmcj.xyz">EL ELE EME</a></mark>, for example. So, here are the notes on how I set up the server that is compatible with the <a href="https://conversations.im/">Conversations</a> app and the <a href="https://movim.eu/">Movim</a> social network. You can see my addresses in <a href="https://luevano.xyz/contact.html">contact</a> and the XMPP compliance/score of the server.</p>
+<p>One of the best resources I found that helped me a lot was <a href="https://community.hetzner.com/tutorials/prosody-debian9">Installing and Configuring Prosody XMPP Server on Debian 9</a>, and of course the <a href="https://wiki.archlinux.org/title/Prosody">Arch Wiki</a> and the <a href="https://prosody.im/">oficial documentation</a>.</p>
+<p>As with my other entries, this is under a server running Arch Linux, with the Nginx web server and Certbot certificates. And all commands here are executed as root (unless specified otherwise)</p>
+<h2 id="prerequisites">Prerequisites</h2>
+<p>Same as with my other entries (<a href="https://luevano.xyz/a/website_with_nginx.html">website</a>, <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html">mail</a> and <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">git</a>) plus:</p>
+<ul>
+<li><strong>A</strong> and (optionally) <strong>AAA</strong> DNS records for:<ul>
+<li><code>xmpp</code>: the actual XMPP server and the file upload service.</li>
+<li><code>muc</code> (or <code>conference</code>): for multi-user chats.</li>
+<li><code>pubsub</code>: the publish-subscribe service.</li>
+<li><code>proxy</code>: a proxy in case one of the users needs it.</li>
+<li><code>vjud</code>: user directory.</li>
+</ul>
+</li>
+<li>(Optionally, but recommended) the following <strong>SRV</strong> DNS records; make sure it is pointing to an <strong>A</strong> or <strong>AAA</strong> record (matching the records from the last point, for example):<ul>
+<li><code>_xmpp-client._tcp.**your.domain**.</code> for port <code>5222</code> pointing to <code>xmpp.**your.domain**.</code></li>
+<li><code>_xmpp-server._tcp.**your.domain**.</code> for port <code>5269</code> pointing to <code>xmpp.**your.domain**.</code></li>
+<li><code>_xmpp-server._tcp.muc.**your.domain**.</code> for port <code>5269</code> pointing to <code>xmpp.**your.domain**.</code></li>
+</ul>
+</li>
+<li>SSL certificates for the previous subdomains; similar that with my other entries just create the appropriate <code>prosody.conf</code> (where <code>server_name</code> will be all the subdomains defined above) file and run <code>certbot --nginx</code>. You can find the example configuration file almost at the end of this entry.</li>
+<li>Email addresses for <code>admin</code>, <code>abuse</code>, <code>contact</code>, <code>security</code>, etc. Or use your own email for all of them, doesn&rsquo;t really matter much as long as you define them in the configuration and are valid, I have aliases so those emails are forwarded to me.</li>
+<li>Allow ports 5000, 5222, 5269, 5280 and 5281 for <a href="https://prosody.im/doc/ports">Prosody</a> and, 3478 and 5349 for <a href="https://webrtc.org/getting-started/turn-server">Turnserver</a> which are the defaults for <code>coturn</code>.</li>
+</ul>
+<h2 id="prosody">Prosody</h2>
+<p><a href="https://wiki.archlinux.org/title/Prosody">Prosody</a> is an implementation of the XMPP protocol that is flexible and extensible.</p>
+<p>Install the <code>prosody</code> package (with optional dependencies) and the <code>mercurial</code> package:</p>
+<pre><code class="language-sh">pacman -S prosody, mercurial, lua52-sec, lua52-dbi, lua52-zlib
+</code></pre>
+<p>We need mercurial to be able to download and update the extra modules needed to make the server compliant with <code>conversations.im</code> and <code>mov.im</code>. Go to <code>/var/lib/prosody</code>, clone the latest Prosody modules repository and prepare the directories:</p>
+<pre><code class="language-sh">cd /var/lib/prosody
+hg clone https://hg.prosody.im/prosody-modules modules-available
+mkdir modules-enabled
+</code></pre>
+<p>You can see that I follow a similar approach that I used with Nginx and the server configuration, where I have all the modules available in a directory, and make a symlink to another to keep track of what is being used. You can update the repository by running <code>hg pull --update</code> while inside the <code>modules-available</code> directory (similar to Git).</p>
+<p>Make symbolic links to the following modules:</p>
+<pre><code>ln -s /var/lib/prosody/modules-available/MODULE_NAME /var/lib/prosody/modules-enabled/
+...
+</code></pre>
+<ul>
+<li>Modules:<ul>
+<li><code>mod_bookmarks</code></li>
+<li><code>mod_cache_c2s_caps</code></li>
+<li><code>mod_checkcerts</code></li>
+<li><code>mod_cloud_notify</code></li>
+<li><code>mod_csi_battery_saver</code></li>
+<li><code>mod_default_bookmarks</code></li>
+<li><code>mod_external_services</code></li>
+<li><code>mod_http_avatar</code></li>
+<li><code>mod_http_pep_avatar</code></li>
+<li><code>mod_http_upload</code></li>
+<li><code>mod_http_upload_external</code></li>
+<li><code>mod_idlecompat</code></li>
+<li><code>mod_muc_limits</code></li>
+<li><code>mod_muc_mam_hints</code></li>
+<li><code>mod_muc_mention_notifications</code></li>
+<li><code>mod_presence_cache</code></li>
+<li><code>mod_pubsub_feeds</code></li>
+<li><code>mod_pubsub_text_interface</code></li>
+<li><code>mod_smacks</code></li>
+<li><code>mod_strict_https</code></li>
+<li><code>mod_vcard_muc</code></li>
+<li><code>mod_vjud</code></li>
+<li><code>mod_watchuntrusted</code></li>
+</ul>
+</li>
+</ul>
+<p>And add other modules if needed, but these work for the apps that I mentioned. You should also change the permissions for these files:</p>
+<pre><code class="language-sh">chown -R prosody:prosody /var/lib/prosody
+</code></pre>
+<p>Now, configure the server by editing the <code>/etc/prosody/prosody.cfg.lua</code> file. It&rsquo;s a bit tricky to configure, so here is my configuration file (lines starting with <code>--</code> are comments). Make sure to change according to your domain, and maybe preferences. Read each line and each comment to know what&rsquo;s going on, It&rsquo;s easier to explain it with comments in the file itself than strip it in a lot of pieces.</p>
+<p>And also, note that the configuration file has a &ldquo;global&rdquo; section and a per &ldquo;virtual server&rdquo;/&rdquo;component&rdquo; section, basically everything above all the VirtualServer/Component sections are global, and bellow each VirtualServer/Component, corresponds to that section.</p>
+<pre><code>-- important for systemd
+daemonize = true
+pidfile = &quot;/run/prosody/prosody.pid&quot;
+
+-- or your account, not that this is an xmpp jid, not email
+admins = { &quot;admin@your.domain&quot; }
+
+contact_info = {
+ abuse = { &quot;mailto:abuse@your.domain&quot;, &quot;xmpp:abuse@your.domain&quot; };
+ admin = { &quot;mailto:admin@your.domain&quot;, &quot;xmpp:admin@your.domain&quot; };
+ admin = { &quot;mailto:feedback@your.domain&quot;, &quot;xmpp:feedback@your.domain&quot; };
+ security = { &quot;mailto:security@your.domain&quot; };
+ support = { &quot;mailto:support@your.domain&quot;, &quot;xmpp:support@muc.your.domain&quot; };
+}
+
+-- so prosody look up the plugins we added
+plugin_paths = { &quot;/var/lib/prosody/modules-enabled&quot; }
+
+modules_enabled = {
+ -- Generally required
+ &quot;roster&quot;; -- Allow users to have a roster. Recommended ;)
+ &quot;saslauth&quot;; -- Authentication for clients and servers. Recommended if you want to log in.
+ &quot;tls&quot;; -- Add support for secure TLS on c2s/s2s connections
+ &quot;dialback&quot;; -- s2s dialback support
+ &quot;disco&quot;; -- Service discovery
+ -- Not essential, but recommended
+ &quot;carbons&quot;; -- Keep multiple clients in sync
+ &quot;pep&quot;; -- Enables users to publish their avatar, mood, activity, playing music and more
+ &quot;private&quot;; -- Private XML storage (for room bookmarks, etc.)
+ &quot;blocklist&quot;; -- Allow users to block communications with other users
+ &quot;vcard4&quot;; -- User profiles (stored in PEP)
+ &quot;vcard_legacy&quot;; -- Conversion between legacy vCard and PEP Avatar, vcard
+ &quot;limits&quot;; -- Enable bandwidth limiting for XMPP connections
+ -- Nice to have
+ &quot;version&quot;; -- Replies to server version requests
+ &quot;uptime&quot;; -- Report how long server has been running
+ &quot;time&quot;; -- Let others know the time here on this server
+ &quot;ping&quot;; -- Replies to XMPP pings with pongs
+ &quot;register&quot;; -- Allow users to register on this server using a client and change passwords
+ &quot;mam&quot;; -- Store messages in an archive and allow users to access it
+ &quot;csi_simple&quot;; -- Simple Mobile optimizations
+ -- Admin interfaces
+ &quot;admin_adhoc&quot;; -- Allows administration via an XMPP client that supports ad-hoc commands
+ --&quot;admin_telnet&quot;; -- Opens telnet console interface on localhost port 5582
+ -- HTTP modules
+ &quot;http&quot;; -- Explicitly enable http server.
+ &quot;bosh&quot;; -- Enable BOSH clients, aka &quot;Jabber over HTTP&quot;
+ &quot;websocket&quot;; -- XMPP over WebSockets
+ &quot;http_files&quot;; -- Serve static files from a directory over HTTP
+ -- Other specific functionality
+ &quot;groups&quot;; -- Shared roster support
+ &quot;server_contact_info&quot;; -- Publish contact information for this service
+ &quot;announce&quot;; -- Send announcement to all online users
+ &quot;welcome&quot;; -- Welcome users who register accounts
+ &quot;watchregistrations&quot;; -- Alert admins of registrations
+ &quot;motd&quot;; -- Send a message to users when they log in
+ --&quot;legacyauth&quot;; -- Legacy authentication. Only used by some old clients and bots.
+ --&quot;s2s_bidi&quot;; -- not yet implemented, have to wait for v0.12
+ &quot;bookmarks&quot;;
+ &quot;checkcerts&quot;;
+ &quot;cloud_notify&quot;;
+ &quot;csi_battery_saver&quot;;
+ &quot;default_bookmarks&quot;;
+ &quot;http_avatar&quot;;
+ &quot;idlecompat&quot;;
+ &quot;presence_cache&quot;;
+ &quot;smacks&quot;;
+ &quot;strict_https&quot;;
+ --&quot;pep_vcard_avatar&quot;; -- not compatible with this version of pep, wait for v0.12
+ &quot;watchuntrusted&quot;;
+ &quot;webpresence&quot;;
+ &quot;external_services&quot;;
+ }
+
+-- only if you want to disable some modules
+modules_disabled = {
+ -- &quot;offline&quot;; -- Store offline messages
+ -- &quot;c2s&quot;; -- Handle client connections
+ -- &quot;s2s&quot;; -- Handle server-to-server connections
+ -- &quot;posix&quot;; -- POSIX functionality, sends server to background, enables syslog, etc.
+}
+
+external_services = {
+ {
+ type = &quot;stun&quot;,
+ transport = &quot;udp&quot;,
+ host = &quot;proxy.your.domain&quot;,
+ port = 3478
+ }, {
+ type = &quot;turn&quot;,
+ transport = &quot;udp&quot;,
+ host = &quot;proxy.your.domain&quot;,
+ port = 3478,
+ -- you could decide this now or come back later when you install coturn
+ secret = &quot;YOUR SUPER SECRET TURN PASSWORD&quot;
+ }
+}
+
+--- general global configuration
+http_ports = { 5280 }
+http_interfaces = { &quot;*&quot;, &quot;::&quot; }
+
+https_ports = { 5281 }
+https_interfaces = { &quot;*&quot;, &quot;::&quot; }
+
+proxy65_ports = { 5000 }
+proxy65_interfaces = { &quot;*&quot;, &quot;::&quot; }
+
+http_default_host = &quot;xmpp.your.domain&quot;
+http_external_url = &quot;https://xmpp.your.domain/&quot;
+-- or if you want to have it somewhere else, change this
+https_certificate = &quot;/etc/prosody/certs/xmpp.your.domain.crt&quot;
+
+hsts_header = &quot;max-age=31556952&quot;
+
+cross_domain_bosh = true
+--consider_bosh_secure = true
+cross_domain_websocket = true
+--consider_websocket_secure = true
+
+trusted_proxies = { &quot;127.0.0.1&quot;, &quot;::1&quot;, &quot;192.169.1.1&quot; }
+
+pep_max_items = 10000
+
+-- this is disabled by default, and I keep it like this, depends on you
+--allow_registration = true
+
+-- you might want this options as they are
+c2s_require_encryption = true
+s2s_require_encryption = true
+s2s_secure_auth = false
+--s2s_insecure_domains = { &quot;insecure.example&quot; }
+--s2s_secure_domains = { &quot;jabber.org&quot; }
+
+-- where the certificates are stored (/etc/prosody/certs by default)
+certificates = &quot;certs&quot;
+checkcerts_notify = 7 -- ( in days )
+
+-- rate limits on connections to the server, these are my personal settings, because by default they were limited to something like 30kb/s
+limits = {
+ c2s = {
+ rate = &quot;2000kb/s&quot;;
+ };
+ s2sin = {
+ rate = &quot;5000kb/s&quot;;
+ };
+ s2sout = {
+ rate = &quot;5000kb/s&quot;;
+ };
+}
+
+-- again, this could be yourself, it is a jid
+unlimited_jids = { &quot;admin@your.domain&quot; }
+
+authentication = &quot;internal_hashed&quot;
+
+-- if you don't want to use sql, change it to internal and comment the second line
+-- since this is optional, i won't describe how to setup mysql or setup the user/database, that would be out of the scope for this entry
+storage = &quot;sql&quot;
+sql = { driver = &quot;MySQL&quot;, database = &quot;prosody&quot;, username = &quot;prosody&quot;, password = &quot;PROSODY USER SECRET PASSWORD&quot;, host = &quot;localhost&quot; }
+
+archive_expires_after = &quot;4w&quot; -- configure message archive
+max_archive_query_results = 20;
+mam_smart_enable = true
+default_archive_policy = &quot;roster&quot; -- archive only messages from users who are in your roster
+
+-- normally you would like at least one log file of certain level, but I keep all of them, the default is only the info = &quot;*syslog&quot; one
+log = {
+ info = &quot;*syslog&quot;;
+ warn = &quot;prosody.warn&quot;;
+ error = &quot;prosody.err&quot;;
+ debug = &quot;prosody.debug&quot;;
+ -- &quot;*console&quot;; -- Needs daemonize=false
+}
+
+-- cloud_notify
+push_notification_with_body = false -- Whether or not to send the message body to remote pubsub node
+push_notification_with_sender = false -- Whether or not to send the message sender to remote pubsub node
+push_max_errors = 5 -- persistent push errors are tolerated before notifications for the identifier in question are disabled
+push_max_devices = 5 -- number of allowed devices per user
+
+-- by default every user on this server will join these muc rooms
+default_bookmarks = {
+ { jid = &quot;room@muc.your.domain&quot;, name = &quot;The Room&quot; };
+ { jid = &quot;support@muc.your.domain&quot;, name = &quot;Support Room&quot; };
+}
+
+-- could be your jid
+untrusted_fail_watchers = { &quot;admin@your.domain&quot; }
+untrusted_fail_notification = &quot;Establishing a secure connection from $from_host to $to_host failed. Certificate hash: $sha1. $errors&quot;
+
+----------- Virtual hosts -----------
+VirtualHost &quot;your.domain&quot;
+ name = &quot;Prosody&quot;
+ http_host = &quot;xmpp.your.domain&quot;
+
+disco_items = {
+ { &quot;your.domain&quot;, &quot;Prosody&quot; };
+ { &quot;muc.your.domain&quot;, &quot;MUC Service&quot; };
+ { &quot;pubsub.your.domain&quot;, &quot;Pubsub Service&quot; };
+ { &quot;proxy.your.domain&quot;, &quot;SOCKS5 Bytestreams Service&quot; };
+ { &quot;vjud.your.domain&quot;, &quot;User Directory&quot; };
+}
+
+
+-- Multi-user chat
+Component &quot;muc.your.domain&quot; &quot;muc&quot;
+ name = &quot;MUC Service&quot;
+ modules_enabled = {
+ --&quot;bob&quot;; -- not compatible with this version of Prosody
+ &quot;muc_limits&quot;;
+ &quot;muc_mam&quot;; -- message archive in muc, again, a placeholder
+ &quot;muc_mam_hints&quot;;
+ &quot;muc_mention_notifications&quot;;
+ &quot;vcard_muc&quot;;
+ }
+
+ restrict_room_creation = false
+
+ muc_log_by_default = true
+ muc_log_presences = false
+ log_all_rooms = false
+ muc_log_expires_after = &quot;1w&quot;
+ muc_log_cleanup_interval = 4 * 60 * 60
+
+
+-- Upload
+Component &quot;xmpp.your.domain&quot; &quot;http_upload&quot;
+ name = &quot;Upload Service&quot;
+ http_host= &quot;xmpp.your.domain&quot;
+ -- you might want to change this, these are numbers in bytes, so 10MB and 100MB respectively
+ http_upload_file_size_limit = 1024*1024*10
+ http_upload_quota = 1024*1024*100
+
+
+-- Pubsub
+Component &quot;pubsub.your.domain&quot; &quot;pubsub&quot;
+ name = &quot;Pubsub Service&quot;
+ pubsub_max_items = 10000
+ modules_enabled = {
+ &quot;pubsub_feeds&quot;;
+ &quot;pubsub_text_interface&quot;;
+ }
+
+ -- personally i don't have any feeds configured
+ feeds = {
+ -- The part before = is used as PubSub node
+ --planet_jabber = &quot;http://planet.jabber.org/atom.xml&quot;;
+ --prosody_blog = &quot;http://blog.prosody.im/feed/atom.xml&quot;;
+ }
+
+
+-- Proxy
+Component &quot;proxy.your.domain&quot; &quot;proxy65&quot;
+ name = &quot;SOCKS5 Bytestreams Service&quot;
+ proxy65_address = &quot;proxy.your.domain&quot;
+
+
+-- Vjud, user directory
+Component &quot;vjud.your.domain&quot; &quot;vjud&quot;
+ name = &quot;User Directory&quot;
+ vjud_mode = &quot;opt-in&quot;
+</code></pre>
+<p>You <mark>HAVE</mark> to read all of the configuration file, because there are a lot of things that you need to change to make it work with your server/domain. Test the configuration file with:</p>
+<pre><code class="language-sh">luac5.2 -p /etc/prosody/prosody.cfg.lua
+</code></pre>
+<p>Notice that by default <code>prosody</code> will look up certificates that look like <code>sub.your.domain</code>, but if you get the certificates as myself, you&rsquo;ll have a single certificate for all subdomains, and by default it is in <code>/etc/letsencrypt/live</code>, which has some strict permissions. So, to import them you can run:</p>
+<pre><code class="language-sh">prosodyctl --root cert import /etc/letsencrypt/live
+</code></pre>
+<p>Ignore the complaining about not finding the subdomain certificates and note that you will have to run that command on each certificate renewal, to automate this, add the <code>--deploy-hook</code> flag to your automated Certbot renewal system; for me it&rsquo;s a <code>systemd</code> timer with the following <code>certbot.service</code>:</p>
+<pre><code class="language-ini">[Unit]
+Description=Let's Encrypt renewal
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/certbot renew --quiet --agree-tos --deploy-hook &quot;systemctl reload nginx.service &amp;&amp; prosodyctl --root cert import /etc/letsencrypt/live&quot;
+</code></pre>
+<p>And if you don&rsquo;t have it already, the <code>certbot.timer</code>:</p>
+<pre><code class="language-ini">[Unit]
+Description=Twice daily renewal of Let's Encrypt's certificates
+
+[Timer]
+OnCalendar=0/12:00:00
+RandomizedDelaySec=1h
+Persistent=true
+
+[Install]
+WantedBy=timers.target
+</code></pre>
+<p>Also, go to the <code>certs</code> directory and make the appropriate symbolic links:</p>
+<pre><code class="language-sh">cd /etc/prosody/certs
+ln -s your.domain.crt SUBDOMAIN.your.domain.crt
+ln -s your.domain.key SUBDOMAIN.your.domain.key
+...
+</code></pre>
+<p>That&rsquo;s basically all the configuration that needs Prosody itself, but we still have to configure Nginx and Coturn before starting/enabling the <code>prosody</code> service.</p>
+<h2 id="nginx-configuration-file">Nginx configuration file</h2>
+<p>Since this is not an ordinary configuration file I&rsquo;m going to describe this too. Your <code>prosody.conf</code> file should have the following location blocks under the main server block (the one that listens to HTTPS):</p>
+<pre><code class="language-nginx"># HTTPS server block
+server {
+ root /var/www/prosody/;
+ server_name xmpp.luevano.xyz muc.luevano.xyz pubsub.luevano.xyz vjud.luevano.xyz proxy.luevano.xyz;
+ index index.html;
+
+ # for extra https discovery (XEP-0256)
+ location /.well-known/acme-challenge {
+ allow all;
+ }
+
+ # bosh specific
+ location /http-bind {
+ proxy_pass https://localhost:5281/http-bind;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # websocket specific
+ location /xmpp-websocket {
+ proxy_pass https://localhost:5281/xmpp-websocket;
+
+ proxy_http_version 1.1;
+ proxy_set_header Connection &quot;Upgrade&quot;;
+ proxy_set_header Upgrade $http_upgrade;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_read_timeout 900s;
+ }
+
+ # general proxy
+ location / {
+ proxy_pass https://localhost:5281;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Real-IP $remote_addr;
+ }
+ ...
+ # Certbot stuff
+}
+# HTTP server block (the one that certbot creates)
+server {
+ ...
+}
+</code></pre>
+<p>Also, you need to add the following to your actual <code>your.domain</code> (this cannot be a subdomain) configuration file:</p>
+<pre><code class="language-nginx">server {
+ ...
+ location /.well-known/host-meta {
+ default_type 'application/xrd+xml';
+ add_header Access-Control-Allow-Origin '*' always;
+ }
+
+ location /.well-known/host-meta.json {
+ default_type 'application/jrd+json';
+ add_header Access-Control-Allow-Origin '*' always;
+ }
+ ...
+}
+</code></pre>
+<p>And you will need the following <code>host-meta</code> and <code>host-meta.json</code> files inside the <code>.well-known/acme-challenge</code> directory for <code>your.domain</code> (following my nomenclature: <code>/var/www/yourdomaindir/.well-known/acme-challenge/</code>).</p>
+<p>For <code>host-meta</code> file:</p>
+<pre><code class="language-xml">&lt;?xml version='1.0' encoding='utf-8'?&gt;
+&lt;XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'&gt;
+ &lt;Link rel=&quot;urn:xmpp:alt-connections:xbosh&quot;
+ href=&quot;https://xmpp.your.domain:5281/http-bind&quot; /&gt;
+ &lt;Link rel=&quot;urn:xmpp:alt-connections:websocket&quot;
+ href=&quot;wss://xmpp.your.domain:5281/xmpp-websocket&quot; /&gt;
+&lt;/XRD&gt;
+</code></pre>
+<p>And <code>host-meta.json</code> file:</p>
+<pre><code class="language-json">{
+ &quot;links&quot;: [
+ {
+ &quot;rel&quot;: &quot;urn:xmpp:alt-connections:xbosh&quot;,
+ &quot;href&quot;: &quot;https://xmpp.your.domain:5281/http-bind&quot;
+ },
+ {
+ &quot;rel&quot;: &quot;urn:xmpp:alt-connections:websocket&quot;,
+ &quot;href&quot;: &quot;wss://xmpp.your.domain:5281/xmpp-websocket&quot;
+ }
+ ]
+}
+</code></pre>
+<p>Remember to have your <code>prosody.conf</code> file symlinked (or discoverable by Nginx) to the <code>sites-enabled</code> directory. You can now restart your <code>nginx</code> service (and test the configuration, optionally):</p>
+<pre><code class="language-sh">nginx -t
+systemctl restart nginx.service
+</code></pre>
+<h2 id="coturn">Coturn</h2>
+<p><a href="https://github.com/coturn/coturn">Coturn</a> is the implementation of TURN and STUN server, which in general is for (at least in the XMPP world) voice support and external service discovery.</p>
+<p>Install the <code>coturn</code> package:</p>
+<pre><code class="language-sh">pacman -S coturn
+</code></pre>
+<p>You can modify the configuration file (located at <code>/etc/turnserver/turnserver.conf</code>) as desired, but at least you need to make the following changes (uncomment or edit):</p>
+<pre><code>use-auth-secret
+realm=proxy.your.domain
+static-auth-secret=YOUR SUPER SECRET TURN PASSWORD
+</code></pre>
+<p>I&rsquo;m sure there is more configuration to be made, like using SQL to store data and whatnot, but for now this is enough for me. Note that you may not have some functionality that&rsquo;s needed to create dynamic users to use the TURN server, and to be honest I haven&rsquo;t tested this since I don&rsquo;t use this feature in my XMPP clients, but if it doesn&rsquo;t work, or you know of an error or missing configuration don&rsquo;t hesitate to <a href="https://luevano.xyz/contact.html">contact me</a>.</p>
+<p>Start/enable the <code>turnserver</code> service:</p>
+<pre><code class="language-sh">systemctl start turnserver.service
+systemctl enable turnserver.service
+</code></pre>
+<p>You can test if your TURN server works at <a href="https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/">Trickle ICE</a>. You may need to add a user in the <code>turnserver.conf</code> to test this.</p>
+<h2 id="wrapping-up">Wrapping up</h2>
+<p>At this point you should have a working XMPP server, start/enable the <code>prosody</code> service now:</p>
+<pre><code>systemctl start prosody.service
+systemctl enable prosody.service
+</code></pre>
+<p>And you can add your first user with the <code>prosodyctl</code> command (it will prompt you to add a password):</p>
+<pre><code>prosodyctl adduser user@your.domain
+</code></pre>
+<p>You may want to add a <code>compliance</code> user, so you can check if your server is set up correctly. To do so, go to <a href="https://compliance.conversations.im/add/">XMPP Compliance Tester</a> and enter the <code>compliance</code> user credentials. It should have similar compliance score to mine:</p>
+<p><a href='https://compliance.conversations.im/server/luevano.xyz'><img src='https://compliance.conversations.im/badge/luevano.xyz'></a></p>
+<p>Additionally, you can test the security of your server in <a href="https://xmpp.net/index.php">IM Observatory</a>, here you only need to specify your <code>domain.name</code> (not <code>xmpp.domain.name</code>, if you set up the <strong>SRV</strong> DNS records correctly). Again, it should have a similar score to mine:</p>
+<p><a href='https://xmpp.net/result.php?domain=luevano.xyz&amp;type=client'><img src='https://xmpp.net/badge.php?domain=luevano.xyz' alt='xmpp.net score' /></a></p>
+<p>You can now log in into your XMPP client of choice, if it asks for the server it should be <code>xmpp.your.domain</code> (or <code>your.domain</code> for some clients) and your login credentials <code>you@your.domain</code> and the password you chose (which you can change in most clients).</p>
+<p>That&rsquo;s it, send me a message <a href="xmpp:david@luevano.xyz">david@luevano.xyz</a> if you were able to set up the server successfully.</p>
+
+ <div class="page-nav">
+
+ <span class="index">
+ <a href="https://blog.luevano.xyz" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ <span class="previous">
+ <a href="https://blog.luevano.xyz/a/acomodada_la_pagina_de_arte.html" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+</div>
+
+
+ <hr>
+ <div class="article-info">
+ <p>By David Luévano</p>
+ <p>Created: Wed, Jun 09, 2021 @ 05:24 UTC</p>
+ <div class="article-tags">
+ <p>Tags:
+<a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a> </p>
+</div>
+
+ </div>
+ </main>
+
+ <footer>
+ <span>
+ <i class="fas fa-address-card" alt="Contact"></i>
+ <a href="https://luevano.xyz/contact.html">Contact</a>
+ </span>
+
+ <span>
+ <i class="fas fa-donate" alt="Donate"></i>
+ <a href="https://luevano.xyz/donate.html">Donate</a>
+ </span>
+
+ <span>
+ <i class="fas fa-rss" alt="RSS"></i>
+ <a target="_blank" href="https://blog.luevano.xyz/rss.xml">RSS</a>
+ </span>
+
+ <br>
+ <span class="created-with">
+ <i class="fas fa-hammer" alt="Hammer"></i>
+ Created with <a href="https://github.com/luevano/pyssg">pyssg</a>
+ </span>
+
+ <br>
+ <span class="copyright">
+ Copyright <i class="far fa-copyright" alt="Copyright"></i> 2021 David Luévano Alvarado
+ </span>
+ </footer>
+ </body>
+</html> \ No newline at end of file
diff --git a/blog/dst/index.html b/blog/dst/index.html
index d6507e1..adad582 100644
--- a/blog/dst/index.html
+++ b/blog/dst/index.html
@@ -95,6 +95,7 @@
<h2>Articles</h2>
<ul class="page-list">
<h3>June 2021</h3>
+ <li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
<li>Jun 06 - <a href="https://blog.luevano.xyz/a/acomodada_la_pagina_de_arte.html">Al fin ya me acomodé la página pa' los dibujos</a></li>
<li>Jun 04 - <a href="https://blog.luevano.xyz/a/asi_nomas_esta_quedando.html">Así nomás está quedando el página</a></li>
<h3>May 2021</h3>
diff --git a/blog/dst/rss.xml b/blog/dst/rss.xml
index 94e819c..dd2556d 100644
--- a/blog/dst/rss.xml
+++ b/blog/dst/rss.xml
@@ -13,8 +13,8 @@
<copyright>Copyright 2021 David Luévano Alvarado</copyright>
<managingEditor>david@luevano.xyz (David Luévano Alvarado)</managingEditor>
<webMaster>david@luevano.xyz (David Luévano Alvarado)</webMaster>
- <pubDate>Tue, 08 Jun 2021 06:57:28 GMT</pubDate>
- <lastBuildDate>Tue, 08 Jun 2021 06:57:28 GMT</lastBuildDate>
+ <pubDate>Wed, 09 Jun 2021 05:24:56 GMT</pubDate>
+ <lastBuildDate>Wed, 09 Jun 2021 05:24:56 GMT</lastBuildDate>
<generator>pyssg v0.5.9</generator>
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
<ttl>30</ttl>
@@ -24,6 +24,513 @@
<link>https://blog.luevano.xyz</link>
</image>
<item>
+ <title>Create an XMPP server with Prosody compatible with Conversations and Movim</title>
+ <link>https://blog.luevano.xyz/a/xmpp_server_with_prosody.html</link>
+ <guid isPermaLink="true">https://blog.luevano.xyz/a/xmpp_server_with_prosody.html</guid>
+ <pubDate>Wed, 09 Jun 2021 05:24:30 GMT</pubDate>
+ <category>English</category>
+ <category>Server</category>
+ <category>Tools</category>
+ <category>Tutorial</category>
+ <description>How to create an XMPP server using Prosody on a server running Nginx. This server will be compatible with at least Conversations and Movim.</description>
+ <content:encoded><![CDATA[<p>Recently I set up an XMPP server (and a Matrix one, too) for my personal use and for friends if they want one; made one for <mark><a href="https://lmcj.xyz">EL ELE EME</a></mark>, for example. So, here are the notes on how I set up the server that is compatible with the <a href="https://conversations.im/">Conversations</a> app and the <a href="https://movim.eu/">Movim</a> social network. You can see my addresses in <a href="https://luevano.xyz/contact.html">contact</a> and the XMPP compliance/score of the server.</p>
+<p>One of the best resources I found that helped me a lot was <a href="https://community.hetzner.com/tutorials/prosody-debian9">Installing and Configuring Prosody XMPP Server on Debian 9</a>, and of course the <a href="https://wiki.archlinux.org/title/Prosody">Arch Wiki</a> and the <a href="https://prosody.im/">oficial documentation</a>.</p>
+<p>As with my other entries, this is under a server running Arch Linux, with the Nginx web server and Certbot certificates. And all commands here are executed as root (unless specified otherwise)</p>
+<h2 id="prerequisites">Prerequisites</h2>
+<p>Same as with my other entries (<a href="https://luevano.xyz/a/website_with_nginx.html">website</a>, <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html">mail</a> and <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">git</a>) plus:</p>
+<ul>
+<li><strong>A</strong> and (optionally) <strong>AAA</strong> DNS records for:<ul>
+<li><code>xmpp</code>: the actual XMPP server and the file upload service.</li>
+<li><code>muc</code> (or <code>conference</code>): for multi-user chats.</li>
+<li><code>pubsub</code>: the publish-subscribe service.</li>
+<li><code>proxy</code>: a proxy in case one of the users needs it.</li>
+<li><code>vjud</code>: user directory.</li>
+</ul>
+</li>
+<li>(Optionally, but recommended) the following <strong>SRV</strong> DNS records; make sure it is pointing to an <strong>A</strong> or <strong>AAA</strong> record (matching the records from the last point, for example):<ul>
+<li><code>_xmpp-client._tcp.**your.domain**.</code> for port <code>5222</code> pointing to <code>xmpp.**your.domain**.</code></li>
+<li><code>_xmpp-server._tcp.**your.domain**.</code> for port <code>5269</code> pointing to <code>xmpp.**your.domain**.</code></li>
+<li><code>_xmpp-server._tcp.muc.**your.domain**.</code> for port <code>5269</code> pointing to <code>xmpp.**your.domain**.</code></li>
+</ul>
+</li>
+<li>SSL certificates for the previous subdomains; similar that with my other entries just create the appropriate <code>prosody.conf</code> (where <code>server_name</code> will be all the subdomains defined above) file and run <code>certbot --nginx</code>. You can find the example configuration file almost at the end of this entry.</li>
+<li>Email addresses for <code>admin</code>, <code>abuse</code>, <code>contact</code>, <code>security</code>, etc. Or use your own email for all of them, doesn&rsquo;t really matter much as long as you define them in the configuration and are valid, I have aliases so those emails are forwarded to me.</li>
+<li>Allow ports 5000, 5222, 5269, 5280 and 5281 for <a href="https://prosody.im/doc/ports">Prosody</a> and, 3478 and 5349 for <a href="https://webrtc.org/getting-started/turn-server">Turnserver</a> which are the defaults for <code>coturn</code>.</li>
+</ul>
+<h2 id="prosody">Prosody</h2>
+<p><a href="https://wiki.archlinux.org/title/Prosody">Prosody</a> is an implementation of the XMPP protocol that is flexible and extensible.</p>
+<p>Install the <code>prosody</code> package (with optional dependencies) and the <code>mercurial</code> package:</p>
+<pre><code class="language-sh">pacman -S prosody, mercurial, lua52-sec, lua52-dbi, lua52-zlib
+</code></pre>
+<p>We need mercurial to be able to download and update the extra modules needed to make the server compliant with <code>conversations.im</code> and <code>mov.im</code>. Go to <code>/var/lib/prosody</code>, clone the latest Prosody modules repository and prepare the directories:</p>
+<pre><code class="language-sh">cd /var/lib/prosody
+hg clone https://hg.prosody.im/prosody-modules modules-available
+mkdir modules-enabled
+</code></pre>
+<p>You can see that I follow a similar approach that I used with Nginx and the server configuration, where I have all the modules available in a directory, and make a symlink to another to keep track of what is being used. You can update the repository by running <code>hg pull --update</code> while inside the <code>modules-available</code> directory (similar to Git).</p>
+<p>Make symbolic links to the following modules:</p>
+<pre><code>ln -s /var/lib/prosody/modules-available/MODULE_NAME /var/lib/prosody/modules-enabled/
+...
+</code></pre>
+<ul>
+<li>Modules:<ul>
+<li><code>mod_bookmarks</code></li>
+<li><code>mod_cache_c2s_caps</code></li>
+<li><code>mod_checkcerts</code></li>
+<li><code>mod_cloud_notify</code></li>
+<li><code>mod_csi_battery_saver</code></li>
+<li><code>mod_default_bookmarks</code></li>
+<li><code>mod_external_services</code></li>
+<li><code>mod_http_avatar</code></li>
+<li><code>mod_http_pep_avatar</code></li>
+<li><code>mod_http_upload</code></li>
+<li><code>mod_http_upload_external</code></li>
+<li><code>mod_idlecompat</code></li>
+<li><code>mod_muc_limits</code></li>
+<li><code>mod_muc_mam_hints</code></li>
+<li><code>mod_muc_mention_notifications</code></li>
+<li><code>mod_presence_cache</code></li>
+<li><code>mod_pubsub_feeds</code></li>
+<li><code>mod_pubsub_text_interface</code></li>
+<li><code>mod_smacks</code></li>
+<li><code>mod_strict_https</code></li>
+<li><code>mod_vcard_muc</code></li>
+<li><code>mod_vjud</code></li>
+<li><code>mod_watchuntrusted</code></li>
+</ul>
+</li>
+</ul>
+<p>And add other modules if needed, but these work for the apps that I mentioned. You should also change the permissions for these files:</p>
+<pre><code class="language-sh">chown -R prosody:prosody /var/lib/prosody
+</code></pre>
+<p>Now, configure the server by editing the <code>/etc/prosody/prosody.cfg.lua</code> file. It&rsquo;s a bit tricky to configure, so here is my configuration file (lines starting with <code>--</code> are comments). Make sure to change according to your domain, and maybe preferences. Read each line and each comment to know what&rsquo;s going on, It&rsquo;s easier to explain it with comments in the file itself than strip it in a lot of pieces.</p>
+<p>And also, note that the configuration file has a &ldquo;global&rdquo; section and a per &ldquo;virtual server&rdquo;/&rdquo;component&rdquo; section, basically everything above all the VirtualServer/Component sections are global, and bellow each VirtualServer/Component, corresponds to that section.</p>
+<pre><code>-- important for systemd
+daemonize = true
+pidfile = &quot;/run/prosody/prosody.pid&quot;
+
+-- or your account, not that this is an xmpp jid, not email
+admins = { &quot;admin@your.domain&quot; }
+
+contact_info = {
+ abuse = { &quot;mailto:abuse@your.domain&quot;, &quot;xmpp:abuse@your.domain&quot; };
+ admin = { &quot;mailto:admin@your.domain&quot;, &quot;xmpp:admin@your.domain&quot; };
+ admin = { &quot;mailto:feedback@your.domain&quot;, &quot;xmpp:feedback@your.domain&quot; };
+ security = { &quot;mailto:security@your.domain&quot; };
+ support = { &quot;mailto:support@your.domain&quot;, &quot;xmpp:support@muc.your.domain&quot; };
+}
+
+-- so prosody look up the plugins we added
+plugin_paths = { &quot;/var/lib/prosody/modules-enabled&quot; }
+
+modules_enabled = {
+ -- Generally required
+ &quot;roster&quot;; -- Allow users to have a roster. Recommended ;)
+ &quot;saslauth&quot;; -- Authentication for clients and servers. Recommended if you want to log in.
+ &quot;tls&quot;; -- Add support for secure TLS on c2s/s2s connections
+ &quot;dialback&quot;; -- s2s dialback support
+ &quot;disco&quot;; -- Service discovery
+ -- Not essential, but recommended
+ &quot;carbons&quot;; -- Keep multiple clients in sync
+ &quot;pep&quot;; -- Enables users to publish their avatar, mood, activity, playing music and more
+ &quot;private&quot;; -- Private XML storage (for room bookmarks, etc.)
+ &quot;blocklist&quot;; -- Allow users to block communications with other users
+ &quot;vcard4&quot;; -- User profiles (stored in PEP)
+ &quot;vcard_legacy&quot;; -- Conversion between legacy vCard and PEP Avatar, vcard
+ &quot;limits&quot;; -- Enable bandwidth limiting for XMPP connections
+ -- Nice to have
+ &quot;version&quot;; -- Replies to server version requests
+ &quot;uptime&quot;; -- Report how long server has been running
+ &quot;time&quot;; -- Let others know the time here on this server
+ &quot;ping&quot;; -- Replies to XMPP pings with pongs
+ &quot;register&quot;; -- Allow users to register on this server using a client and change passwords
+ &quot;mam&quot;; -- Store messages in an archive and allow users to access it
+ &quot;csi_simple&quot;; -- Simple Mobile optimizations
+ -- Admin interfaces
+ &quot;admin_adhoc&quot;; -- Allows administration via an XMPP client that supports ad-hoc commands
+ --&quot;admin_telnet&quot;; -- Opens telnet console interface on localhost port 5582
+ -- HTTP modules
+ &quot;http&quot;; -- Explicitly enable http server.
+ &quot;bosh&quot;; -- Enable BOSH clients, aka &quot;Jabber over HTTP&quot;
+ &quot;websocket&quot;; -- XMPP over WebSockets
+ &quot;http_files&quot;; -- Serve static files from a directory over HTTP
+ -- Other specific functionality
+ &quot;groups&quot;; -- Shared roster support
+ &quot;server_contact_info&quot;; -- Publish contact information for this service
+ &quot;announce&quot;; -- Send announcement to all online users
+ &quot;welcome&quot;; -- Welcome users who register accounts
+ &quot;watchregistrations&quot;; -- Alert admins of registrations
+ &quot;motd&quot;; -- Send a message to users when they log in
+ --&quot;legacyauth&quot;; -- Legacy authentication. Only used by some old clients and bots.
+ --&quot;s2s_bidi&quot;; -- not yet implemented, have to wait for v0.12
+ &quot;bookmarks&quot;;
+ &quot;checkcerts&quot;;
+ &quot;cloud_notify&quot;;
+ &quot;csi_battery_saver&quot;;
+ &quot;default_bookmarks&quot;;
+ &quot;http_avatar&quot;;
+ &quot;idlecompat&quot;;
+ &quot;presence_cache&quot;;
+ &quot;smacks&quot;;
+ &quot;strict_https&quot;;
+ --&quot;pep_vcard_avatar&quot;; -- not compatible with this version of pep, wait for v0.12
+ &quot;watchuntrusted&quot;;
+ &quot;webpresence&quot;;
+ &quot;external_services&quot;;
+ }
+
+-- only if you want to disable some modules
+modules_disabled = {
+ -- &quot;offline&quot;; -- Store offline messages
+ -- &quot;c2s&quot;; -- Handle client connections
+ -- &quot;s2s&quot;; -- Handle server-to-server connections
+ -- &quot;posix&quot;; -- POSIX functionality, sends server to background, enables syslog, etc.
+}
+
+external_services = {
+ {
+ type = &quot;stun&quot;,
+ transport = &quot;udp&quot;,
+ host = &quot;proxy.your.domain&quot;,
+ port = 3478
+ }, {
+ type = &quot;turn&quot;,
+ transport = &quot;udp&quot;,
+ host = &quot;proxy.your.domain&quot;,
+ port = 3478,
+ -- you could decide this now or come back later when you install coturn
+ secret = &quot;YOUR SUPER SECRET TURN PASSWORD&quot;
+ }
+}
+
+--- general global configuration
+http_ports = { 5280 }
+http_interfaces = { &quot;*&quot;, &quot;::&quot; }
+
+https_ports = { 5281 }
+https_interfaces = { &quot;*&quot;, &quot;::&quot; }
+
+proxy65_ports = { 5000 }
+proxy65_interfaces = { &quot;*&quot;, &quot;::&quot; }
+
+http_default_host = &quot;xmpp.your.domain&quot;
+http_external_url = &quot;https://xmpp.your.domain/&quot;
+-- or if you want to have it somewhere else, change this
+https_certificate = &quot;/etc/prosody/certs/xmpp.your.domain.crt&quot;
+
+hsts_header = &quot;max-age=31556952&quot;
+
+cross_domain_bosh = true
+--consider_bosh_secure = true
+cross_domain_websocket = true
+--consider_websocket_secure = true
+
+trusted_proxies = { &quot;127.0.0.1&quot;, &quot;::1&quot;, &quot;192.169.1.1&quot; }
+
+pep_max_items = 10000
+
+-- this is disabled by default, and I keep it like this, depends on you
+--allow_registration = true
+
+-- you might want this options as they are
+c2s_require_encryption = true
+s2s_require_encryption = true
+s2s_secure_auth = false
+--s2s_insecure_domains = { &quot;insecure.example&quot; }
+--s2s_secure_domains = { &quot;jabber.org&quot; }
+
+-- where the certificates are stored (/etc/prosody/certs by default)
+certificates = &quot;certs&quot;
+checkcerts_notify = 7 -- ( in days )
+
+-- rate limits on connections to the server, these are my personal settings, because by default they were limited to something like 30kb/s
+limits = {
+ c2s = {
+ rate = &quot;2000kb/s&quot;;
+ };
+ s2sin = {
+ rate = &quot;5000kb/s&quot;;
+ };
+ s2sout = {
+ rate = &quot;5000kb/s&quot;;
+ };
+}
+
+-- again, this could be yourself, it is a jid
+unlimited_jids = { &quot;admin@your.domain&quot; }
+
+authentication = &quot;internal_hashed&quot;
+
+-- if you don't want to use sql, change it to internal and comment the second line
+-- since this is optional, i won't describe how to setup mysql or setup the user/database, that would be out of the scope for this entry
+storage = &quot;sql&quot;
+sql = { driver = &quot;MySQL&quot;, database = &quot;prosody&quot;, username = &quot;prosody&quot;, password = &quot;PROSODY USER SECRET PASSWORD&quot;, host = &quot;localhost&quot; }
+
+archive_expires_after = &quot;4w&quot; -- configure message archive
+max_archive_query_results = 20;
+mam_smart_enable = true
+default_archive_policy = &quot;roster&quot; -- archive only messages from users who are in your roster
+
+-- normally you would like at least one log file of certain level, but I keep all of them, the default is only the info = &quot;*syslog&quot; one
+log = {
+ info = &quot;*syslog&quot;;
+ warn = &quot;prosody.warn&quot;;
+ error = &quot;prosody.err&quot;;
+ debug = &quot;prosody.debug&quot;;
+ -- &quot;*console&quot;; -- Needs daemonize=false
+}
+
+-- cloud_notify
+push_notification_with_body = false -- Whether or not to send the message body to remote pubsub node
+push_notification_with_sender = false -- Whether or not to send the message sender to remote pubsub node
+push_max_errors = 5 -- persistent push errors are tolerated before notifications for the identifier in question are disabled
+push_max_devices = 5 -- number of allowed devices per user
+
+-- by default every user on this server will join these muc rooms
+default_bookmarks = {
+ { jid = &quot;room@muc.your.domain&quot;, name = &quot;The Room&quot; };
+ { jid = &quot;support@muc.your.domain&quot;, name = &quot;Support Room&quot; };
+}
+
+-- could be your jid
+untrusted_fail_watchers = { &quot;admin@your.domain&quot; }
+untrusted_fail_notification = &quot;Establishing a secure connection from $from_host to $to_host failed. Certificate hash: $sha1. $errors&quot;
+
+----------- Virtual hosts -----------
+VirtualHost &quot;your.domain&quot;
+ name = &quot;Prosody&quot;
+ http_host = &quot;xmpp.your.domain&quot;
+
+disco_items = {
+ { &quot;your.domain&quot;, &quot;Prosody&quot; };
+ { &quot;muc.your.domain&quot;, &quot;MUC Service&quot; };
+ { &quot;pubsub.your.domain&quot;, &quot;Pubsub Service&quot; };
+ { &quot;proxy.your.domain&quot;, &quot;SOCKS5 Bytestreams Service&quot; };
+ { &quot;vjud.your.domain&quot;, &quot;User Directory&quot; };
+}
+
+
+-- Multi-user chat
+Component &quot;muc.your.domain&quot; &quot;muc&quot;
+ name = &quot;MUC Service&quot;
+ modules_enabled = {
+ --&quot;bob&quot;; -- not compatible with this version of Prosody
+ &quot;muc_limits&quot;;
+ &quot;muc_mam&quot;; -- message archive in muc, again, a placeholder
+ &quot;muc_mam_hints&quot;;
+ &quot;muc_mention_notifications&quot;;
+ &quot;vcard_muc&quot;;
+ }
+
+ restrict_room_creation = false
+
+ muc_log_by_default = true
+ muc_log_presences = false
+ log_all_rooms = false
+ muc_log_expires_after = &quot;1w&quot;
+ muc_log_cleanup_interval = 4 * 60 * 60
+
+
+-- Upload
+Component &quot;xmpp.your.domain&quot; &quot;http_upload&quot;
+ name = &quot;Upload Service&quot;
+ http_host= &quot;xmpp.your.domain&quot;
+ -- you might want to change this, these are numbers in bytes, so 10MB and 100MB respectively
+ http_upload_file_size_limit = 1024*1024*10
+ http_upload_quota = 1024*1024*100
+
+
+-- Pubsub
+Component &quot;pubsub.your.domain&quot; &quot;pubsub&quot;
+ name = &quot;Pubsub Service&quot;
+ pubsub_max_items = 10000
+ modules_enabled = {
+ &quot;pubsub_feeds&quot;;
+ &quot;pubsub_text_interface&quot;;
+ }
+
+ -- personally i don't have any feeds configured
+ feeds = {
+ -- The part before = is used as PubSub node
+ --planet_jabber = &quot;http://planet.jabber.org/atom.xml&quot;;
+ --prosody_blog = &quot;http://blog.prosody.im/feed/atom.xml&quot;;
+ }
+
+
+-- Proxy
+Component &quot;proxy.your.domain&quot; &quot;proxy65&quot;
+ name = &quot;SOCKS5 Bytestreams Service&quot;
+ proxy65_address = &quot;proxy.your.domain&quot;
+
+
+-- Vjud, user directory
+Component &quot;vjud.your.domain&quot; &quot;vjud&quot;
+ name = &quot;User Directory&quot;
+ vjud_mode = &quot;opt-in&quot;
+</code></pre>
+<p>You <mark>HAVE</mark> to read all of the configuration file, because there are a lot of things that you need to change to make it work with your server/domain. Test the configuration file with:</p>
+<pre><code class="language-sh">luac5.2 -p /etc/prosody/prosody.cfg.lua
+</code></pre>
+<p>Notice that by default <code>prosody</code> will look up certificates that look like <code>sub.your.domain</code>, but if you get the certificates as myself, you&rsquo;ll have a single certificate for all subdomains, and by default it is in <code>/etc/letsencrypt/live</code>, which has some strict permissions. So, to import them you can run:</p>
+<pre><code class="language-sh">prosodyctl --root cert import /etc/letsencrypt/live
+</code></pre>
+<p>Ignore the complaining about not finding the subdomain certificates and note that you will have to run that command on each certificate renewal, to automate this, add the <code>--deploy-hook</code> flag to your automated Certbot renewal system; for me it&rsquo;s a <code>systemd</code> timer with the following <code>certbot.service</code>:</p>
+<pre><code class="language-ini">[Unit]
+Description=Let's Encrypt renewal
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/certbot renew --quiet --agree-tos --deploy-hook &quot;systemctl reload nginx.service &amp;&amp; prosodyctl --root cert import /etc/letsencrypt/live&quot;
+</code></pre>
+<p>And if you don&rsquo;t have it already, the <code>certbot.timer</code>:</p>
+<pre><code class="language-ini">[Unit]
+Description=Twice daily renewal of Let's Encrypt's certificates
+
+[Timer]
+OnCalendar=0/12:00:00
+RandomizedDelaySec=1h
+Persistent=true
+
+[Install]
+WantedBy=timers.target
+</code></pre>
+<p>Also, go to the <code>certs</code> directory and make the appropriate symbolic links:</p>
+<pre><code class="language-sh">cd /etc/prosody/certs
+ln -s your.domain.crt SUBDOMAIN.your.domain.crt
+ln -s your.domain.key SUBDOMAIN.your.domain.key
+...
+</code></pre>
+<p>That&rsquo;s basically all the configuration that needs Prosody itself, but we still have to configure Nginx and Coturn before starting/enabling the <code>prosody</code> service.</p>
+<h2 id="nginx-configuration-file">Nginx configuration file</h2>
+<p>Since this is not an ordinary configuration file I&rsquo;m going to describe this too. Your <code>prosody.conf</code> file should have the following location blocks under the main server block (the one that listens to HTTPS):</p>
+<pre><code class="language-nginx"># HTTPS server block
+server {
+ root /var/www/prosody/;
+ server_name xmpp.luevano.xyz muc.luevano.xyz pubsub.luevano.xyz vjud.luevano.xyz proxy.luevano.xyz;
+ index index.html;
+
+ # for extra https discovery (XEP-0256)
+ location /.well-known/acme-challenge {
+ allow all;
+ }
+
+ # bosh specific
+ location /http-bind {
+ proxy_pass https://localhost:5281/http-bind;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # websocket specific
+ location /xmpp-websocket {
+ proxy_pass https://localhost:5281/xmpp-websocket;
+
+ proxy_http_version 1.1;
+ proxy_set_header Connection &quot;Upgrade&quot;;
+ proxy_set_header Upgrade $http_upgrade;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_read_timeout 900s;
+ }
+
+ # general proxy
+ location / {
+ proxy_pass https://localhost:5281;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Real-IP $remote_addr;
+ }
+ ...
+ # Certbot stuff
+}
+# HTTP server block (the one that certbot creates)
+server {
+ ...
+}
+</code></pre>
+<p>Also, you need to add the following to your actual <code>your.domain</code> (this cannot be a subdomain) configuration file:</p>
+<pre><code class="language-nginx">server {
+ ...
+ location /.well-known/host-meta {
+ default_type 'application/xrd+xml';
+ add_header Access-Control-Allow-Origin '*' always;
+ }
+
+ location /.well-known/host-meta.json {
+ default_type 'application/jrd+json';
+ add_header Access-Control-Allow-Origin '*' always;
+ }
+ ...
+}
+</code></pre>
+<p>And you will need the following <code>host-meta</code> and <code>host-meta.json</code> files inside the <code>.well-known/acme-challenge</code> directory for <code>your.domain</code> (following my nomenclature: <code>/var/www/yourdomaindir/.well-known/acme-challenge/</code>).</p>
+<p>For <code>host-meta</code> file:</p>
+<pre><code class="language-xml">&lt;?xml version='1.0' encoding='utf-8'?&gt;
+&lt;XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'&gt;
+ &lt;Link rel=&quot;urn:xmpp:alt-connections:xbosh&quot;
+ href=&quot;https://xmpp.your.domain:5281/http-bind&quot; /&gt;
+ &lt;Link rel=&quot;urn:xmpp:alt-connections:websocket&quot;
+ href=&quot;wss://xmpp.your.domain:5281/xmpp-websocket&quot; /&gt;
+&lt;/XRD&gt;
+</code></pre>
+<p>And <code>host-meta.json</code> file:</p>
+<pre><code class="language-json">{
+ &quot;links&quot;: [
+ {
+ &quot;rel&quot;: &quot;urn:xmpp:alt-connections:xbosh&quot;,
+ &quot;href&quot;: &quot;https://xmpp.your.domain:5281/http-bind&quot;
+ },
+ {
+ &quot;rel&quot;: &quot;urn:xmpp:alt-connections:websocket&quot;,
+ &quot;href&quot;: &quot;wss://xmpp.your.domain:5281/xmpp-websocket&quot;
+ }
+ ]
+}
+</code></pre>
+<p>Remember to have your <code>prosody.conf</code> file symlinked (or discoverable by Nginx) to the <code>sites-enabled</code> directory. You can now restart your <code>nginx</code> service (and test the configuration, optionally):</p>
+<pre><code class="language-sh">nginx -t
+systemctl restart nginx.service
+</code></pre>
+<h2 id="coturn">Coturn</h2>
+<p><a href="https://github.com/coturn/coturn">Coturn</a> is the implementation of TURN and STUN server, which in general is for (at least in the XMPP world) voice support and external service discovery.</p>
+<p>Install the <code>coturn</code> package:</p>
+<pre><code class="language-sh">pacman -S coturn
+</code></pre>
+<p>You can modify the configuration file (located at <code>/etc/turnserver/turnserver.conf</code>) as desired, but at least you need to make the following changes (uncomment or edit):</p>
+<pre><code>use-auth-secret
+realm=proxy.your.domain
+static-auth-secret=YOUR SUPER SECRET TURN PASSWORD
+</code></pre>
+<p>I&rsquo;m sure there is more configuration to be made, like using SQL to store data and whatnot, but for now this is enough for me. Note that you may not have some functionality that&rsquo;s needed to create dynamic users to use the TURN server, and to be honest I haven&rsquo;t tested this since I don&rsquo;t use this feature in my XMPP clients, but if it doesn&rsquo;t work, or you know of an error or missing configuration don&rsquo;t hesitate to <a href="https://luevano.xyz/contact.html">contact me</a>.</p>
+<p>Start/enable the <code>turnserver</code> service:</p>
+<pre><code class="language-sh">systemctl start turnserver.service
+systemctl enable turnserver.service
+</code></pre>
+<p>You can test if your TURN server works at <a href="https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/">Trickle ICE</a>. You may need to add a user in the <code>turnserver.conf</code> to test this.</p>
+<h2 id="wrapping-up">Wrapping up</h2>
+<p>At this point you should have a working XMPP server, start/enable the <code>prosody</code> service now:</p>
+<pre><code>systemctl start prosody.service
+systemctl enable prosody.service
+</code></pre>
+<p>And you can add your first user with the <code>prosodyctl</code> command (it will prompt you to add a password):</p>
+<pre><code>prosodyctl adduser user@your.domain
+</code></pre>
+<p>You may want to add a <code>compliance</code> user, so you can check if your server is set up correctly. To do so, go to <a href="https://compliance.conversations.im/add/">XMPP Compliance Tester</a> and enter the <code>compliance</code> user credentials. It should have similar compliance score to mine:</p>
+<p><a href='https://compliance.conversations.im/server/luevano.xyz'><img src='https://compliance.conversations.im/badge/luevano.xyz'></a></p>
+<p>Additionally, you can test the security of your server in <a href="https://xmpp.net/index.php">IM Observatory</a>, here you only need to specify your <code>domain.name</code> (not <code>xmpp.domain.name</code>, if you set up the <strong>SRV</strong> DNS records correctly). Again, it should have a similar score to mine:</p>
+<p><a href='https://xmpp.net/result.php?domain=luevano.xyz&amp;type=client'><img src='https://xmpp.net/badge.php?domain=luevano.xyz' alt='xmpp.net score' /></a></p>
+<p>You can now log in into your XMPP client of choice, if it asks for the server it should be <code>xmpp.your.domain</code> (or <code>your.domain</code> for some clients) and your login credentials <code>you@your.domain</code> and the password you chose (which you can change in most clients).</p>
+<p>That&rsquo;s it, send me a message <a href="xmpp:david@luevano.xyz">david@luevano.xyz</a> if you were able to set up the server successfully.</p>]]></content:encoded>
+ </item>
+ <item>
<title>Al fin ya me acomodé la página pa' los dibujos</title>
<link>https://blog.luevano.xyz/a/acomodada_la_pagina_de_arte.html</link>
<guid isPermaLink="true">https://blog.luevano.xyz/a/acomodada_la_pagina_de_arte.html</guid>
@@ -316,7 +823,7 @@ cp /usr/share/doc/dovecot/example-config/dovecot.conf /etc/dovecot/dovecot.conf
cp -r /usr/share/doc/dovecot/example-config/conf.d /etc/dovecot
</code></pre>
<p>As Luke stated, <code>dovecot</code> comes with a lot of &ldquo;modules&rdquo; (under <code>/etc/dovecot/conf.d/</code> if you copied that folder) for all sorts of configurations that you can include, but I do as he does and just edit/create the whole <code>dovecot.conf</code> file; although, I would like to check each of the separate configuration files <code>dovecot</code> provides I think the options Luke provides are more than good enough.</p>
-<p>I&rsquo;m working with an empty <code>dovecot.conf</code> file. Add the following lines for SSL and login configuration (also replace <code>{yourcertdir}</code> with the same certificate directory described in the <a href="#postfix">Postfix</a> section above, note that the <code>&lt;</code> is required):</p>
+<p>I&rsquo;m working with an empty <code>dovecot.conf</code> file. Add the following lines for SSL and login configuration (also replace <code>{yourcertdir}</code> with the same certificate directory described in the Postfix section above, note that the <code>&lt;</code> is required):</p>
<pre><code class="language-apache">ssl = required
ssl_cert = &lt;{yourcertdir}/fullchain.pem
ssl_key = &lt;{yourcertdir}/privkey.pem
diff --git a/blog/dst/sitemap.xml b/blog/dst/sitemap.xml
index 40b3af4..13213e7 100644
--- a/blog/dst/sitemap.xml
+++ b/blog/dst/sitemap.xml
@@ -3,6 +3,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
+ <loc>https://blog.luevano.xyz/a/xmpp_server_with_prosody.html</loc>
+ <lastmod>2021-06-09</lastmod>
+ <changefreq>weekly</changefreq>
+ <priority>1.0</priority>
+ </url>
+ <url>
<loc>https://blog.luevano.xyz/a/acomodada_la_pagina_de_arte.html</loc>
<lastmod>2021-06-06</lastmod>
<changefreq>weekly</changefreq>
@@ -53,43 +59,43 @@
<url>
<loc>https://blog.luevano.xyz/tag/@english.html</loc>
- <lastmod>2021-06-08</lastmod>
+ <lastmod>2021-06-09</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@server.html</loc>
- <lastmod>2021-06-08</lastmod>
+ <lastmod>2021-06-09</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@short.html</loc>
- <lastmod>2021-06-08</lastmod>
+ <lastmod>2021-06-09</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@spanish.html</loc>
- <lastmod>2021-06-08</lastmod>
+ <lastmod>2021-06-09</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@tools.html</loc>
- <lastmod>2021-06-08</lastmod>
+ <lastmod>2021-06-09</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@tutorial.html</loc>
- <lastmod>2021-06-08</lastmod>
+ <lastmod>2021-06-09</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>https://blog.luevano.xyz/tag/@update.html</loc>
- <lastmod>2021-06-08</lastmod>
+ <lastmod>2021-06-09</lastmod>
<changefreq>daily</changefreq>
<priority>0.5</priority>
</url>
diff --git a/blog/dst/tag/@english.html b/blog/dst/tag/@english.html
index 5cfce87..121609a 100644
--- a/blog/dst/tag/@english.html
+++ b/blog/dst/tag/@english.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>May 2021</h3>
+ <h3>June 2021</h3>
+ <li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
+ <h3>May 2021</h3>
<li>May 28 - <a href="https://blog.luevano.xyz/a/new_blogging_system.html">I'm using a new blogging system</a></li>
<h3>March 2021</h3>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">Create a git server and setup cgit web app (on Nginx)</a></li>
diff --git a/blog/dst/tag/@server.html b/blog/dst/tag/@server.html
index 623706c..18fbf43 100644
--- a/blog/dst/tag/@server.html
+++ b/blog/dst/tag/@server.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>March 2021</h3>
+ <h3>June 2021</h3>
+ <li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
+ <h3>March 2021</h3>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">Create a git server and setup cgit web app (on Nginx)</a></li>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html">Create a mail server with Postfix, Dovecot, SpamAssassin and OpenDKIM</a></li>
<li>Mar 19 - <a href="https://blog.luevano.xyz/a/website_with_nginx.html">Create a website with Nginx and Certbot</a></li>
diff --git a/blog/dst/tag/@tools.html b/blog/dst/tag/@tools.html
index e8236ac..c1daced 100644
--- a/blog/dst/tag/@tools.html
+++ b/blog/dst/tag/@tools.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>May 2021</h3>
+ <h3>June 2021</h3>
+ <li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
+ <h3>May 2021</h3>
<li>May 28 - <a href="https://blog.luevano.xyz/a/new_blogging_system.html">I'm using a new blogging system</a></li>
<h3>March 2021</h3>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">Create a git server and setup cgit web app (on Nginx)</a></li>
diff --git a/blog/dst/tag/@tutorial.html b/blog/dst/tag/@tutorial.html
index d086475..f979ad2 100644
--- a/blog/dst/tag/@tutorial.html
+++ b/blog/dst/tag/@tutorial.html
@@ -80,7 +80,9 @@
<h2>Articles</h2>
<ul class="page-list">
- <h3>March 2021</h3>
+ <h3>June 2021</h3>
+ <li>Jun 09 - <a href="https://blog.luevano.xyz/a/xmpp_server_with_prosody.html">Create an XMPP server with Prosody compatible with Conversations and Movim</a></li>
+ <h3>March 2021</h3>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/git_server_with_cgit.html">Create a git server and setup cgit web app (on Nginx)</a></li>
<li>Mar 21 - <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html">Create a mail server with Postfix, Dovecot, SpamAssassin and OpenDKIM</a></li>
<li>Mar 19 - <a href="https://blog.luevano.xyz/a/website_with_nginx.html">Create a website with Nginx and Certbot</a></li>
diff --git a/blog/plt/page.html b/blog/plt/page.html
index dbb2734..1b0afd9 100644
--- a/blog/plt/page.html
+++ b/blog/plt/page.html
@@ -16,6 +16,9 @@
{{page.content}}
+ {%import "page_nav.html" as page_nav%}
+ {{page_nav.print(page, config)}}
+
<hr>
<div class="article-info">
<p>By {{page.author}}</p>
diff --git a/blog/plt/page_nav.html b/blog/plt/page_nav.html
new file mode 100644
index 0000000..b15b9eb
--- /dev/null
+++ b/blog/plt/page_nav.html
@@ -0,0 +1,28 @@
+{%macro print(page, config)%}
+<div class="page-nav">
+ {%if page.next is not none%}
+ <span class="next">
+ <a href="{{page.next.url}}" alt="Next">
+ <i class="fas fa-arrow-left" alt="Arrow left"></i>
+ <span>Next</span>
+ </a>
+ </span>
+ {%endif%}
+
+ <span class="index">
+ <a href="{{config.url}}" alt="Index">
+ <i class="fas fa-home" alt="Home"></i>
+ <span>Index</span>
+ </a>
+ </span>
+
+ {%if page.previous is not none%}
+ <span class="previous">
+ <a href="{{page.previous.url}}" alt="Previous">
+ <i class="fas fa-arrow-right" alt="Arrow right"></i>
+ <span>Previous</span>
+ </a>
+ </span>
+ {%endif%}
+</div>
+{%endmacro%}
diff --git a/blog/src/.files b/blog/src/.files
index cc15f1c..979a2f6 100644
--- a/blog/src/.files
+++ b/blog/src/.files
@@ -1,11 +1,12 @@
-a/website_with_nginx.md 1616122695.085315 1623132678.0349047 english,server,tools,tutorial
-a/git_server_with_cgit.md 1616353229.8983006 1623135227.874393 english,server,tools,tutorial
+a/website_with_nginx.md 1616122695.085315 1623137232.645304 english,server,tools,tutorial
+a/git_server_with_cgit.md 1616353229.8983006 1623137257.0257351 english,server,tools,tutorial
a/el_blog_ya_tiene_timestamps.md 1615862784.9032707 1621284818.4731243 short,spanish,tools,update
a/shell_scripting_video_notes.md 1615701454.6499224 1622793622.0414143 english,notes
a/sql_video_notes.md 1614695711.6048582 1622950879.0081563 english,notes
a/first_blog_post.md 1614431313.2090824 1621284833.6700118 english,short,tools,update
a/linux_video_notes.md 1615701443.6397786 1622793573.704325 english,notes
-a/mail_server_with_postfix.md 1616299559.6570284 1623133655.6586692 english,server,tools,tutorial
+a/mail_server_with_postfix.md 1616299559.6570284 1623137344.8639452 english,server,tools,tutorial
a/new_blogging_system.md 1622172099.117893 1622173322.4337702 english,short,tools,update
a/asi_nomas_esta_quedando.md 1622795043.0874712 0.0 short,spanish,update
a/acomodada_la_pagina_de_arte.md 1623006369.6071973 1623006525.2665823 short,spanish,update
+a/xmpp_server_with_prosody.md 1623216270.0372887 0.0 english,server,tools,tutorial
diff --git a/blog/src/a/git_server_with_cgit.md b/blog/src/a/git_server_with_cgit.md
index 9d7ab44..4eb440c 100644
--- a/blog/src/a/git_server_with_cgit.md
+++ b/blog/src/a/git_server_with_cgit.md
@@ -15,8 +15,8 @@ Note that this is mostly for personal use, so there's no user/authentication con
I might get tired of saying this (it's just copy paste, basically)... but you will need the same prerequisites as before (check my [website](https://blog.luevano.xyz/a/website_with_nginx.html) and [mail](https://blog.luevano.xyz/a/mail_server_with_postfix.html) entries), with the extras:
-* (Optional, if you want a "front-end") A **CNAME** for "git" and (optionally) "www.git", or some other name for your sub-domains.
-* An SSL certificate, if you're following the other entries, add a `git.conf` and run `certbot --nginx` to extend the certificate.
+- (Optional, if you want a "front-end") A **CNAME** for "git" and (optionally) "www.git", or some other name for your sub-domains.
+- An SSL certificate, if you're following the other entries, add a `git.conf` and run `certbot --nginx` to extend the certificate.
## Git
diff --git a/blog/src/a/mail_server_with_postfix.md b/blog/src/a/mail_server_with_postfix.md
index e254416..63bf564 100644
--- a/blog/src/a/mail_server_with_postfix.md
+++ b/blog/src/a/mail_server_with_postfix.md
@@ -169,7 +169,7 @@ cp -r /usr/share/doc/dovecot/example-config/conf.d /etc/dovecot
As Luke stated, `dovecot` comes with a lot of "modules" (under `/etc/dovecot/conf.d/` if you copied that folder) for all sorts of configurations that you can include, but I do as he does and just edit/create the whole `dovecot.conf` file; although, I would like to check each of the separate configuration files `dovecot` provides I think the options Luke provides are more than good enough.
-I'm working with an empty `dovecot.conf` file. Add the following lines for SSL and login configuration (also replace `{yourcertdir}` with the same certificate directory described in the [Postfix](#postfix) section above, note that the `<` is required):
+I'm working with an empty `dovecot.conf` file. Add the following lines for SSL and login configuration (also replace `{yourcertdir}` with the same certificate directory described in the Postfix section above, note that the `<` is required):
```apache
ssl = required
@@ -500,15 +500,15 @@ Now, to actually use the mail service: first of all, you need a *normal* account
Next, to actually login into a mail app/program/whateveryouwanttocallit, you will use the following settings, at least for `thunderdbird`(I tested in windows default mail app and you don't need a lot of settings):
-* \* server: subdomain.domain (mail.luevano.xyz in my case)
-* **SMTP** port: 587
-* **SMTPS** port: 465 (I use this one)
-* **IMAP** port: 143
-* **IMAPS** port: 993 (again, I use this one)
-* Connection/security: SSL/TLS
-* Authentication method: Normal password
-* Username: just your `user`, not the whole email (`david` in my case)
-* Password: your `user` password (as in the password you use to login to the server with that user)
+- \* server: subdomain.domain (mail.luevano.xyz in my case)
+- **SMTP** port: 587
+- **SMTPS** port: 465 (I use this one)
+- **IMAP** port: 143
+- **IMAPS** port: 993 (again, I use this one)
+- Connection/security: SSL/TLS
+- Authentication method: Normal password
+- Username: just your `user`, not the whole email (`david` in my case)
+- Password: your `user` password (as in the password you use to login to the server with that user)
All that's left to do is test your mail server for spoofing, and to see if everything is setup correctly. Go to [DKIM Test](https://www.appmaildev.com/en/dkim) and follow the instructions (basically click next, and send an email with whatever content to the email that they provide). After you send the email, you should see something like:
diff --git a/blog/src/a/website_with_nginx.md b/blog/src/a/website_with_nginx.md
index 09a7781..7e4624a 100644
--- a/blog/src/a/website_with_nginx.md
+++ b/blog/src/a/website_with_nginx.md
@@ -97,12 +97,12 @@ That could serve as a template if you intend to add more domains.
Note some things:
-* `listen`: we're telling Nginx which port to listen to (IPv4 and IPv6, respectively).
-* `root`: the root directory of where the website files (`.html`, `.css`, `.js`, etc. files) are located. I followed Luke's directory path `/var/www/some_folder`.
-* `server_name`: the actual domain to "listen" to (for my website it is: `server_name luevano.xyz www.luevano.xyz;` and for this blog is: `server_name blog.luevano.xyz www.blog.luevano.xyz;`).
-* `index`: what file to serve as the index (could be any `.html`, `.htm`, `.php`, etc. file) when just entering the website.
-* `location`: what goes after `domain.name`, used in case of different configurations depending on the URL paths (deny access on `/private`, make a proxy on `/proxy`, etc).
- * `try_files`: tells what files to look for.
+- `listen`: we're telling Nginx which port to listen to (IPv4 and IPv6, respectively).
+- `root`: the root directory of where the website files (`.html`, `.css`, `.js`, etc. files) are located. I followed Luke's directory path `/var/www/some_folder`.
+- `server_name`: the actual domain to "listen" to (for my website it is: `server_name luevano.xyz www.luevano.xyz;` and for this blog is: `server_name blog.luevano.xyz www.blog.luevano.xyz;`).
+- `index`: what file to serve as the index (could be any `.html`, `.htm`, `.php`, etc. file) when just entering the website.
+- `location`: what goes after `domain.name`, used in case of different configurations depending on the URL paths (deny access on `/private`, make a proxy on `/proxy`, etc).
+ - `try_files`: tells what files to look for.
Then, make a symbolic link from this configuration file to the `sites-enabled` directory:
diff --git a/blog/src/a/xmpp_server_with_prosody.md b/blog/src/a/xmpp_server_with_prosody.md
new file mode 100644
index 0000000..be3d610
--- /dev/null
+++ b/blog/src/a/xmpp_server_with_prosody.md
@@ -0,0 +1,579 @@
+title: Create an XMPP server with Prosody compatible with Conversations and Movim
+author: David Luévano
+lang: en
+summary: How to create an XMPP server using Prosody on a server running Nginx. This server will be compatible with at least Conversations and Movim.
+tags: server
+ tools
+ tutorial
+ english
+
+Recently I set up an XMPP server (and a Matrix one, too) for my personal use and for friends if they want one; made one for ???[EL ELE EME](https://lmcj.xyz)???, for example. So, here are the notes on how I set up the server that is compatible with the [Conversations](https://conversations.im/) app and the [Movim](https://movim.eu/) social network. You can see my addresses in [contact](https://luevano.xyz/contact.html) and the XMPP compliance/score of the server.
+
+One of the best resources I found that helped me a lot was [Installing and Configuring Prosody XMPP Server on Debian 9](https://community.hetzner.com/tutorials/prosody-debian9), and of course the [Arch Wiki](https://wiki.archlinux.org/title/Prosody) and the [oficial documentation](https://prosody.im/).
+
+As with my other entries, this is under a server running Arch Linux, with the Nginx web server and Certbot certificates. And all commands here are executed as root (unless specified otherwise)
+
+## Prerequisites
+
+Same as with my other entries ([website](https://luevano.xyz/a/website_with_nginx.html), [mail](https://blog.luevano.xyz/a/mail_server_with_postfix.html) and [git](https://blog.luevano.xyz/a/git_server_with_cgit.html)) plus:
+
+- **A** and (optionally) **AAA** DNS records for:
+ - `xmpp`: the actual XMPP server and the file upload service.
+ - `muc` (or `conference`): for multi-user chats.
+ - `pubsub`: the publish-subscribe service.
+ - `proxy`: a proxy in case one of the users needs it.
+ - `vjud`: user directory.
+- (Optionally, but recommended) the following **SRV** DNS records; make sure it is pointing to an **A** or **AAA** record (matching the records from the last point, for example):
+ - `_xmpp-client._tcp.**your.domain**.` for port `5222` pointing to `xmpp.**your.domain**.`
+ - `_xmpp-server._tcp.**your.domain**.` for port `5269` pointing to `xmpp.**your.domain**.`
+ - `_xmpp-server._tcp.muc.**your.domain**.` for port `5269` pointing to `xmpp.**your.domain**.`
+* SSL certificates for the previous subdomains; similar that with my other entries just create the appropriate `prosody.conf` (where `server_name` will be all the subdomains defined above) file and run `certbot --nginx`. You can find the example configuration file almost at the end of this entry.
+- Email addresses for `admin`, `abuse`, `contact`, `security`, etc. Or use your own email for all of them, doesn't really matter much as long as you define them in the configuration and are valid, I have aliases so those emails are forwarded to me.
+- Allow ports 5000, 5222, 5269, 5280 and 5281 for [Prosody](https://prosody.im/doc/ports) and, 3478 and 5349 for [Turnserver](https://webrtc.org/getting-started/turn-server) which are the defaults for `coturn`.
+
+## Prosody
+
+[Prosody](https://wiki.archlinux.org/title/Prosody) is an implementation of the XMPP protocol that is flexible and extensible.
+
+Install the `prosody` package (with optional dependencies) and the `mercurial` package:
+
+```sh
+pacman -S prosody, mercurial, lua52-sec, lua52-dbi, lua52-zlib
+```
+
+We need mercurial to be able to download and update the extra modules needed to make the server compliant with `conversations.im` and `mov.im`. Go to `/var/lib/prosody`, clone the latest Prosody modules repository and prepare the directories:
+
+```sh
+cd /var/lib/prosody
+hg clone https://hg.prosody.im/prosody-modules modules-available
+mkdir modules-enabled
+```
+
+You can see that I follow a similar approach that I used with Nginx and the server configuration, where I have all the modules available in a directory, and make a symlink to another to keep track of what is being used. You can update the repository by running `hg pull --update` while inside the `modules-available` directory (similar to Git).
+
+Make symbolic links to the following modules:
+
+```
+ln -s /var/lib/prosody/modules-available/MODULE_NAME /var/lib/prosody/modules-enabled/
+...
+```
+
+- Modules:
+ - `mod_bookmarks`
+ - `mod_cache_c2s_caps`
+ - `mod_checkcerts`
+ - `mod_cloud_notify`
+ - `mod_csi_battery_saver`
+ - `mod_default_bookmarks`
+ - `mod_external_services`
+ - `mod_http_avatar`
+ - `mod_http_pep_avatar`
+ - `mod_http_upload`
+ - `mod_http_upload_external`
+ - `mod_idlecompat`
+ - `mod_muc_limits`
+ - `mod_muc_mam_hints`
+ - `mod_muc_mention_notifications`
+ - `mod_presence_cache`
+ - `mod_pubsub_feeds`
+ - `mod_pubsub_text_interface`
+ - `mod_smacks`
+ - `mod_strict_https`
+ - `mod_vcard_muc`
+ - `mod_vjud`
+ - `mod_watchuntrusted`
+
+And add other modules if needed, but these work for the apps that I mentioned. You should also change the permissions for these files:
+
+```sh
+chown -R prosody:prosody /var/lib/prosody
+```
+
+Now, configure the server by editing the `/etc/prosody/prosody.cfg.lua` file. It's a bit tricky to configure, so here is my configuration file (lines starting with `--` are comments). Make sure to change according to your domain, and maybe preferences. Read each line and each comment to know what's going on, It's easier to explain it with comments in the file itself than strip it in a lot of pieces.
+
+And also, note that the configuration file has a "global" section and a per "virtual server"/"component" section, basically everything above all the VirtualServer/Component sections are global, and bellow each VirtualServer/Component, corresponds to that section.
+
+```
+-- important for systemd
+daemonize = true
+pidfile = "/run/prosody/prosody.pid"
+
+-- or your account, not that this is an xmpp jid, not email
+admins = { "admin@your.domain" }
+
+contact_info = {
+ abuse = { "mailto:abuse@your.domain", "xmpp:abuse@your.domain" };
+ admin = { "mailto:admin@your.domain", "xmpp:admin@your.domain" };
+ admin = { "mailto:feedback@your.domain", "xmpp:feedback@your.domain" };
+ security = { "mailto:security@your.domain" };
+ support = { "mailto:support@your.domain", "xmpp:support@muc.your.domain" };
+}
+
+-- so prosody look up the plugins we added
+plugin_paths = { "/var/lib/prosody/modules-enabled" }
+
+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
+ "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
+ "limits"; -- Enable bandwidth limiting for XMPP connections
+ -- 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_simple"; -- Simple Mobile optimizations
+ -- Admin interfaces
+ "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
+ --"admin_telnet"; -- Opens telnet console interface on localhost port 5582
+ -- HTTP modules
+ "http"; -- Explicitly enable http server.
+ "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP"
+ "websocket"; -- XMPP over WebSockets
+ "http_files"; -- Serve static files from a directory over HTTP
+ -- Other specific functionality
+ "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.
+ --"s2s_bidi"; -- not yet implemented, have to wait for v0.12
+ "bookmarks";
+ "checkcerts";
+ "cloud_notify";
+ "csi_battery_saver";
+ "default_bookmarks";
+ "http_avatar";
+ "idlecompat";
+ "presence_cache";
+ "smacks";
+ "strict_https";
+ --"pep_vcard_avatar"; -- not compatible with this version of pep, wait for v0.12
+ "watchuntrusted";
+ "webpresence";
+ "external_services";
+ }
+
+-- only if you want to disable some modules
+modules_disabled = {
+ -- "offline"; -- Store offline messages
+ -- "c2s"; -- Handle client connections
+ -- "s2s"; -- Handle server-to-server connections
+ -- "posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
+}
+
+external_services = {
+ {
+ type = "stun",
+ transport = "udp",
+ host = "proxy.your.domain",
+ port = 3478
+ }, {
+ type = "turn",
+ transport = "udp",
+ host = "proxy.your.domain",
+ port = 3478,
+ -- you could decide this now or come back later when you install coturn
+ secret = "YOUR SUPER SECRET TURN PASSWORD"
+ }
+}
+
+--- general global configuration
+http_ports = { 5280 }
+http_interfaces = { "*", "::" }
+
+https_ports = { 5281 }
+https_interfaces = { "*", "::" }
+
+proxy65_ports = { 5000 }
+proxy65_interfaces = { "*", "::" }
+
+http_default_host = "xmpp.your.domain"
+http_external_url = "https://xmpp.your.domain/"
+-- or if you want to have it somewhere else, change this
+https_certificate = "/etc/prosody/certs/xmpp.your.domain.crt"
+
+hsts_header = "max-age=31556952"
+
+cross_domain_bosh = true
+--consider_bosh_secure = true
+cross_domain_websocket = true
+--consider_websocket_secure = true
+
+trusted_proxies = { "127.0.0.1", "::1", "192.169.1.1" }
+
+pep_max_items = 10000
+
+-- this is disabled by default, and I keep it like this, depends on you
+--allow_registration = true
+
+-- you might want this options as they are
+c2s_require_encryption = true
+s2s_require_encryption = true
+s2s_secure_auth = false
+--s2s_insecure_domains = { "insecure.example" }
+--s2s_secure_domains = { "jabber.org" }
+
+-- where the certificates are stored (/etc/prosody/certs by default)
+certificates = "certs"
+checkcerts_notify = 7 -- ( in days )
+
+-- rate limits on connections to the server, these are my personal settings, because by default they were limited to something like 30kb/s
+limits = {
+ c2s = {
+ rate = "2000kb/s";
+ };
+ s2sin = {
+ rate = "5000kb/s";
+ };
+ s2sout = {
+ rate = "5000kb/s";
+ };
+}
+
+-- again, this could be yourself, it is a jid
+unlimited_jids = { "admin@your.domain" }
+
+authentication = "internal_hashed"
+
+-- if you don't want to use sql, change it to internal and comment the second line
+-- since this is optional, i won't describe how to setup mysql or setup the user/database, that would be out of the scope for this entry
+storage = "sql"
+sql = { driver = "MySQL", database = "prosody", username = "prosody", password = "PROSODY USER SECRET PASSWORD", host = "localhost" }
+
+archive_expires_after = "4w" -- configure message archive
+max_archive_query_results = 20;
+mam_smart_enable = true
+default_archive_policy = "roster" -- archive only messages from users who are in your roster
+
+-- normally you would like at least one log file of certain level, but I keep all of them, the default is only the info = "*syslog" one
+log = {
+ info = "*syslog";
+ warn = "prosody.warn";
+ error = "prosody.err";
+ debug = "prosody.debug";
+ -- "*console"; -- Needs daemonize=false
+}
+
+-- cloud_notify
+push_notification_with_body = false -- Whether or not to send the message body to remote pubsub node
+push_notification_with_sender = false -- Whether or not to send the message sender to remote pubsub node
+push_max_errors = 5 -- persistent push errors are tolerated before notifications for the identifier in question are disabled
+push_max_devices = 5 -- number of allowed devices per user
+
+-- by default every user on this server will join these muc rooms
+default_bookmarks = {
+ { jid = "room@muc.your.domain", name = "The Room" };
+ { jid = "support@muc.your.domain", name = "Support Room" };
+}
+
+-- could be your jid
+untrusted_fail_watchers = { "admin@your.domain" }
+untrusted_fail_notification = "Establishing a secure connection from $from_host to $to_host failed. Certificate hash: $sha1. $errors"
+
+----------- Virtual hosts -----------
+VirtualHost "your.domain"
+ name = "Prosody"
+ http_host = "xmpp.your.domain"
+
+disco_items = {
+ { "your.domain", "Prosody" };
+ { "muc.your.domain", "MUC Service" };
+ { "pubsub.your.domain", "Pubsub Service" };
+ { "proxy.your.domain", "SOCKS5 Bytestreams Service" };
+ { "vjud.your.domain", "User Directory" };
+}
+
+
+-- Multi-user chat
+Component "muc.your.domain" "muc"
+ name = "MUC Service"
+ modules_enabled = {
+ --"bob"; -- not compatible with this version of Prosody
+ "muc_limits";
+ "muc_mam"; -- message archive in muc, again, a placeholder
+ "muc_mam_hints";
+ "muc_mention_notifications";
+ "vcard_muc";
+ }
+
+ restrict_room_creation = false
+
+ muc_log_by_default = true
+ muc_log_presences = false
+ log_all_rooms = false
+ muc_log_expires_after = "1w"
+ muc_log_cleanup_interval = 4 * 60 * 60
+
+
+-- Upload
+Component "xmpp.your.domain" "http_upload"
+ name = "Upload Service"
+ http_host= "xmpp.your.domain"
+ -- you might want to change this, these are numbers in bytes, so 10MB and 100MB respectively
+ http_upload_file_size_limit = 1024*1024*10
+ http_upload_quota = 1024*1024*100
+
+
+-- Pubsub
+Component "pubsub.your.domain" "pubsub"
+ name = "Pubsub Service"
+ pubsub_max_items = 10000
+ modules_enabled = {
+ "pubsub_feeds";
+ "pubsub_text_interface";
+ }
+
+ -- personally i don't have any feeds configured
+ feeds = {
+ -- The part before = is used as PubSub node
+ --planet_jabber = "http://planet.jabber.org/atom.xml";
+ --prosody_blog = "http://blog.prosody.im/feed/atom.xml";
+ }
+
+
+-- Proxy
+Component "proxy.your.domain" "proxy65"
+ name = "SOCKS5 Bytestreams Service"
+ proxy65_address = "proxy.your.domain"
+
+
+-- Vjud, user directory
+Component "vjud.your.domain" "vjud"
+ name = "User Directory"
+ vjud_mode = "opt-in"
+```
+
+You ???HAVE??? to read all of the configuration file, because there are a lot of things that you need to change to make it work with your server/domain. Test the configuration file with:
+
+```sh
+luac5.2 -p /etc/prosody/prosody.cfg.lua
+```
+
+Notice that by default `prosody` will look up certificates that look like `sub.your.domain`, but if you get the certificates as myself, you'll have a single certificate for all subdomains, and by default it is in `/etc/letsencrypt/live`, which has some strict permissions. So, to import them you can run:
+
+```sh
+prosodyctl --root cert import /etc/letsencrypt/live
+```
+
+Ignore the complaining about not finding the subdomain certificates and note that you will have to run that command on each certificate renewal, to automate this, add the `--deploy-hook` flag to your automated Certbot renewal system; for me it's a `systemd` timer with the following `certbot.service`:
+
+```ini
+[Unit]
+Description=Let's Encrypt renewal
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/certbot renew --quiet --agree-tos --deploy-hook "systemctl reload nginx.service && prosodyctl --root cert import /etc/letsencrypt/live"
+```
+
+And if you don't have it already, the `certbot.timer`:
+
+```ini
+[Unit]
+Description=Twice daily renewal of Let's Encrypt's certificates
+
+[Timer]
+OnCalendar=0/12:00:00
+RandomizedDelaySec=1h
+Persistent=true
+
+[Install]
+WantedBy=timers.target
+```
+
+Also, go to the `certs` directory and make the appropriate symbolic links:
+
+```sh
+cd /etc/prosody/certs
+ln -s your.domain.crt SUBDOMAIN.your.domain.crt
+ln -s your.domain.key SUBDOMAIN.your.domain.key
+...
+```
+
+That's basically all the configuration that needs Prosody itself, but we still have to configure Nginx and Coturn before starting/enabling the `prosody` service.
+
+## Nginx configuration file
+
+Since this is not an ordinary configuration file I'm going to describe this too. Your `prosody.conf` file should have the following location blocks under the main server block (the one that listens to HTTPS):
+
+```nginx
+# HTTPS server block
+server {
+ root /var/www/prosody/;
+ server_name xmpp.luevano.xyz muc.luevano.xyz pubsub.luevano.xyz vjud.luevano.xyz proxy.luevano.xyz;
+ index index.html;
+
+ # for extra https discovery (XEP-0256)
+ location /.well-known/acme-challenge {
+ allow all;
+ }
+
+ # bosh specific
+ location /http-bind {
+ proxy_pass https://localhost:5281/http-bind;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # websocket specific
+ location /xmpp-websocket {
+ proxy_pass https://localhost:5281/xmpp-websocket;
+
+ proxy_http_version 1.1;
+ proxy_set_header Connection "Upgrade";
+ proxy_set_header Upgrade $http_upgrade;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_read_timeout 900s;
+ }
+
+ # general proxy
+ location / {
+ proxy_pass https://localhost:5281;
+
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Real-IP $remote_addr;
+ }
+ ...
+ # Certbot stuff
+}
+# HTTP server block (the one that certbot creates)
+server {
+ ...
+}
+```
+
+Also, you need to add the following to your actual `your.domain` (this cannot be a subdomain) configuration file:
+
+```nginx
+server {
+ ...
+ location /.well-known/host-meta {
+ default_type 'application/xrd+xml';
+ add_header Access-Control-Allow-Origin '*' always;
+ }
+
+ location /.well-known/host-meta.json {
+ default_type 'application/jrd+json';
+ add_header Access-Control-Allow-Origin '*' always;
+ }
+ ...
+}
+```
+
+And you will need the following `host-meta` and `host-meta.json` files inside the `.well-known/acme-challenge` directory for `your.domain` (following my nomenclature: `/var/www/yourdomaindir/.well-known/acme-challenge/`).
+
+For `host-meta` file:
+
+```xml
+<?xml version='1.0' encoding='utf-8'?>
+<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
+ <Link rel="urn:xmpp:alt-connections:xbosh"
+ href="https://xmpp.your.domain:5281/http-bind" />
+ <Link rel="urn:xmpp:alt-connections:websocket"
+ href="wss://xmpp.your.domain:5281/xmpp-websocket" />
+</XRD>
+```
+
+And `host-meta.json` file:
+
+```json
+{
+ "links": [
+ {
+ "rel": "urn:xmpp:alt-connections:xbosh",
+ "href": "https://xmpp.your.domain:5281/http-bind"
+ },
+ {
+ "rel": "urn:xmpp:alt-connections:websocket",
+ "href": "wss://xmpp.your.domain:5281/xmpp-websocket"
+ }
+ ]
+}
+```
+
+Remember to have your `prosody.conf` file symlinked (or discoverable by Nginx) to the `sites-enabled` directory. You can now restart your `nginx` service (and test the configuration, optionally):
+
+```sh
+nginx -t
+systemctl restart nginx.service
+```
+
+## Coturn
+
+[Coturn](https://github.com/coturn/coturn) is the implementation of TURN and STUN server, which in general is for (at least in the XMPP world) voice support and external service discovery.
+
+Install the `coturn` package:
+
+```sh
+pacman -S coturn
+```
+
+You can modify the configuration file (located at `/etc/turnserver/turnserver.conf`) as desired, but at least you need to make the following changes (uncomment or edit):
+
+```
+use-auth-secret
+realm=proxy.your.domain
+static-auth-secret=YOUR SUPER SECRET TURN PASSWORD
+```
+
+I'm sure there is more configuration to be made, like using SQL to store data and whatnot, but for now this is enough for me. Note that you may not have some functionality that's needed to create dynamic users to use the TURN server, and to be honest I haven't tested this since I don't use this feature in my XMPP clients, but if it doesn't work, or you know of an error or missing configuration don't hesitate to [contact me](https://luevano.xyz/contact.html).
+
+Start/enable the `turnserver` service:
+
+```sh
+systemctl start turnserver.service
+systemctl enable turnserver.service
+```
+
+You can test if your TURN server works at [Trickle ICE](https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/). You may need to add a user in the `turnserver.conf` to test this.
+
+## Wrapping up
+
+At this point you should have a working XMPP server, start/enable the `prosody` service now:
+
+```
+systemctl start prosody.service
+systemctl enable prosody.service
+```
+
+And you can add your first user with the `prosodyctl` command (it will prompt you to add a password):
+
+```
+prosodyctl adduser user@your.domain
+```
+
+You may want to add a `compliance` user, so you can check if your server is set up correctly. To do so, go to [XMPP Compliance Tester](https://compliance.conversations.im/add/) and enter the `compliance` user credentials. It should have similar compliance score to mine:
+
+<a href='https://compliance.conversations.im/server/luevano.xyz'><img src='https://compliance.conversations.im/badge/luevano.xyz'></a>
+
+Additionally, you can test the security of your server in [IM Observatory](https://xmpp.net/index.php), here you only need to specify your `domain.name` (not `xmpp.domain.name`, if you set up the **SRV** DNS records correctly). Again, it should have a similar score to mine:
+
+<a href='https://xmpp.net/result.php?domain=luevano.xyz&amp;type=client'><img src='https://xmpp.net/badge.php?domain=luevano.xyz' alt='xmpp.net score' /></a>
+
+You can now log in into your XMPP client of choice, if it asks for the server it should be `xmpp.your.domain` (or `your.domain` for some clients) and your login credentials `you@your.domain` and the password you chose (which you can change in most clients).
+
+That's it, send me a message <a href="xmpp:david@luevano.xyz">david@luevano.xyz</a> if you were able to set up the server successfully.
diff --git a/blog/xmpp_server_with_prosody.md b/blog/xmpp_server_with_prosody.md
deleted file mode 100644
index 60f459b..0000000
--- a/blog/xmpp_server_with_prosody.md
+++ /dev/null
@@ -1,189 +0,0 @@
-title: Create an XMPP server with Prosody compatible with Conversations and Movim
-author: David Luévano
-lang: en
-summary: How to create an XMPP server using Prosody on a server running Nginx. This server will be compatible with at least Conversations and Movim.
-tags: server
- tools
- tutorial
- english
-
-My git server is all I need to setup to actually *kill* my other server (I've been moving from servers on these last 2-3 blog entries), that's why I'm already doing this entry. I'm basically following [git's guide on setting up a server](https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server) plus some specific stuff for (btw i use) Arch Linux ([Arch Linux Wiki: Git server](https://wiki.archlinux.org/index.php/Git_server#Web_interfaces) and [Step by step guide on setting up git server in arch linux (pushable)](https://miracoin.wordpress.com/2014/11/25/step-by-step-guide-on-setting-up-git-server-in-arch-linux-pushable/)).
-
-Note that this is mostly for personal use, so there's no user/authentication control other than that of SSH. Also, most if not all commands here are run as root.
-
-## Prerequisites
-
-I might get tired of saying this (it's just copy paste, basically)... but you will need the same prerequisites as before (check my [website](https://blog.luevano.xyz/a/website_with_nginx.html) and [mail](https://blog.luevano.xyz/a/mail_server_with_postfix.html) entries), with the extras:
-
-* (Optional, if you want a "front-end") A **CNAME** for "git" and (optionally) "www.git", or some other name for your sub-domains.
-* An SSL certificate, if you're following the other entries, add a `git.conf` and run `certbot --nginx` to extend the certificate.
-
-## Git
-
-[Git](https://wiki.archlinux.org/title/git) is a version control system.
-
-If not installed already, install the `git` package:
-
-```sh
-pacman -S git
-```
-
-On Arch Linux, when you install the `git` package, a `git` user is automatically created, so all you have to do is decide where you want to store the repositories, for me, I like them to be on `/home/git` like if `git` was a "normal" user. So, create the `git` folder (with corresponding permissions) under `/home` and set the `git` user's home to `/home/git`:
-
-```sh
-mkdir /home/git
-chown git:git /home/git
-usermod -d /home/git git
-```
-
-Also, the `git` user is "expired" by default and will be locked (needs a password), change that with:
-
-```sh
-chage -E -1 git
-passwd git
-```
-
-Give it a strong one and remember to use `PasswordAuthentication no` for `ssh` (as you should). Create the `.ssh/authorized_keys` for the `git` user and set the permissions accordingly:
-
-```sh
-mkdir /home/git/.ssh
-chmod 700 /home/git/.ssh
-touch /home/git/.ssh/authorized_keys
-chmod 600 /home/git/.ssh/authorized_keys
-chown -R git:git /home/git
-```
-
-Now is a good idea to copy over your local SSH public keys to this file, to be able to push/pull to the repositories. Do it by either manually copying it or using `ssh`'s built in `ssh-copy-id` (for that you may want to check your `ssh` configuration in case you don't let people access your server with user/password).
-
-Next, and almost finally, we need to edit the `git-daemon` service, located at `/usr/lib/systemd/system/` (called `git-daemon@.service`):
-
-```ini
-...
-ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/home/git --enable=receive-pack
-...
-```
-
-I just appended `--enable=receive-pack` and note that I also changed the `--base-path` to reflect where I want to serve my repositories from (has to match what you set when changing `git` user's home).
-
-Now, go ahead and start and enable the `git-daemon` socket:
-
-```sh
-systemctl start git-daemon.socket
-systemctl enable git-daemon.socket
-```
-
-You're basically done. Now you should be able to push/pull repositories to your server... except, you haven't created any repository in your server, that's right, they're not created automatically when trying to push. To do so, you have to run (while inside `/home/git`):
-
-```sh
-git init --bare {repo_name}.git
-chown -R git:git repo_name.git
-```
-
-Those two lines above will need to be run each time you want to add a new repository to your server (yeah, kinda lame... although there are options to "automate" this, I like it this way).
-
-After that you can already push/pull to your repository. I have my repositories (locally) set up so I can push to more than one remote at the same time (my server, GitHub, GitLab, etc.); to do so, check [this gist](https://gist.github.com/rvl/c3f156e117e22a25f242).
-
-## Cgit
-
-[Cgit](https://wiki.archlinux.org/title/Cgit) is a fast web interface for git.
-
-This is optionally since it's only for the web application.
-
-Install the `cgit` and `fcgiwrap` packages:
-
-```sh
-pacman -S cgit fcgiwrap
-```
-
-Now, just start and enable the `fcgiwrap` socket:
-
-```sh
-systemctl start fcgiwrap.socket
-systemctl enable fcgiwrap.socket
-```
-
-Next, create the `git.conf` as stated in my [nginx setup entry](https://blog.luevano.xyz/a/website_with_nginx.html). Add the following lines to your `git.conf` file:
-
-```nginx
-server {
- listen 80;
- listen [::]:80;
- root /usr/share/webapps/cgit;
- server_name {yoursubdomain}.{yourdomain};
- try_files $uri @cgit;
-
- location @cgit {
- include fastcgi_params;
- fastcgi_param SCRIPT_FILENAME $document_root/cgit.cgi;
- fastcgi_param PATH_INFO $uri;
- fastcgi_param QUERY_STRING $args;
- fastcgi_param HTTP_HOST $server_name;
- fastcgi_pass unix:/run/fcgiwrap.sock;
- }
-}
-```
-
-Where the `server_name` line depends on you, I have mine setup to `git.luevano.xyz` and `www.git.luevano.xyz`. Optionally run `certbot --nginx` to get a certificate for those domains if you don't have already.
-
-Now, all that's left is to configure `cgit`. Create the configuration file `/etc/cgitrc` with the following content (my personal options, pretty much the default):
-
-```apache
-css=/cgit.css
-logo=/cgit.png
-
-enable-http-clone=1
-# robots=noindex, nofollow
-virtual-root=/
-
-repo.url={url}
-repo.path={dir_path}
-repo.owner={owner}
-repo.desc={short_description}
-
-...
-```
-
-Where you can uncomment the `robots` line to let web crawlers (like Google's) to index your `git` web app. And at the end keep all your repositories (the ones you want to make public), for example for my [*dotfiles*](https://git.luevano.xyz/.dots) I have:
-
-```apache
-...
-repo.url=.dots
-repo.path=/home/git/.dots.git
-repo.owner=luevano
-repo.desc=These are my personal dotfiles.
-...
-```
-
-Otherwise you could let `cgit` to automatically detect your repositories (you have to be careful if you want to keep "private" repos) using the option `scan-path` and setup `.git/description` for each repository. For more, you can check [cgitrc(5)](https://man.archlinux.org/man/cgitrc.5).
-
-By default you can't see the files on the site, you need a highlighter to render the files, I use `highlight`. Install the `highlight` package:
-
-```sh
-pacman -S highlight
-```
-
-Copy the `syntax-highlighting.sh` script to the corresponding location (basically adding `-edited` to the file):
-
-```sh
-cp /usr/lib/cgit/filters/syntax-highlighting.sh /usr/lib/cgit/filters/syntax-highlighting-edited.sh
-```
-
-And edit it to use the version 3 and add `--inline-css` for more options without editing `cgit`'s CSS file:
-
-```sh
-...
-# This is for version 2
-# exec highlight --force -f -I -X -S "$EXTENSION" 2>/dev/null
-
-# This is for version 3
-exec highlight --force --inline-css -f -I -O xhtml -S "$EXTENSION" 2>/dev/null
-...
-```
-
-Finally, enable the filter in `/etc/cgitrc` configuration:
-
-```apache
-source-filter=/usr/lib/cgit/filters/syntax-highlighting-edited.sh
-```
-
-That would be everything. If you need support for more stuff like compressed snapshots or support for markdown, check the optional dependencies for `cgit`.
diff --git a/gb/index.html b/gb/index.html
index c0f3f67..8df243f 100644
--- a/gb/index.html
+++ b/gb/index.html
@@ -1,20 +1,79 @@
<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <link rel="icon" href="https://static.luevano.xyz/images/gb/gb_icon.svg" />
- <title>Gameboy</title>
+<html class="theme-dark" lang="en"
+ prefix="og: https://ogp.me/ns#">
+ <head>
+ <base href="https://static.luevano.xyz/">
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Gameboy -- Luévano's Site</title>
+ <meta name="description" content="My personal website where I host my blog, art gallery and more."/>
+ <link rel="alternate" type="application/rss+xml" href="https://blog.luevano.xyz/rss.xml" title="Luévano's Blog RSS">
+ <link rel="alternate" type="application/rss+xml" href="https://art.luevano.xyz/rss.xml" title="Luévano's Art RSS">
+ <link rel="icon" href="images/icons/favicon.ico">
- <script src="https://static.luevano.xyz/scripts/jquery-3.5.1.min.js"></script>
- <script src="https://static.luevano.xyz/scripts/gb.js"></script>
+ <!-- general style -->
+ <link rel="stylesheet" type="text/css" href="css/style.css">
+ <link rel="stylesheet" type="text/css" href="fork-awesome/css/fork-awesome.min.css">
+ <link rel="stylesheet" type="text/css" href="font-awesome/css/all.min.css">
- <link rel="stylesheet" href="https://static.luevano.xyz/css/gb.css">
-</head>
-<body>
+ <!-- theme related -->
+ <script type="text/javascript" src="scripts/theme.js"></script>
+ <link id="theme-css" rel="stylesheet" type="text/css" href="css/theme.css">
+ <link rel="stylesheet" type="text/css" href="css/gb.css">
- <header>
- <a href="https://luevano.xyz/">[HOME]</a>
- </header>
+ <!-- for the gameboy to work -->
+ <script src="scripts/jquery-3.5.1.min.js"></script>
+ <script src="scripts/gb.js"></script>
+
+
+ <!-- og meta -->
+ <meta property="og:title" content="Gameboy -- Luévano's Site"/>
+ <meta property="og:type" content="website"/>
+ <meta property="og:url" content="https://gb.luevano.xyz/index.html"/>
+ <meta property="og:image" content="images/default.png"/>
+ <meta property="og:description" content="My instance of Gameboy.Live emulator."/>
+ <meta property="og:locale" content="en"/>
+ <meta property="og:site_name" content="Luévano's Site"/>
+ </head>
+
+ <body>
+ <header>
+ <nav>
+ <ul>
+ <li>
+ <a href="https://luevano.xyz/"><i class="fas fa-home" alt="Home"></i><span>Home</span></a>
+ </li>
+
+ <li>
+ <a href="https://blog.luevano.xyz/"><i class="fas fa-book-open" alt="Blog"></i><span>Blog</span></a>
+ </li>
+
+ <li>
+ <a href="https://art.luevano.xyz/"><i class="fas fa-paint-brush" alt="Art"></i><span>Art</span></a>
+ </li>
+
+ <li><i class="fab fa-git" alt="Git"></i><span>Git</span>
+ <ul>
+ <li><a href="https://git.luevano.xyz/" target="_blank"><i class="fab fa-git-alt" alt="Git-alt"></i></a></li>
+
+ <li><a href="https://github.com/luevano" target="_blank"><i class="fab fa-github" alt="Github"></i></a></li>
+
+ <li><a href="https://gitlab.com/dluevano" target="_blank"><i class="fab fa-gitlab" alt="Gitlab"></i></a></li>
+ </ul>
+ </li>
+
+ <li><i class="fas fa-box-open" alt="Stuff"></i><span>Stuff</span>
+ <ul>
+ <li><a href="https://gb.luevano.xyz/"><i class="fas fa-gamepad" alt="Gameboy"></i><span>Gameboy</span></a></li>
+ </ul>
+ </li>
+ </ul>
+ </nav>
+
+ <button class="theme-switcher" onclick="toggleTheme()"><i class="fas fa-moon"></i><i class="fas fa-sun"></i></button>
+ </header>
+
+ <main>
<div class="gameboy">
<img class="screen" src="https://gb.ezclap.xyz/image" id="game_img"><br><br>
@@ -25,37 +84,37 @@
<tr>
<td/>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/up.png" alt="Up" id="btn_up">
+ <input type="image" src="images/gb/up.png" alt="Up" id="btn_up">
</td>
<td/>
<td/>
<td/>
<td/>
<td>
- <a href="https://gb.luevano.xyz"><img src="https://static.luevano.xyz/images/gb/refresh.png"></a>
+ <a href="https://gb.luevano.xyz"><input type="image" src="images/gb/refresh.png" alt="Refresh"></a>
</td>
</tr>
<tr>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/left.png" alt="Left" id="btn_left">
+ <input type="image" src="images/gb/left.png" alt="Left" id="btn_left">
</td>
<td/>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/right.png" alt="Right" id="btn_right">
+ <input type="image" src="images/gb/right.png" alt="Right" id="btn_right">
</td>
<td/>
<td/>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/B.png" alt="B" id="btn_b">
+ <input type="image" src="images/gb/B.png" alt="B" id="btn_b">
</td>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/A.png" alt="A" id="btn_a">
+ <input type="image" src="images/gb/A.png" alt="A" id="btn_a">
</td>
</tr>
<tr>
<td/>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/down.png" alt="Down" id="btn_down">
+ <input type="image" src="images/gb/down.png" alt="Down" id="btn_down">
</td>
<td/>
<td/>
@@ -68,10 +127,10 @@
<td/>
<td/>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/select.png" alt="Select" id="btn_select">
+ <input type="image" src="images/gb/select.png" alt="Select" id="btn_select">
</td>
<td>
- <input type="image" src="https://static.luevano.xyz/images/gb/start.png" alt="Start" id="btn_start">
+ <input type="image" src="images/gb/start.png" alt="Start" id="btn_start">
</td>
<td/>
<td/>
@@ -80,10 +139,27 @@
</table>
</div>
- <footer>
- <a href="https://github.com/HFO4/gameboy.live">Gameboy emulator written in Go</a> by <a href="https://github.com/HFO4">Aaron Liu AKA HFO4 on GitHub</a>.<br>
- Input button images also taken from him.
- </footer>
+ <p>
+ <a href="https://github.com/HFO4/gameboy.live">Gameboy emulator written in Go</a> by <a href="https://github.com/HFO4">Aaron Liu AKA HFO4 on GitHub</a>. Also took his images for the buttons.
+ </p>
+
+ </main>
+
+ <footer>
+ <span>
+ <i class="fas fa-address-card" alt="Contact"></i>
+ <a href="https://luevano.xyz/contact.html">Contact</a>
+ </span>
+
+ <span>
+ <i class="fas fa-donate" alt="Donate"></i>
+ <a href="https://luevano.xyz/donate.html">Donate</a>
+ </span>
-</body>
+ <br>
+ <span class="copyright">
+ Copyright <i class="far fa-copyright" alt="Copyright"></i> 2021 David Luévano Alvarado
+ </span>
+ </footer>
+ </body>
</html>
diff --git a/luevano/contact.html b/luevano/contact.html
index 067c619..7977412 100644
--- a/luevano/contact.html
+++ b/luevano/contact.html
@@ -72,7 +72,7 @@
Contact
</h1>
- <img class="wrap-right" src="images/gifs/head_talking_1_trans.gif" alt="Contact info">
+ <img class="wrap-right" src="images/gifs/head_talking_1_trans.gif" width="100px" alt="Contact info">
<p>
You can contact me through:
diff --git a/static/css/gb.css b/static/css/gb.css
index 54682d0..8152469 100644
--- a/static/css/gb.css
+++ b/static/css/gb.css
@@ -1,33 +1,26 @@
-body{
+main {
text-align: center;
- background-color: #e0dbcd;
}
-div.gameboy{
- padding: 10px;
- border-radius: 10px;
+div.gameboy {
display: inline-block;
background-color: #a89f94;
+ border-radius: 10px;
+ padding: 1em;
+ width: clamp(30ch, 100%, 45ch);
}
-img.screen{
+div.gameboy img.screen {
border: 10px solid #2b2b26;
border-radius: 10px;
- width: 320px;
- height: 288px;
+ width: 100%;
}
-table{
+div.gameboy table.controls {
margin-left: auto;
margin-right: auto;
}
-table.controls{
- max-width: 320px;
- height: auto;
-}
-
-.controls input, img{
- height: 35px;
- width: auto;
+div.gameboy table.controls input{
+ width: 100%;
}
diff --git a/static/css/style.css b/static/css/style.css
index 47ec270..915a1f2 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -13,7 +13,8 @@ h2 {
text-align: center;
}
-body, html {
+body,
+html {
margin: 0;
padding: 0;
}
@@ -36,10 +37,13 @@ body > header {
body > footer {
grid-area: footer;
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
}
main {
grid-area: main;
+ padding-top: 0.5em;
border-radius: 5px;
padding-bottom: 0.5em;
}
@@ -48,7 +52,9 @@ a{
text-decoration: none;
}
-body > header, body > footer, main {
+body > header,
+body > footer,
+main {
justify-self: center;
width: clamp(30ch, calc(100% - 1em), 75ch);
padding-left: 0.5em;
@@ -59,6 +65,12 @@ main.art {
width: clamp(30ch, calc(100% - 1em), 100%);
}
+main.art p {
+ margin-left: auto;
+ margin-right: auto;
+ width: clamp(30ch, calc(100% - 1em), 75ch);
+}
+
/* article/art elements */
div.article-info,
@@ -180,6 +192,9 @@ pre {
}
code {
+ padding: 0.1em;
+ padding-left: 0.4em;
+ padding-right: 0.4em;
overflow-wrap: anywhere;
}
@@ -208,6 +223,19 @@ code.crypto {
/* images */
+figure {
+ margin: 0;
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+figcaption {
+ margin-top: 0.5em;
+ text-align: center;
+ font-size: smaller;
+ font-style: italic;
+}
+
img {
border-radius: 5px;
max-width: 100%;
@@ -267,7 +295,6 @@ div.art-grid a {
}
div.art-grid img {
- border: 1px solid white;
object-fit: cover;
}
@@ -293,8 +320,9 @@ a.zoom-in {
cursor: zoom-in;
}
-/* art nav */
-div.art-nav {
+/* art nav / for now also page nav */
+div.art-nav,
+div.page-nav {
width: 100%;
display: grid;
grid-template-areas:
@@ -305,19 +333,23 @@ div.art-nav {
justify-items: center;
}
-div.art-nav > span.index {
+div.art-nav > span.index,
+div.page-nav > span.index {
grid-area: index;
}
-div.art-nav > span.previous {
+div.art-nav > span.previous,
+div.page-nav > span.previous {
grid-area: prev;
}
-div.art-nav > span.next {
+div.art-nav > span.next,
+div.page-nav > span.next {
grid-area: next;
}
-div.art-nav > span {
+div.art-nav > span,
+div.page-nav > span {
border-radius: 5px;
min-width: 1em;
max-width: 10em;
@@ -329,12 +361,14 @@ div.art-nav > span {
margin-right: 0.2em;
}
-div.art-nav > span span {
+div.art-nav > span span,
+div.page-nav > span span {
display: none;
}
@media screen and (min-width: 600px) {
- div.art-nav > span span {
+ div.art-nav > span span,
+ div.page-nav > span span {
display: inline;
}
}
diff --git a/static/css/theme.css b/static/css/theme.css
index 8f900ba..b3bbb18 100644
--- a/static/css/theme.css
+++ b/static/css/theme.css
@@ -44,6 +44,7 @@
--switch-sun: var(--color13);
--code-border: var(--color3);
+ --art-border: var(--color3);
--pagenav-bg: var(--color1);
--pagenav-bg-hl: var(--color2);
@@ -77,6 +78,7 @@
--switch-sun: var(--color13);
--code-border: var(--color4);
+ --art-border: var(--color4);
--pagenav-bg: var(--color10);
--pagenav-bg-hl: var(--color9);
@@ -188,19 +190,32 @@ button.theme-switcher > .fa-sun {
color: var(--switch-sun);
}
-/* art nav */
-div.art-nav > span {
+/* art grid / art gallery */
+div.art-grid img {
+ border: 1px solid var(--art-border);
+}
+
+div.art-grid img:hover {
+ border: 5px solid var(--art-border);
+}
+
+/* art nav / for now also page nav */
+div.art-nav > span,
+div.page-nav > span {
background: var(--pagenav-bg);
}
-div.art-nav > span > a {
+div.art-nav > span > a,
+div.page-nav > span > a {
color: var(--pagenav-link);
}
-div.art-nav > span:hover {
+div.art-nav > span:hover,
+div.page-nav > span:hover {
background: var(--pagenav-bg-hl);
}
-div.art-nav > span:hover > a {
+div.art-nav > span:hover > a,
+div.page-nav > span:hover > a {
color: var(--pagenav-link-hl);
}