summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.footer.html10
-rw-r--r--404.html2
-rw-r--r--auth.html10
-rw-r--r--bat.html6
-rw-r--r--bitcoin.html6
-rw-r--r--calibre.html131
-rw-r--r--certbot.html29
-rw-r--r--cgi.html268
-rw-r--r--cron.html46
-rw-r--r--crypto.html8
-rw-r--r--dns.html14
-rw-r--r--domain.html11
-rw-r--r--federation.html2
-rw-r--r--gemini.html103
-rw-r--r--git.html4
-rw-r--r--gitea.html109
-rw-r--r--html.html6
-rw-r--r--html2.html2
-rw-r--r--html4.html2
-rw-r--r--index.html63
-rw-r--r--irc.html801
-rw-r--r--jitsi.html130
-rw-r--r--maintenance.html2
-rw-r--r--matrix.html87
-rw-r--r--monero.html6
-rw-r--r--nextcloud.html69
-rw-r--r--nginx.html15
-rw-r--r--openalias.html16
-rw-r--r--peertube.html223
-rw-r--r--pix/calibre.pngbin0 -> 17440 bytes
-rw-r--r--pix/calibre/calibre-1.pngbin0 -> 5823 bytes
-rw-r--r--pix/calibre/calibre-2.pngbin0 -> 15884 bytes
-rw-r--r--pix/gitea-push-create.pngbin0 -> 6546 bytes
-rw-r--r--pix/gitea.svg31
-rw-r--r--pix/irc.svg57
-rw-r--r--pix/irc/hexchat-connection-complete.pngbin0 -> 44139 bytes
-rw-r--r--pix/irc/hexchat-network-edit.pngbin0 -> 55960 bytes
-rw-r--r--pix/irc/hexchat-network-select.pngbin0 -> 40520 bytes
-rw-r--r--pix/irc/hexchat-sasl.pngbin0 -> 59369 bytes
-rw-r--r--pix/irc/textual-identity.pngbin0 -> 45779 bytes
-rw-r--r--pix/irc/textual-network-edit.pngbin0 -> 49037 bytes
-rw-r--r--pix/jitsi-01.webpbin0 -> 14998 bytes
-rw-r--r--pix/jitsi.svg650
-rw-r--r--pix/landchad.gifbin0 -> 15127 bytes
-rw-r--r--pix/peertube-login.jpgbin0 -> 76446 bytes
-rw-r--r--pix/peertube.svg118
-rw-r--r--pleroma.html169
-rw-r--r--rss-bridge.html98
-rw-r--r--rss.xml1829
-rw-r--r--rsync.html55
-rw-r--r--server.html9
-rw-r--r--sshkeys.html2
-rw-r--r--standalone.html32
-rw-r--r--style.css42
-rw-r--r--template.html2
-rw-r--r--tor.html34
-rw-r--r--ufw.html193
-rw-r--r--xmpp.html89
58 files changed, 5370 insertions, 221 deletions
diff --git a/.footer.html b/.footer.html
index 902f4eb..2edcf80 100644
--- a/.footer.html
+++ b/.footer.html
@@ -1,7 +1,7 @@
<a href="https://landchad.net">LandChad.net</a></br>
Because Everyone should be an Internet LandChad.</br>
-<li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li>
-<li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li>
-<li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li>
-<li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li>
-<li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a>
+<a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a>
+<a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a>
+<a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a>
+<a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a>
+<a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a>
diff --git a/404.html b/404.html
index cc9933b..05cbe39 100644
--- a/404.html
+++ b/404.html
@@ -22,6 +22,6 @@
will feature all new pages and significant changes.
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/auth.html b/auth.html
index 6c30d7f..49ee445 100644
--- a/auth.html
+++ b/auth.html
@@ -21,8 +21,8 @@
<p>We will be using the command <code>htpasswd</code> to make username and password pairs.</p>
<pre><code>apt install apache2-utils</code></pre>
<aside>
- <p>The apache utils has a small username-password pair encryption tool.</p>
- <p>Like the other on this site, this tutorial is for Nginx, <strong>not</strong> for Apache servers.</p>
+ <p>The apache utils include a small username-password pair encryption tool.</p>
+ <p>Like the other tutorials on this site, this tutorial is for Nginx, <strong>not</strong> for Apache servers.</p>
</aside>
<p>
@@ -81,7 +81,7 @@
<p>If you want to check both a username and password with an ip address, use the <code>satisfy</code> directive.</p>
<pre><code>location /api {
#...
- satify all ;
+ satisfy all ;
allow 192.168.1.23:8080 ;
deny 127.0.0.1 ;
@@ -114,9 +114,9 @@
<p>Reload nginx and you're good to go!</p>
- <strong>Contributor</strong> - <a href="https://tomfasano.xyz" target="_blank">tomfasano.xyz</a>
+ <strong>Contributor</strong> - <a href="https://tomfasano.co" target="_blank">tomfasano.co</a>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/bat.html b/bat.html
index 6d20124..be0f5a2 100644
--- a/bat.html
+++ b/bat.html
@@ -22,7 +22,7 @@
</p>
<p>
- You can receive these donations in BAT itself, or in another cryptocurreny of your choosing.
+ You can receive these donations in BAT itself, or in another cryptocurrency of your choosing.
</p>
<h3>Explanation of the BAT system</h3>
<p>
@@ -33,7 +33,7 @@
<h3>Why you might <em>not</em> want to enroll...</h3>
<p>
Unlike <a href="bitcoin.html">Bitcoin</a> and <a href="monero.html">Monero</a>, BAT is a token organized by a company, and as such, it has to comply with know-your-customer regulations.
- What that means for you is that to get a payout in BAT, you must have an custodial cryptocurrency wallet with either Gemini or Uphold, the two services they are interfaced with.
+ What that means for you is that to get a payout in BAT, you must have a custodial cryptocurrency wallet with either Gemini or Uphold, the two services they are interfaced with.
You can move your payouts elsewhere when you want, but those sites require real-world identification.
</p>
<p>
@@ -87,6 +87,6 @@
Tip buttons will appear on many other social media sites, for example Github commits, projects and comments by users.
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/bitcoin.html b/bitcoin.html
index ec41f23..81fc641 100644
--- a/bitcoin.html
+++ b/bitcoin.html
@@ -75,7 +75,7 @@
In fact, as you use these up, the wallet will automatically add more.
</p>
<p>
- These addresses (which will all be generated with <code>bc1</code> at the beginning can be used by others to send you Bitcoins.
+ These addresses (which will all be generated with <code>bc1</code> at the beginning) can be used by others to send you Bitcoins.
Someone can just copy-and-paste the address into their wallet to send you funds.
</p>
<img src="pix/bitcoin-03.png" alt="bitcoin addresses">
@@ -88,7 +88,7 @@
<h4>What is the QR code for?</h4>
<p>
In case you don't know, a QR code is a way of storing text information in a format that can be scanned by a phone.
- If someone has a wallet program on a phone, then can easily scan the QR code on another screen to avoid having to copy your address over or even worse, write it manually.
+ If someone has a wallet program on a phone, they can easily scan the QR code on another screen to avoid having to copy your address over or even worse, write it manually.
</p>
<h3>Let's receive donations on our website.</h3>
<p>
@@ -97,6 +97,6 @@
Bitcoin users will know how to scan and use them.
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/calibre.html b/calibre.html
new file mode 100644
index 0000000..2251917
--- /dev/null
+++ b/calibre.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Setting up a Calibre library server &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Setting up a Calibre library server</h1></header>
+ <nav></nav>
+ <main>
+ <img src="pix/calibre.png" alt="Calibre logo" class=titleimg>
+ <p>
+ The Calibre library server is a great way to store your eBooks.
+ It allows you to:
+ </p>
+ <ul>
+ <li>Share your books with others.</li>
+ <li>Easily transfer your books between devices and access them from anywhere.</li>
+ </ul>
+
+ <h2>Installation</h2>
+
+ <p>Install the Calibre package.
+ You might also want rsync to upload books.</p>
+
+ <pre><code>apt install -y calibre rsync
+mkdir /opt/calibre</code></pre>
+
+ <p>
+ Either upload your existing library using <code>rsync</code>. For example to <code>/opt/calibre/</code>.
+ <pre><code>cd ~/Documents
+rsync -avuP <strong>your-library-dir</strong> root@<strong>example.org</strong>:/opt/calibre/</code></pre>
+
+ <p>
+ Or create a library and add a book to it:
+ </p>
+
+<pre><code>cd /opt/calibre
+calibredb add <strong>book.epub</strong> --with-library <strong>your-library</strong></code></pre>
+
+ <aside>
+ <p>
+ For more information about the <code>calibredb</code> command see <code>man calibredb</code>.
+ </p>
+ </aside>
+
+ <p>
+ Add a new user to protect your server:
+ </p>
+
+ <pre><code>calibre-server --manage-users</code></pre>
+
+ <h2>Creating a service</h2>
+
+ <p>
+ Create a new file <code>/etc/systemd/system/calibre-server.service</code> and add the following:
+ </p>
+
+<pre><code>[Unit]
+Description=Calibre library server
+After=network.target
+
+[Service]
+Type=simple
+User=root
+Group=root
+ExecStart=/usr/bin/calibre-server --enable-auth --enable-local-write /opt/calibre/your_library --listen-on 127.0.0.1
+
+[Install]
+WantedBy=multi-user.target
+</code></pre>
+ <aside>
+ <p>
+ You can change the port with the <code>--port</code> prefix. Additional information <code>man calibre-server</code>.
+ </p>
+ </aside>
+
+ <p>
+ Issue <code>systemctl daemon-reload</code> to apply the changes.
+ </p>
+
+ <p>
+ Enable and start the service.
+ </p>
+
+<pre><code>systemctl enable calibre-server
+systemctl start calibre-server</code></pre>
+
+ <h2>A reverse proxy with Nginx</h2>
+
+ <p>
+ Create a new file <code>/etc/nginx/sites-available/calibre</code> and enter the following:
+ </p>
+
+<pre><code>server {
+ listen 80;
+ client_max_body_size 64M; # to upload large books
+ server_name <strong>calibre.example.org</strong> ;
+
+ location / {
+ proxy_pass http://127.0.0.1:8080;
+ }
+}</code></pre>
+
+ <p>Issue a Let's Encrypt certificate. <a href="certbot.html">Detailed instructions and additional information</a>.</p>
+
+ <pre><code>certbot --nginx</code></pre>
+
+ <p>Now just go to <strong>calibre.example.org</strong>. The server will request an username and a password.</p>
+
+ <a href="pix/calibre-1.png">
+ <img src="pix/calibre/calibre-1.png" alt="calibre">
+ </a>
+
+ <p>After login you will see something like this.</p>
+
+ <a href="pix/calibre-1.png">
+ <img src="pix/calibre/calibre-2.png" alt="calibre">
+ </a>
+
+ <h2>Contribution</h2>
+ <li>Author: rflx &ndash; <a href="https://rflx.xyz">website</a> -- XMR: <code class=crypto>48T5XpHTXAZ5Nn8YCypA4aWn1ffQLHJkFGDArXQB6cmrP6cqLY72cu7CR2iq2MmL5Ndu3d47e5MKjGpL4prYgdrTCFAHD9c</code>
+ </li>
+ </main>
+<footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+</body>
+</html>
diff --git a/certbot.html b/certbot.html
index cabf6cd..7b5545a 100644
--- a/certbot.html
+++ b/certbot.html
@@ -14,12 +14,12 @@
<main>
<p>
Once you have a website, it is extremely important to enable encrypted connections over HTTPS/SSL.
- You might have no idea what that means, but it's easy to do how we've already <a href="nginx.html">set our server up</a>.
+ You might have no idea what that means, but it's easy to do now that we've <a href="nginx.html">set our web server up</a>.
</p>
<p>
Certbot is a program that automatically creates and deploys the certificates that allow encrypted connections.
- It used to be a pain (and often expensive) to do this, but now it's all free and automatic.
+ It used to be painful (and often expensive) to do this, but now it's all free and automatic.
</p>
<h2>Why is encryption important?</h2>
@@ -41,7 +41,7 @@
<p>Just run:</p>
- <pre><code>apt install python-certbot-nginx</code></pre>
+ <pre><code>apt install python3-certbot-nginx</code></pre>
<p>And this will install <code>certbot</code> and its module for <code>nginx</code>.</p>
@@ -62,7 +62,7 @@ ufw allow 443</code></pre>
<p>
The command will ask you for your email.
- This is so when the certificates need to be renewed in three months, you will get a email about it.
+ This is so when the certificates need to be renewed in three months, you will get an email about it.
You can set the certificates to renew automatically, but it's a good idea to check it the first time to ensure it renewed properly.
You can avoid giving your email by running the command with the <code>--register-unsafely-without-email</code> option as well.
</p>
@@ -76,8 +76,8 @@ ufw allow 443</code></pre>
<img src=pix/certbot-01.png>
<p>
- It will take a moment to create the certiticate, but afterwards, you will be asked if you want to automatically redirect all connections to be encrypted.
- Since this is preferrable, choose 2 to Redirect.
+ It will take a moment to create the certificate, but afterwards, you will be asked if you want to automatically redirect all connections to be encrypted.
+ Since this is preferable, choose 2 to Redirect.
</p>
<img src=pix/certbot-02.png>
@@ -129,8 +129,21 @@ ufw allow 443</code></pre>
For more on cron and crontabs please <a href="cron.html">click here!</a>
</p>
- <span class=next><a href="html.html">Next: Use HTML to Make Simple Webpages</a></span>
+ <span class=prev><a href="nginx.html">Previous: Set up a webserver.</a></span>
+ <!-- <span class=next><a href="html.html">Next: Use HTML to Make Simple Webpages</a></span> -->
+
+ <span class=next>You've reached the end of the basic course!</span>
+
+ <p>
+ You now have a live website on the internet.
+ You can add to it what you wish.
+ </p>
+
+ <p>
+ As you add content to your site, there are many other things you can also install linked on <a href="index.html">the main page</a>,
+ and many more improvements, tweaks and bonuses.
+ </p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/cgi.html b/cgi.html
new file mode 100644
index 0000000..ef1526a
--- /dev/null
+++ b/cgi.html
@@ -0,0 +1,268 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Server-Side Scripting with CGI</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Server-Side Scripting with CGI</h1></header>
+ <nav></nav>
+ <main>
+ <p>
+ The basic website tutorial here describes how to set up a static
+ website &mdash; one that just serves HTML files saved on your server,
+ and until you change something manually, the same content will be served
+ each time a given page is requested. This is perfectly enough for most
+ personal website needs. This is how blogs should be implemented, instead
+ of relying on bloatware like WordPress!
+ </p>
+
+ <p>
+ But sometimes you genuinely <i>do</i> need something more. You need your
+ website to serve different contents depending on the time, on who the
+ requester is, on the contents of a database, or maybe process user input
+ from a form.
+ </p>
+
+ <h2>CGI</h2>
+ <p>
+ CGI, or the Common Gateway Interface, is a specification to allow you,
+ the server owner, to program your web server using pretty much any
+ programming language you might know. The specification is almost as old
+ as the Internet itself and for a long time CGI scripting was the primary
+ method of creating dynamic websites.
+ </p>
+
+ <p>
+ CGI is a very simple specification indeed. You write a script in your
+ favorite language, the script receives input about the request in
+ environment variables, and whatever you print to the standard output
+ will be the response. Most likely, though, you will want to use a
+ library for your language of choice that makes a lot of this
+ request/response handling simpler (e.g. parsing query parameters for
+ you, setting appropriate headers, etc.).
+ </p>
+
+ <h3>Limitations of CGI</h3>
+ <p>
+ While in theory you could implement any sort of functionality with CGI
+ scripts, it's going to get difficult managing a lot of separate scripts
+ if they're supposed to be working in tandem to implement a dynamic
+ website. If you want to build a full out web application, you'd probably
+ be better off learning a web framework than gluing together Perl
+ scripts.
+ </p>
+
+ <p>
+ That said, just as most of the web could be replaced with static
+ websites, much of the remaining non-static web could be replaced with a
+ few simple scripts, rather than bloated Ruby on Rails or Django
+ applications.
+ </p>
+
+ <h2>Let's write a CGI script!</h2>
+
+ <p>
+ We'll implement a simple example CGI script. I'll use Ruby for this
+ tutorial, but you'll be able to follow along even if you don't know
+ Ruby, just treat it as pseudocode then find a CGI library for your
+ language.
+ </p>
+
+ <h3>The working example</h3>
+
+ <p>
+ Our working example will be the Lazy Calculator. Yeah, you're probably
+ tired of seeing calculator examples in every programming tutorial, but
+ have you ever implemented one that takes the weekends off?
+ </p>
+
+ <p>
+ Here's how it will work. When in a browser you submit a request to your
+ website like
+ </p>
+
+ <pre><code>example.com/calculator.html?a=10&amp;b=32</code></pre>
+
+ <p>
+ you will receive a page with the result of the addition of 10 and 32:
+ 42.
+ </p>
+
+ <p>
+ <i>Unless</i> you send your request on a weekend. Then the website will
+ respond with
+ </p>
+
+ <pre><code>I don't get paid to work on weekends! Come back Monday.</code></pre>
+
+ <p>
+ This example will show a few things that CGI scripts can do that you
+ wouldn't have been able to get using just file hosting in your
+ web server:
+
+ <ul>
+ <li> getting inputs from the user; </li>
+ <li>
+ getting external information (here just the system time, but you
+ could imagine instead connecting to a database);
+ </li>
+ <li> using the above to create dynamic output. </li>
+ </ul>
+
+ <h3>The code</h3>
+
+ <p>
+ Here's an implementation of the lazy calculator as a Ruby CGI script:
+ </p>
+
+ <pre><code>#!/bin/env ruby
+
+require 'cgi'
+require 'date'
+
+cgi = CGI.new
+today = Date::today
+
+a = cgi["a"].to_i
+b = cgi["b"].to_i
+
+if today.saturday? || today.sunday?
+ cgi.out do
+ "I don't get paid to work on weekends! Come back Monday."
+ end
+else
+ cgi.out do
+ (a + b).to_s
+ end
+end</code></pre>
+
+ <p>
+ Let's go through what's happening here.
+ </p>
+
+ <h3>The shebang line</h3>
+ <p>
+ CGI works by pointing your web server to an executable program. A Ruby
+ or Python script by itself is not immediately executable by a computer.
+ But on Unix-like systems you can specify the program that will be able
+ to execute your file in its first line if it starts with <code>#!</code>
+ (known as the shebang; read more about it on
+ <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">Wikipedia</a>).
+ </p>
+
+ <p>
+ So if you're going to be using a scripting language, you'll probably
+ need the appropriate shebang line at the top of your script. If you use
+ a compiled language, you'll just point your web server to the compiled
+ executable binary.
+ </p>
+
+ <h3>Query parameters</h3>
+ <p>
+ The next interesting lines of code are where we set the variables
+ <code>a</code> and <code>b</code>. Here we are getting user inputs from
+ the request.
+ </p>
+
+ <p>
+ In the example request we mentioned above
+ (<code>example.com/calculator.html?a=10&amp;b=32</code>), the part
+ starting from the question mark, <code>?a=10&amp;b=32</code>, is the
+ <i>query string</i>. This is how users can submit parameters with their
+ web requests. Usually these parameters are set by e.g. a form on your
+ website, but in our simple example we'll be just manually manipulating
+ the URL.
+ </p>
+
+ <p>
+ The query string contains key-value pairs. The Ruby CGI library makes
+ them available in the <code>CGI</code> object it provides. We just need
+ to index it with the desired key, and we'll get the corresponding value.
+ </p>
+
+ <h3>Wrapping it up</h3>
+ <p>
+ The remaining parts of the code should be pretty self-explanatory. We
+ get today's date, check if it's a Saturday or a Sunday, and depending on
+ that, we instruct the CGI library to output either the answer, or a
+ "come back later" message.
+ </p>
+
+ <p>
+ The Ruby library by default returns an HTML response, so we really
+ should have wrapped our outputs in some <code>html</code>,
+ <code>body</code>, etc. tags. Alternatively, we could have specified
+ that the response is just plain text with
+ </p>
+
+ <pre><code>cgi.out 'text/plain' do</code></pre>
+
+ <p>
+ In general, your CGI library will probably have ways of specifying all
+ sorts of HTTP response headers, like status code, content type, etc.
+ </p>
+
+ <h2>Making it work</h2>
+ <p>
+ We have a CGI script, now let's point our web server to it.
+ </p>
+
+ <h3>Installing FastCGI</h3>
+
+ <p>
+ If you're using Nginx, install <code>fcgiwrap</code>:
+ </p>
+
+ <pre><code>apt install fcgiwrap</code></pre>
+
+ <p>
+ This installs the necessary packages for Nginx to use FastCGI &mdash; a
+ layer between your web server and CGI script that allows for faster
+ handling of scripts than if the web server had to handle it all by
+ itself.
+ </p>
+
+ <p>
+ Other web servers will probably have a similarly simple way of enabling
+ FastCGI, or you can look into other methods for launching CGI scripts.
+ </p>
+
+ <h3>Nginx configuration</h3>
+ <p>
+ In the configuration file for your website, add something like the
+ following:
+ </p>
+
+<pre><code>location /calculator.html {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME /usr/local/bin/lazy-calculator.rb;
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_pass unix:/run/fcgiwrap.socket;
+}</code></pre>
+
+ <p>
+ <code>fastcgi_param</code> directives specify various parameters for
+ FastCGI. <code>SCRIPT_FILENAME</code> should point to your executable.
+ For <code>QUERY_STRING</code>, we just copy Nginx's
+ <code>$query_string</code> variable. You might want to pass other
+ information to your CGI script as well, see for example
+ <a href="https://wiki.debian.org/nginx/FastCGI">the Debian wiki</a> for
+ a more detailed example, including pointing to an entire directory of
+ CGI scripts, rather than adding each one by hand to your web server
+ config.
+ </p>
+
+ <h2>Contribution</h2>
+ <ul>
+ <li>Martin Chrzanowski -- <a
+ href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/donate.html">donate</a></li>
+ </ul>
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/cron.html b/cron.html
index 3f61f23..645dc03 100644
--- a/cron.html
+++ b/cron.html
@@ -19,13 +19,13 @@
<p>
You can schedule anything! Some examples of what you might have done already include:
<ul>
- <li> <code> updatedb </code> to update your <code> locate </code> database </li>
- <li> <code> certbot </code> to update renewing of your https certs </li>
+ <li><code>updatedb</code> to update your <code>locate</code> database</li>
+ <li><code>certbot</code> to update renewing of your https certs</li>
</ul>
Some tasks that you might <em>want</em> to schedule may include:
<ul>
- <li> Package updates - if you really just want to leave your server alone you can automated updating packages on your server </li>
- <li> Backups - you may want to backup certain files every day and some every week, this is possible with cron </li>
+ <li>Package updates - if you really just want to leave your server alone you can automated updating packages on your server</li>
+ <li>Backups - you may want to backup certain files every day and some every week, this is possible with cron</li>
</ul>
<p>
And many more, anything you can do can be turned into a cronjob.
@@ -34,25 +34,25 @@
<h2>Basic Cronjobs</h2>
<p>
- This the preferred method for personal tasks and scripts, it's also the easiest to get started with. Run the command <code> crontab -e </code> to access your users crontab
+ This the preferred method for personal tasks and scripts; it's also the easiest to get started with. Run the command <code>crontab -e</code> to access your user's crontab
</p>
<p>
- Once you have figured out the command you want to run you need to figure out how often you want to run it and when. I am going to schedule my system updates once a week on at 3:30 AM on a Monday.
+ Once you have figured out the command you want to run you need to figure out how often you want to run it and when. I am going to schedule my system updates once a week on at 3:30 AM on Mondays.
</p>
<p>
We now have to convert this time (Every Monday at 3:30 AM) into a cron time. Cron uses a simple but effective way of scheduling when to run things.
</p>
<p>
- Crontab expressions look like this <code> * * * * * command-to-run </code>
+ Crontab expressions look like this <code>* * * * * command-to-run</code>
The five elements before the command tell when the command is supposed to be run automatically.
<p>
- So for our Monday at 3:30AM job we would do the following:
+ So for our Monday at 3:30 AM job we would do the following:
<p>
<pre><code> .---------------- minute (0 - 59)
| .------------- hour (0 - 23)
| | .---------- day of month (1 - 31)
- | | | .------- month (1 - 12
+ | | | .------- month (1 - 12)
| | | | .---- day of week (0 - 6)
| | | | |
* * * * *
@@ -67,7 +67,9 @@
<h3>More examples</h3>
<p>
- Let's add another job, our backup job (for the purposes of this our backup command is just called <code> backup</code>) We want to run <code> backup </code> Every evening at 11PM, once we work out the timings for this we can add the to the same file as the above by running <code> crontab -e </code> This would mean our full crontab would look like this:
+ Let's add another job, our backup job (for the purposes of this our backup command is just called <code>backup</code>).
+ We want to run <code>backup</code> every evening at 11PM.
+ Once we work out the timings for this we can add the to the same file as the above by running <code>crontab -e</code> This would mean our full crontab would look like this:
<pre><code>0 23 * * * backup</code></pre>
<h3>Consecutive times</h3>
@@ -87,21 +89,18 @@
<p>
We can also randomly specify non-consecutive arguments with a comma.
Suppose you have a script you want to run at the midday of the 1st, 15th, and 20th day of every month.
- You can specify that my putting <code>1,15,20</code> for the day of the month argument:
+ You can specify that by putting <code>1,15,20</code> for the day of the month argument:
</p>
<pre><code>0 12 1,15,20 * * /usr/bin/pay_bills_script</code></pre>
<h3>"Every X minutes/days/months"</h3>
- <p>We can also easily run a command very several minutes or months, without specifying the specific times:
- </p>
+ <p>We can also easily run a command every several minutes or months, without specifying the specific times:</p>
<pre><code>*/15 * * * * updatedb</code></pre>
- <p>
- This cronjob will run the <code>updatedb</code> command every 15 minutes.
- </p>
+ <p>This cronjob will run the <code>updatedb</code> command every 15 minutes.</p>
<h3>Beware of this Rookie Mistake Though...</h3>
@@ -146,13 +145,14 @@
</p>
<p>
- Run the command <code> ls /etc/cron* </code> you should see a list of directories and there contents. The directories should be something like the below
+ Run the command <code>ls /etc/cron*</code> you should see a list of directories and there contents. The directories should be something like the below:
+ </p>
<ul>
- <li> /etc/cron.d <em> This is a crontab like the ones that you create with </em> <code> crontab -e </code> </li>
- <li> /etc/cron.hourly </li>
- <li> /etc/cron.daily </li>
- <li> /etc/cron.weekly </li>
- <li> /etc/cron.monthly </li>
+ <li>/etc/cron.d <em>This is a crontab like the ones that you create with</em> <code>crontab -e</code></li>
+ <li>/etc/cron.hourly</li>
+ <li>/etc/cron.daily</li>
+ <li>/etc/cron.weekly</li>
+ <li>/etc/cron.monthly</li>
</ul>
<p>
@@ -169,6 +169,6 @@
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/crypto.html b/crypto.html
index f7b150c..b3c314f 100644
--- a/crypto.html
+++ b/crypto.html
@@ -22,7 +22,7 @@
<p>
To accept donations costs you absolutely nothing.
- It costs you nothing to hold this donations for years before you bother to figure out how it works.
+ It costs you nothing to hold these donations for years before you bother to figure out how it works.
You don't have to do anything now but create a wallet and put a public address up.
</p>
@@ -33,7 +33,7 @@
</p>
<p>
- Cryptocurrency is the first every technology that secures digital scarcity and allows people to transact with one another digitally without any intermediary.
+ Cryptocurrency is the first ever technology that secures digital scarcity and allows people to transact with one another digitally without any intermediary.
</p>
<p>
@@ -56,7 +56,7 @@
It is clunky, old, sometimes expensive to transact with for small amounts, but it is consistent and is coming to function as "digital gold":
a way of storing value over years.
As the Bitcoin network comes to be used by more and more people, companies, countries and others to store value, it also increases the price, which obviously has made many people very rich.
- Bitcoin will surge and crash in cycles, but the long-term trend is unambiguously up and more people store value on the network.
+ Bitcoin will surge and crash in cycles, but the long-term trend is unambiguously up as more people store value on the network.
</p>
<p>
@@ -82,5 +82,5 @@
</ul>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
diff --git a/dns.html b/dns.html
index d14ea02..0130f6d 100644
--- a/dns.html
+++ b/dns.html
@@ -76,7 +76,7 @@
<p>
Now let's get our IPv6 address, which is a little more hidden for some reason.
- IPv6 are important because we are running our of IPv4 addresses so it is highly important to allow connections via IPv6 as it will be standard in the future.
+ IPv6 is important because we are running out of IPv4 addresses, so it is highly important to allow connections via IPv6 as it will be standard in the future.
Anyway, now back on Vultr, click on the server name.
</p>
@@ -87,7 +87,7 @@
<a href=pix/dns-vultr.png><img src="pix/dns-vultr.png" alt="Looking for the IPv6"></a>
<p>
- Now just click on <strong>IPv6</strong> submenu to reveal your IPv6 address.
+ Now just click on the <strong>IPv6</strong> submenu to reveal your IPv6 address.
</p>
<a href=pix/dns-ipv6.png><img src="pix/dns-ipv6.png" alt="The IPv6 address"></a>
@@ -95,14 +95,15 @@
<p>
That ugly looking sequence of numbers and letters with colons in between (<code>2001:19f0:5:ccc:5400:03ff:fe58:324a</code>) is my <strong>IPv6</strong> address.
Yours will look something like it.
- Now let's put it into Epik, this time, be sure to select to put in AAAA records as below:
+ Now let's put it into Epik.
+ This time, be sure to select to put in AAAA records as below:
</p>
<a href=pix/dns-ipv6-done.png><img src="pix/dns-ipv6-done.png" alt="IPv6 complete"></a>
<p>
Now just click "Save Changes."
- It might take a minute for the DNS settings to propgate across the internet.
+ It might take a minute for the DNS settings to propagate across the internet.
</p>
<h2>Test it out!</h2>
@@ -115,13 +116,14 @@
<img src="pix/dns-ping.png" alt="Pinging landchad.net">
<p>
- As you can see, our ping to <code>landchad.net</code> is now being directed to <code>104.238.126.105</code>.
+ As you can see, our ping to <code>landchad.net</code> is now being directed to <code>104.238.128.105</code>.
That means we have successfully set up our DNS records!
You can also run the command <code>host</code> if you have it, which will list both IPv4 and IPv6 addresses for a domain name.
</p>
+ <span class=prev><a href="server.html">Previous: Get a server.</a></span>
<span class=next><a href="nginx.html">Next: Setting up the Webserver</a></span>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/domain.html b/domain.html
index 3e60c68..429c790 100644
--- a/domain.html
+++ b/domain.html
@@ -82,7 +82,7 @@
<p>Now we will get a server to host your website on.</p>
- <span class=next><a href="server.html">Next: Get a Server</a></span>
+ <span class=next><a href="server.html">Next: Get a Server.</a></span>
<hr>
@@ -118,6 +118,8 @@
If you don't want to use Epik, use a registrar based in Russia or China or a country more sympathetic to political criticism.
</p>
+ <p>Here are some registrars to explicitly avoid:</p>
+
<ul>
<li>GoDaddy &ndash; People always want to go here because it's so well advertized.
@@ -126,7 +128,7 @@
</li>
<li>NearlyFreeSpeech &ndash; People have signed up for this minor registrar because of its name that's actually tongue-and-cheek. I will let <a href="https://web.archive.org/web/20210121022350/https://blog.nearlyfreespeech.net/2021/01/19/free-speech-in-2021">this post of theirs</a> speak for itself.
Register a domain here only if you want to have it seized.</li>
- <li>Google, Amazon &ndash; Maybe this is obvious, but if you are trying to escape the control of Google or Amazon, it is a very, self-defeating thing to register your domain with them.</li>
+ <li>Google, Amazon &ndash; Maybe this is obvious, but if you are trying to escape the control of Google or Amazon, it is a very self-defeating thing to register your domain with them. Sites like Parler figured this out the hard way.</li>
</ul>
<p>
@@ -136,10 +138,9 @@
Registrars without principled policies maintain the right to seize your domain name on their whim.
Don't think for a minute that this doesn't apply to you.
</p>
+ <span class=next><a href="server.html">Next: Get a Server.</a></span>
-
- <!--TAGLIST-->
</main>
- <!-- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer> -->
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/federation.html b/federation.html
index 65a742f..e60614a 100644
--- a/federation.html
+++ b/federation.html
@@ -66,6 +66,6 @@
This is also used by other software like <a href="https://joinpeertube.org/">PeerTube</a> (which is a self-hosted YouTube-equivalent), <a href="https://friendi.ca/">Friendica</a> (Facebook equivalent)
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/gemini.html b/gemini.html
new file mode 100644
index 0000000..6bfbe75
--- /dev/null
+++ b/gemini.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>How to set up your own gemini server</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1> Creating and serving gemini capsules </h1></header>
+ <nav></nav>
+ <main>
+ <h2 id="whatis">What is Gemini?</h2>
+ <p><a href="https://gemini.circumlunar.space" target="_blank">Gemini</a> is a new internet protocol which is different from the HTTP and Gopher. It's much cleaner and has a growing community and audience of hackers.</p>
+ <h3>Why use gemini protocol?</h3>
+ <ul>
+ <li>Gemini capsules (webpages of gemini) are lightweight, minimal, and don't use many resources to operate.</li>
+ <li>It can run along with your websites. Gemini capsules use port 1965 by default. Your webserver can run at port 80 or 443 along with gemini server at port 1965. </li>
+ <li>By exploring an alternative protocol, you can check different ways to serve data and blogs.</li>
+ </ul>
+ <p>To access any gemini urls i.e. <code>gemini://example.org</code>, you can use any gemini client such as <a href="https://github.com/makeworld-the-better-one/amfora" target="_blank">amfora</a>, <a href="https://gmi.skyjake.fi/lagrange" target="_blank">lagrange</a>, <a href="https://thelambdalab.xyz/elpher/" target="_blank">elpher</a>, etc.
+ <h2 id="instructions">Instructions</h2>
+ <h3>Create a gemini user</h3>
+ <p>
+ It is most secure and clean to have a separate <code>gemini</code> user, so let's create one:
+ </p>
+ <pre><code>useradd -m -s /bin/bash gemini</code></pre>
+ <p>Now log in as <code>gemini</code> with the following command:</p>
+ <pre><code>su -l gemini</code></pre>
+ <p>To create and serve a gemini capsule, we need three basic steps:</p>
+ <ol>
+ <li>Content &ndash; the webpages in our capsule</li>
+ <li>TLS certificate &ndash; Gemini requires encrypted connection.</li>
+ <li>Gemini server &ndash; the program that makes our capsule available (similar to Nginx for HTTP)</li>
+ </ol>
+ <p>As the gemini user, we can create three different directories to simplify the process:</p>
+ <pre><code>mkdir -p ~/gemini/{content,certificate,server}</code></pre>
+ <h3>Content</h3>
+ <p>This will be the directory where your capsule files will be contained. Gemini uses text/gemini markup (in place of HTTP's equivalent HTML). It heavily borrows from Markdown. Similar to .html or .md, gemini uses .gmi as its extension.</p>
+ <p>To create one gemini file, go inside the <code>content</code> directory and create one <code>index.gmi</code> file.</p>
+ <pre><code>nano gemini/content/index.gmi</code></pre>
+ <p>We can add the content we want in our Gemini capsule here:</p>
+ <pre><code># This is Sample Gemini page
+## With header 1 and header 2
+And a short paragraph like this.
+=> /index.gmi Link to the same page</code></pre>
+ <h3>TLS certificate</h3>
+ <p>Go to the <code>certificate</code> directory which we created earlier and generate a TLS certificate using OpenSSL.</p>
+ <pre><code>cd ~/gemini/certificate/
+openssl req -new -subj "/CN=<strong>example.org</strong>" -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days 3650 -nodes -out cert.pem -keyout key.pem</code></pre>
+ <h3>Gemini server</h3>
+ <h4>Download and prepare the server</h4>
+ <p>There are <a href="https://gemini.circumlunar.space/software">many gemini server software choices available</a>.
+ We will use <code>agate</code> server for now. This is a simple gemini server written in Rust.</p>
+ <p>It's a good idea to always get the most recent version, which you can see <a href="https://github.com/mbrubeck/agate/releases">on the agate releases page</a>. At the time of this writing, that is agate v3.1.0 which we will now download. We will download it to the <code>server</code> directory we made.</p>
+ <pre><code>cd ~/gemini/server
+wget https://github.com/mbrubeck/agate/releases/download/v3.1.0/agate.x86_64-unknown-linux-gnu.gz</code></pre>
+ <p>Unzip the gz, then rename and make it executable:</p>
+ <pre><code>gunzip agate.x86_64-unknown-linux-gnu.gz
+mv agate.x86_64-unknown-linux-gnu agate-server
+chmod +x agate-server</code></pre>
+ <h4>Create a system service</h4>
+ <p>Now we need to create a systemd service to autostart and manage agate.
+ The gemini user does not have permission to do this, so press <code>ctrl-d</code> to log out of the gemini user and return to root.
+ As root, create the file below by opening it in your text editor (nano, vim, etc.):</p>
+ <pre><code>nano /etc/systemd/system/agate.service</code></pre>
+ <p>Add the following content to the file <strong>customizing highlighted text</strong> to your use.</p>
+ <pre><code>[Unit]
+Description=agate
+After=network.target
+
+[Service]
+User=gemini
+Type=simple
+ExecStart=/home/gemini/gemini/server/agate-server --content /home/gemini/gemini/content --certs /home/gemini/gemini/certificate/ --hostname <strong>example.org</strong> --lang <strong>en-US</strong>
+
+[Install]
+WantedBy=default.target</code></pre>
+ <p>Now we are ready to run server. Enable and run agate server.</p>
+ <pre><code>systemctl enable agate
+systemctl start agate</code></pre>
+ <h4>Firewall</h4>
+ <p>Lastly, if you have a firewall running, remember to open port 1965, which is the port number used by gemini:</p>
+ <pre><code>ufw allow 1965</code></pre>
+ <h2>Finalization</h2>
+ <p>Now your server should be running. If everything went okay, you can access your gemini capsule via any gemini client with a url like this:</p>
+ <pre><code>gemini://<strong>example.org</strong></code></pre>
+ <p>Sample gemini site for reference:</p>
+ <pre><code>gemini://gemini.circumlunar.space</code></pre>
+ <p>Enjoy your first gemini capsule.</p>
+ <p>
+ For information about how to write in "gemtext" the markup language in Gemini, see this site: <a href="https://gemini.circumlunar.space/docs/gemtext.gmi">https://gemini.circumlunar.space/docs/gemtext.gmi</a>.
+ As you might guess, it also has an analogous gemini capsule here: gemini://gemini.circumlunar.space/docs/gemtext.gmi
+ </p>
+ <hr>
+ <p><em>Written by <a href="https://nihar.page">nihar.page</a></em></p>
+
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/git.html b/git.html
index b5dd616..67ea0a3 100644
--- a/git.html
+++ b/git.html
@@ -182,9 +182,9 @@ mkdir git</code></pre>
<h2>Contribution</h2>
<ul>
<li>Martin Chrzanowski -- <a
- href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/crypto.html">donate</a></li>
+ href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/donate.html">donate</a></li>
</ul>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/gitea.html b/gitea.html
new file mode 100644
index 0000000..2b9b588
--- /dev/null
+++ b/gitea.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Setting up Gitea &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Setting up Gitea</h1></header>
+ <nav></nav>
+ <main>
+ <img class=titleimg src="pix/gitea.svg">
+ <p>Gitea allows you to self-host your git repositories similar to <a href="git.html">bare repositories</a>, but comes with additional features that you might know from GitHub, such as issues, pull requests or multiple users. Its advantage over GitLab&mdash;another Free Software GitHub clone&mdash;is that it is much more lightweight and easier to setup.</p>
+ <p>Head over to <a href="https://gitea.com">gitea.com</a> to see what it looks like in practice.</p>
+ <p>Although Gitea is lighter than Gitlab, if you have a VPS with only 512MB of RAM, you will probably have to upgrade. Gitea is more memory-intensive than having just a bare git repository.</p>
+
+ <h2>Installing Gitea</h2>
+ <p>First install a few dependencies:</p>
+ <pre><code>apt install curl sqlite3</code></pre>
+ <p>Unfortunately, Gitea itself is not in the official Debian repos, so we will add a third-party repository for it.</p>
+ <p>Add the repo's gpg key to apt's trusted keys:</p>
+
+ <pre><code>curl -sL -o /etc/apt/trusted.gpg.d/morph027-gitea.asc https://packaging.gitlab.io/gitea/gpg.key</code></pre>
+
+ <p>Then add the actual repository to apt:</p>
+
+ <pre><code>echo "deb [arch=amd64] https://packaging.gitlab.io/gitea gitea main" > /etc/apt/sources.list.d/morph027-gitea.list</code></pre>
+
+ <p>Now we can install Gitea:<p>
+
+ <pre><code>apt update
+apt install gitea</code></pre>
+
+ <p>Since apt automatically enables and starts the Gitea service, it should already be running on port <code>3000</code> on your server!</p>
+
+ <h2>Setting up a Nginx reverse proxy</h2>
+ <p>You should know how to generate SSL certificates and use Nginx by now. Add this to your Nginx config to proxy requests made to your git subdomain to Gitea running on port 3000:</p>
+
+ <pre><code>
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ ssl_certificate /etc/ssl/nginx/<strong>git.example.org</strong>.crt;
+ ssl_certificate_key /etc/ssl/nginx/<strong>git.example.org</strong>.key;
+ server_name <strong>git.example.org</strong>;
+ location / {
+ proxy_pass http://localhost:3000/; # The / is important!
+ proxy_redirect off;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+}
+ </pre></code>
+ <p>And reload Nginx:</p>
+ <pre><code>systemctl reload nginx</code></pre>
+
+ <h2>Setting up Gitea</h2>
+
+ <p>If everything worked fine you should now see a setup screen when you go to your configured domain in the browser. The options should be pretty self-explanatory, it is only important to select SQLite3 and to replace the base url and SSH server domain with your own.</p>
+
+ <dl>
+ <dt>Database Type:</dt>
+ <dd>SQLite3</dd>
+ <dt>SSH Server Domain:</dt>
+ <dd><strong>git.example.org</strong></dd>
+ <dt>Gitea Base URL:</dt>
+ <dd><strong>git.example.org</strong></dd>
+ </dl>
+
+ <p>These and other settings can be changed in a configuration file later so don't worry about making wrong decisions right now.</p>
+
+ <p>After clicking the install button you should now be able to log into your Gitea instance with the account you just created! Explore the settings for more things to do, such as setting up your SSH keys.</p>
+
+ <p>If Gitea does not load fully and has random errors, it is possible that you need to increase your available memory on your VPS. This can usually be done on your VPS-provider's website without too much trouble.</p>
+
+ <h2>A few extras</h2>
+ <h3>Automatically create a new repo on push</h3>
+ <p>This is an incredibly useful feature for me. Open up <code>/etc/gitea/app.ini</code> and add <code>DEFAULT_PUSH_CREATE_PRIVATE = true</code> to the <code>repository</code> section like so:</p>
+ <img src=pix/gitea-push-create.png>
+ <br>
+ <p>If you now add a remote to a repository like this</p>
+ <pre><code>git remote add origin 'ssh://gitea@git.<strong>example.org</strong>/<strong>username</strong>/<strong>coolproject</strong>.git'</code></pre>
+ <p>and push, Gitea will automatically create a private <code>coolproject</code> repository in your account!</p>
+
+ <h3>Change tab-width</h3>
+ <p>By default Gitea displays tabs 8 spaces wide, however I prefer 4 spaces. We can change this!</p>
+ <pre><code>mkdir -p /var/lib/gitea/custom/templates/custom/</code></pre>
+ <p>And write this into <code>/var/lib/gitea/custom/templates/custom/header.tmpl</code>:</p>
+ <pre><code>&ltstyle&gt
+.tab-size-8 {
+ tab-size: 4 !important;
+ -moz-tab-size: 4 !important;
+}
+&lt/style&gt</code></pre>
+
+
+ <h2>Contribution</h2>
+ <ul>
+ <li><a href="https://phire.cc">phire</a></li>
+ </ul>
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/html.html b/html.html
index e12d8ac..6ff3f73 100644
--- a/html.html
+++ b/html.html
@@ -31,7 +31,7 @@
It is the "language" that all webpages are written in so that all browsers can read and display them properly.
</p>
<p>
- A <dfn>markup language</dfn> <em>not</em> the same as a programming language:
+ A <dfn>markup language</dfn> is <em>not</em> the same as a programming language:
Programming languages specify orders for a computer, while markup languages are ways of specifying the styling of text.
Markup languages are necessary because computers run on mere text, not colors, sizes, headers and other styling things.
</p>
@@ -142,7 +142,7 @@ Heading tags are for your page's title and section headings in the document:
<h4>A preview to CSS</h4>
<p>
-It is very imporant to use headings like this for your pages.
+It is very important to use headings like this for your pages.
Notice that on this website, headings come in different colors, text-alignment and sizes for emphasis.
If we use these heading tags, when we clear CSS, we can easily style all <code>&lt;h2&gt;</code>, for example,
@@ -195,6 +195,6 @@ We can make bold, italic, underlined or struck through text with more HTML tags:
<span class=next><a href="html2.html">Next: Images and Links in HTML</a></span>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/html2.html b/html2.html
index 3360f1f..4d5873a 100644
--- a/html2.html
+++ b/html2.html
@@ -22,6 +22,6 @@
&lt;<++>&gt;
<span class=next><a href="<++>">Next:<++></a></span>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/html4.html b/html4.html
index 39475b9..32c5639 100644
--- a/html4.html
+++ b/html4.html
@@ -94,6 +94,6 @@
<span class=next><a href="css.html">Next: Styling with CSS</a></span>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/index.html b/index.html
index cab7e9e..5b9d84f 100644
--- a/index.html
+++ b/index.html
@@ -9,6 +9,10 @@
<link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
</head>
+<style>
+img { border: none ;}
+</style>
+
<body>
<header><h1>Chad's Guide to Starting Your Own Website</h1></header>
<nav></nav>
@@ -47,27 +51,41 @@
<h3 id=other>Excellent Extras</h3>
<ul class=ll>
- <li><a href="maintenance.html">How to maintain a server.</a></li>
+ <li><a href="rsync.html">Rsync: Upload and Sync Files and Websites</a></li>
+ <li><a href="maintenance.html">How to Maintain a Server.</a></li>
<li><a href="sshkeys.html">Use your SSH keys to prevent hacking.</a></li>
<li><a href="cron.html">Schedule tasks with Crontabs/Cronjobs.</a></li>
+ <li><a href="cgi.html">Server side scripting with CGI</a></li>
<li><a href="tor.html">Mirror your site on <img src="pix/tor.svg">Tor.</a></li>
<li><a href="auth.html">Password-protecting Webpages (HTTP Authentication)</a></li>
+ <li><a href="ufw.html">Using ufw as a firewall.</a></li>
+ <li><a href="gemini.html">Create a Gemini Capsule.</a></li>
+ <li><a href="standalone.html">Standalone Certbot Certificates</a></li>
</ul>
<h3 id=platform>"Build your own platform!"</h3>
- <ul class=ll>
- <li><a href="git.html">Host your own <img src="pix/git.svg"><code>git</code> repositories</a></li>
- <li><a href="nextcloud.html">Setting up a <img src="pix/nextcloud.svg">Nextcloud Instance (file hosting and more)</a></li>
- </ul>
+
+ <dl class=ll>
+ <dt><a href="xmpp.html"><img src="pix/xmpp.svg" alt="xmpp logo"> XMPP</a></dt><dd>Minimalist and federated chat server</dd>
+ <dt><a href="pleroma.html">Pleroma</a></dt><dd>A federated Twitter-like microblogging Site</dd>
+ <dt><a href="peertube.html"><img src="pix/peertube.svg" alt="peertube logo"> PeerTube</a></dt><dd>A federated YouTube-like video Site</dd>
+ <dt><a href="nextcloud.html"><img src="pix/nextcloud.svg"> Nextcloud</a></dt><dd>Setting up a Nextcloud Instance (file hosting and more)</dd>
+ <dt><a href="jitsi.html"><img src="pix/jitsi.svg" alt="Jitsi logo"> Jitsi</a></dt><dd>Free and easy video conferencing</dd>
+ <dt><a href="git.html"><img src="pix/git.svg"> git</a></dt><dd>Version control software on your own server</dd>
+ <dt><a href="gitea.html"><img src="pix/gitea.svg"> Gitea</a></dt><dd>A fully-featured git and issue tracking site</dd>
+ <dt><a href="irc.html"><img src="pix/irc.svg"> IRC</a></dt><dd>Installing and managing a classic internet relay chat server</dd>
+ <dt><a href="rss-bridge.html">RSS Bridge</a></dt><dd>Creating RSS feeds for social media sites</dd>
+ <dt><a href="calibre.html"><img src="pix/calibre.png"> Calibre</a></dt><dd>A library server</dd>
+ </dl>
<h3 id=crypto>Accepting Cryptocurrency Tips</h3>
- <ul class=ll>
- <li><a href="crypto.html">The Case for Crypto for Normal People</a></li>
- <li><a href="bitcoin.html">Accept <img src="pix/btc.svg" alt="btc logo">Bitcoin (BTC) donations</a></li>
- <li><a href="monero.html">Accept <img src="pix/xmr.svg" alt="xmr logo">Monero (XMR) donations for superior privacy</a></li>
- <li><a href="openalias.html">OpenAlias to make crypto easy</a></li>
- <li><a href="bat.html"><img src="pix/bat.svg">Basic Attention Token (BAT)</a></li>
- </ul>
+ <dl class=ll>
+ <dt><a href="crypto.html">Why crypto?</a></dt><dd>The case for crypto for normal people</dd>
+ <dt><a href="bitcoin.html"><img src="pix/btc.svg" alt="btc logo"> Bitcoin</a></dt><dd>Accept Bitcoin (BTC) donations</dd>
+ <dt><a href="monero.html"><img src="pix/xmr.svg" alt="xmr logo"> Monero</a></dt><dd>Accept Monero (XMR) donations for superior privacy</dd>
+ <dt><a href="openalias.html">OpenAlias</a></dt><dd>OpenAlias to make crypto easy</dd>
+ <dt><a href="bat.html"><img src="pix/bat.svg"> BAT</a></dt><dd>Receive donations via the Brave browser</dd>
+ </dl>
<h2>In the Works...</h2>
@@ -81,10 +99,7 @@
<ul>
<li>Full HTML tutorial</li>
<li>Full CSS tutorial</li>
- <li>Setting up an Email server</li>
- <li>Using rsync for websites and servers.</li>
<li>RSS feeds</li>
- <li>XMPP Prosody (federated chat)</li>
<li>Matrix (federated chat)</li>
<li>SearX (search engine)</li>
</ul>
@@ -100,21 +115,21 @@
</p>
<ul>
- <li>IRC servers</li>
+ <li><a href="https://btcpayserver.org/">BTCPay</a></li>
<li>Email webclients</li>
<li>Simple static site generators</li>
- <li>Calibre (library server)</li>
+ <li><a href="https://www.ejabberd.im/">XMPP ejabberd</a></li>
+ <li><a href="https://movim.eu/">Movim for XMPP</a></li>
<li>Nitter</li>
- <li>Pleroma (like Twitter)</li>
- <li>PeerTube (like YouTube)</li>
- <li>Using ufw as a firewall.</li>
- <li>XMPP ejabberd</li>
- <li>Movim for XMPP</li>
</ul>
<h2>Support LandChad.net</h2>
+ <p>Help advertize this site by adding this banner with a link on your website:</p>
+
+ <a href="https://landchad.net"><img src="pix/landchad.gif" alt="LandChad.net"></a>
+
<p>
No ads, trackers or trash on this site.
We are funded by doing good and earning gratitude.
@@ -122,7 +137,7 @@
</p>
<ul class=ll>
- <li>When settings up a website, use our linked affiliate links, like <a href="https://www.vultr.com/?ref=8384069-6G">to Vultr</a>.</li>
+ <li>When setting up a website, use our linked affiliate links, like to <a href="https://www.vultr.com/?ref=8384069-6G">Vultr</a> or <a href="https://my.frantech.ca/aff.php?aff=3886">Frantech/BuyVM</a> for a VPS.</li>
<li>If you enjoy a guest article, the author's donation links may be included at the bottom of the page.</li>
<li>Donate crypto to the long-term LandChad maintenance and expansion fund:</li>
</ul>
@@ -146,6 +161,6 @@
<!--TAGLIST-->
</main>
- <!-- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer> -->
+ <!-- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer> -->
</body>
</html>
diff --git a/irc.html b/irc.html
new file mode 100644
index 0000000..2b5f704
--- /dev/null
+++ b/irc.html
@@ -0,0 +1,801 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Creating Your Own Chat Server With IRC &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Creating Your Own Chat Server With IRC</h1></header>
+ <nav></nav>
+ <main>
+ <img class=titleimg src="pix/irc.svg">
+ <p>
+ Creating your own chat server for you and your friends is easy, and you don't have to rely on a complicated system to get started.
+ IRC is an old but gold protocol, and has clients for basically every operating system made since the 80s, with many powerful modern ones on Linux, Mac, and Windows.
+ </p>
+
+ <p>
+ Having a chat server for you and your friends makes it impossible for a group of arbitrarily appointed moderators to deplatform you for wrong-think, and gives you greater freedom of communication.
+ </p>
+
+ <h2 id="installing">Installing an IRCd</h2>
+
+ <p>
+ An IRCd is short for "IRC daemon", which just means an IRC server.
+ The most easy IRCd to set up is <a href="https://ergo.chat/">Ergo</a>.
+ </p>
+
+ <p>
+ The first thing you need to do is create a new user for the server to be run by.
+ This is good practice for installing software/servers manually, as it give you more fine-grained control over which permissions the application has.
+ </p>
+
+<pre><code>useradd -m ergo -s /bin/bash</code></pre>
+
+ <p>
+ Next, we want to switch to our newly created <code>ergo</code> user and create the server directory.
+ </p>
+
+<pre><code>sudo -i -u ergo
+mkdir server</code></pre>
+
+ <p>
+ You can find the latest release of Ergo on its GitHub <a href="https://github.com/ergochat/ergo/releases/latest">latest release</a> page.<br>
+ There are several platforms available, but you want to choose Linux, most likely <code>linux-x86_64</code>.<br>
+ Once you have selected the correct package, copy its URL and replace the release url with the package URL (still as the <code>ergo</code> user):
+ </p>
+
+<pre><code>wget https://github.com/ergochat/ergo/releases/download/v2.7.0/ergo-2.7.0-linux-x86_64.tar.gz
+tar -xf ergo-2.7.0-linux-x86_64.tar.gz
+mv ergo-2.7.0-linux-x86_64/*
+rm -r ergo-2.7.0-linux-x86_64*</code></pre>
+
+ <p>Executing <code>ls -l</code> should now yield something like this:</p>
+
+<pre><code>-rw-r--r-- 1 ergo ergo 118825 Jun 8 00:51 CHANGELOG.md
+-rw-r--r-- 1 ergo ergo 1983 May 31 01:48 README
+-rw-r--r-- 1 ergo ergo 41440 Jun 8 00:42 default.yaml
+drwxr-xr-x 2 ergo ergo 4096 Jul 1 09:01 docs
+-rwxr-xr-x 1 ergo ergo 9654272 Jun 8 00:53 ergo
+-rw-r--r-- 1 ergo ergo 1753 May 31 01:48 ergo.motd
+drwxr-xr-x 2 ergo ergo 12288 Jul 1 09:01 languages
+-rw-r--r-- 1 ergo ergo 39722 Jun 8 00:42 traditional.yaml</code></pre>
+
+ <p>If you see something similar to the above, that means Ergo is installed, although not quite ready to run yet.</p>
+
+ <h2 id="configuring">Configuring Ergo</h2>
+
+ <p>
+ Now that Ergo is installed, you want to configure it to fit the needs of your group.<br>
+ The configuration in this section is tailored towards a small group of people, and less for a possibly large network,
+ but it should work for any size of group.
+ </p>
+
+ <p>
+ First thing, make sure you're still using the <code>ergo</code> user, and are in the <code>~/server</code> directory.<br>
+ If you aren't, you can run the following to get back there:
+ </p>
+
+<pre><code>sudo -i -u ergo
+cd ~/server</code></pre>
+
+ <p>To start configuring, we need to copy some files:</p>
+
+<pre><code>cp default.yaml ircd.yaml
+cp ergo.motd ircd.motd</code></pre>
+
+ <p>
+ Next, generate certificate files for TLS:
+ </p>
+
+ <pre><code>./ergo mkcerts</code></pre>
+
+ <p>
+ Ergo comes with a default configuration file with detailed documentation that can be used to guide you through the configuration process.
+ This guide will help you setup the server for a typical use-case, but if you see any settings that you would like to change along the way,
+ go ahead and change them, as long as you know what you're doing.
+ </p>
+
+ <p>
+ The next steps involve editing the newly copied <code>ircd.yaml</code> file. If you do not know how to edit text files from the command line,
+ you can use <code>nano</code>, which is very simple, using arrow keys to navigate, <code>CTRL+O</code> to save, and <code>CTRL+X</code> to exit.<br>
+ Another option is <code>vim</code>, which is a much more powerful text editor, but has a learning curve. It is only recommended for this guide if you already know how to use it.<br>
+ Lastly, you can copy the <code>ircd.yaml</code> file to a text editor on your computer and edit it with a GUI text editor of your choice.
+ If that is what you choose to do, you may want to just download the file from <a href="https://raw.githubusercontent.com/ergochat/ergo/master/default.yaml">Ergo's GitHub</a>,
+ edit it on your computer, clear the <code>ircd.yaml</code> file on the server, and then paste the contents from your computer into the blank file.<br>
+ No matter how you do it, the next steps assume you can edit the configuration file.
+ </p>
+
+ <p>
+ <b>Note</b>:<br>
+ The options highlighted in this section are not a complete overview of all options.
+ Instead, the options shown are the ones which are most relevant to a small network.<br>
+ You should read over the configuration file yourself if you are curious about everything you can change.
+ </p>
+
+ <h3 id="configuring-names">Network and server names</h3>
+ <p>
+ One of the first properties in the config file is network name.
+ You can change this to whatever you like, as it will show up as the name when you connect to the server.
+ </p>
+
+<pre><code># network configuration
+network:
+ # name of the network
+ name: "Land-Chat"</code></pre>
+
+ <p>Change the server name to your server's domain name.</p>
+
+<pre><code># server configuration
+server:
+ # server name
+ name: "example.org"</code></pre>
+
+ <h3 id="configuring-password">Network password</h3>
+ <p>
+ The next step is optional, depending on if you want your network password protected or not.
+ The benefit of password protection is fairly obvious; nobody can connect to your network unless you gave them the password.
+ If you're wanting to run a public network which anyone can join and create a channel, you want to skip this, but for personal setups,
+ it is highly recommended.
+ </p>
+
+ <p>Generate a password to use by executing the following:</p>
+
+ <pre><code>./ergo genpasswd</code></pre>
+
+ <p>
+ It will ask you to enter a password and confirm it, then you will be given a hashed password.<br>
+ Copy this password, and paste it into the following field (also removing the <code>#</code> before the <code>password:</code> line):
+ </p>
+
+<pre><code># password to login to the server, generated using `ergo genpasswd`:
+password: "<i>&lt;your hashed password&gt;</i>"</code></pre>
+
+ <h3 id="configuring-motd">Message of the day (MotD)</h3>
+ <p>Change the MotD (<b>M</b>essage <b>o</b>f <b>t</b>he <b>D</b>ay) file to the one you copied earlier:</p>
+
+<pre><code># motd filename
+# if you change the motd, you should move it to ircd.motd
+motd: ircd.motd</code></pre>
+
+ <p>Feel free to edit <code>ircd.motd</code> to your heart's content. Its contents will be sent to clients when they connect to the network.</p>
+
+ <h3 id="configuring-ip-limits">IP limits</h3>
+ <p>
+ For security purposes, you might want to limit the amount of client connections per IP.
+ For a private network, 4 is likely the maximum amount of connections you will have per IP, so that is a safe value.<br>
+ If your network is password protected, this is less of an issue, since the only people connecting will be people who have the password.
+ The following is the default, but you can change it to be whichever value you like:
+ </p>
+
+<pre><code># IP-based DoS protection
+ip-limits:
+ # whether to limit the total number of concurrent connections per IP/CIDR
+ count: true
+ # maximum concurrent connections per IP/CIDR
+ max-concurrent-connections: 16</code></pre>
+
+ <h3 id="configuring-ip-cloaking">IP cloaking</h3>
+ <p>
+ Traditionally, IRC networks expose users' IP addresses to everyone. This is not a good practice for privacy, however.
+ With Ergo, IP cloaking is enable by default. You can enable or disable it if you like, and change how it looks to users.<br>
+ In this case, <code>netname</code> was changed to <code>"chad"</code>.
+ </p>
+
+<pre><code># IP cloaking hides users' IP addresses from other users and from channel admins
+# (but not from server admins), while still allowing channel admins to ban
+# offending IP addresses or networks. In place of hostnames derived from reverse
+# DNS, users see fake domain names like pwbs2ui4377257x8.irc. These names are
+# generated deterministically from the underlying IP address, but if the underlying
+# IP is not already known, it is infeasible to recover it from the cloaked name.
+# If you disable this, you should probably enable lookup-hostnames in its place.
+ip-cloaking:
+ # whether to enable IP cloaking
+ enabled: true
+
+ # whether to use these cloak settings (specifically, `netname` and `num-bits`)
+ # to produce unique hostnames for always-on clients. you can enable this even if
+ # you disabled IP cloaking for normal clients above. if this is disabled,
+ # always-on clients will all have an identical hostname (the server name).
+ enabled-for-always-on: true
+
+ # fake TLD at the end of the hostname, e.g., pwbs2ui4377257x8.irc
+ # you may want to use your network name here
+ netname: "chad"</code></pre>
+
+ <h3 id="configuring-hexchat-password">Password enforcement adjustments for HexChat (and possibly other clients)</h3>
+ <p>
+ Ergo offers account registration to allow users to do things like use history and bouncer features, register channels, etc.<br>
+ In clients such as HexChat, server passwords may conflict with account passwords, so the following setting should be enabled if you wish to use accounts with clients such as HexChat.<br>
+ Note that this could under some circumstances be considered a security hazard, as a user with an account does not need to know the server password to connect,
+ although that user would have needed to register an account before the server had a password, and then a password would need to have been set after the fact, so this can be considered a very small concern if your setup has always had a password.<br>
+ Also keep in mind that this setting has no effect if your network does not even have a password at all.
+ </p>
+
+<pre><code># some clients (notably Pidgin and Hexchat) offer only a single password field,
+# which makes it impossible to specify a separate server password (for the PASS
+# command) and SASL password. if this option is set to true, a client that
+# successfully authenticates with SASL will not be required to send
+# PASS as well, so it can be configured to authenticate with SASL only.
+skip-server-password: true</code></pre>
+
+ <h3 id="configuring-multiclient">Multiclient, always-on clients, history, etc</h3>
+ <p>
+ Traditionally, IRC servers have no message history, and once you close your client, you cannot receive messages, and are not shown to be online at all.
+ Ergo includes functionality to allow users to both receive history, and keep their clients "online" even after they have left.
+ It also allows multiple clients to connect to the same account.<br>
+ If you are running a private network for friends, you should set <code>always-on</code> and <code>auto-away</code> to <code>opt-out</code>,
+ to have all users with accounts to appear as if they are online at all times, and be able to receive messages when they are offline.<br>
+ For a public network, keep everything as their default values, since you probably do not want randoms having this by default.<br>
+ If for some reason you do not want any of these features at all, you can set <code>enabled</code> to <code>false</code>, but this is not recommended.
+ Below are the recommended values for a private network (e.g. for friends) where users with accounts will be able to receive messages and history while they are offline.
+ </p>
+
+<pre><code># multiclient controls whether Ergo allows multiple connections to
+# attach to the same client/nickname identity; this is part of the
+# functionality traditionally provided by a bouncer like ZNC
+multiclient:
+ # when disabled, each connection must use a separate nickname (as is the
+ # typical behavior of IRC servers). when enabled, a new connection that
+ # has authenticated with SASL can associate itself with an existing
+ # client
+ enabled: true
+
+ # if this is disabled, clients have to opt in to bouncer functionality
+ # using nickserv or the cap system. if it's enabled, they can opt out
+ # via nickserv
+ allowed-by-default: true
+
+ # whether to allow clients that remain on the server even
+ # when they have no active connections. The possible values are:
+ # "disabled", "opt-in", "opt-out", or "mandatory".
+ always-on: "opt-out"
+
+ # whether to mark always-on clients away when they have no active connections:
+ auto-away: "opt-out"
+
+ # QUIT always-on clients from the server if they go this long without connecting
+ # (use 0 or omit for no expiration):
+ #always-on-expiration: 90d</code></pre>
+
+ <h3 id="configuring-vhosts">VHosts</h3>
+ <p>
+ IP cloaking was mentioned previously, and somewhat related to that, Ergo includes "vhost" functionality, which allows users to set a custom IP/host string.
+ This is mostly for cosmetic value, and does not interfere with operators being able to see actual IP addresses for banning, but if you do not want it enable for some reason, you can disable it.
+ </p>
+
+<pre><code># vhosts controls the assignment of vhosts (strings displayed in place of the user's
+# hostname/IP) by the HostServ service
+vhosts:
+ # are vhosts enabled at all?
+ enabled: true</code></pre>
+
+ <h3 id="configuring-channels">Channels</h3>
+ <p>
+ Channels are where everyone on an IRC network talk. By default, anyone can create a channel, and anyone with an account can register one.
+ The difference between a normal channel and a registered one is that the registered one will preserve the operator status of the person who created,
+ whereas a normal channel's owner will lose operator status if they leave the channel or disconnect from the network.<br>
+ There are various settings for channels available, but the defaults are suitable for a private network with trust among users, or where you just want anyone to have the ability to create a channel.
+ Below are the default values:
+ </p>
+
+<pre><code># channel options
+channels:
+ # modes that are set when new channels are created
+ # +n is no-external-messages and +t is op-only-topic
+ # see /QUOTE HELP cmodes for more channel modes
+ default-modes: +nt
+
+ # how many channels can a client be in at once?
+ max-channels-per-client: 100
+
+ # if this is true, new channels can only be created by operators with the
+ # `chanreg` operator capability
+ operator-only-creation: false
+
+ # channel registration - requires an account
+ registration:
+ # can users register new channels?
+ enabled: true
+
+ # restrict new channel registrations to operators only?
+ # (operators can then transfer channels to regular users using /CS TRANSFER)
+ operator-only: false
+
+ # how many channels can each account register?
+ max-channels-per-account: 15</code></pre>
+
+ <h3 id="configuring-operators">Operators (administrators, etc)</h3>
+ <p>
+ The IRC term for an administrator or another privileged user is "operator", or "oper" for short.<br>
+ Ergo's opers have different permissions that can be granted to them, and are defined in "classes", basically groups of permissions under a name.
+ For example, "chat-moderator" and "server-admin" are defined in the default configuration:
+ </p>
+
+<pre><code># operator classes
+oper-classes:
+ # chat moderator: can ban/unban users from the server, join channels,
+ # fix mode issues and sort out vhosts.
+ "chat-moderator":
+ # title shown in WHOIS
+ title: Chat Moderator
+
+ # capability names
+ capabilities:
+ - "kill"
+ - "ban"
+ - "nofakelag"
+ - "roleplay"
+ - "relaymsg"
+ - "vhosts"
+ - "sajoin"
+ - "samode"
+ - "snomasks"
+
+ # server admin: has full control of the ircd, including nickname and
+ # channel registrations
+ "server-admin":
+ # title shown in WHOIS
+ title: Server Admin
+
+ # oper class this extends from
+ extends: "chat-moderator"
+
+ # capability names
+ capabilities:
+ - "rehash"
+ - "accreg"
+ - "chanreg"
+ - "history"
+ - "defcon"
+ - "massmessage"</code></pre>
+
+ <p>
+ The above can be kept with their default values, but you are free to modify them or create any new classes that are appropriate for your setup.<br>
+ Next, let's actually create an operator account:
+ </p>
+
+<pre><code># ircd operators
+opers:
+ # default operator named 'gigachad'; log in with /OPER gigachad &lt;password&gt;
+ "gigachad":
+ # which capabilities this oper has access to
+ class: "server-admin"
+
+ # custom whois line
+ whois-line: is the server administrator
+
+ # custom hostname
+ vhost: "gigachad"
+
+ # normally, operator status is visible to unprivileged users in WHO and WHOIS
+ # responses. this can be disabled with 'hidden'. ('hidden' also causes the
+ # 'vhost' line above to be ignored.)
+ hidden: false
+
+ # modes are modes to auto-set upon opering-up. uncomment this to automatically
+ # enable snomasks ("server notification masks" that alert you to server events;
+ # see `/quote help snomasks` while opered-up for more information):
+ #modes: +is acjknoqtuxv
+
+ # operators can be authenticated either by password (with the /OPER command),
+ # or by certificate fingerprint, or both. if a password hash is set, then a
+ # password is required to oper up (e.g., /OPER dan mypassword). to generate
+ # the hash, use `ergo genpasswd`.
+ password: "<i>&lt;your oper password&gt;</i>"</code></pre>
+
+ <p>
+ This is a modified version of the default oper entry. The account name is "gigachad", but you can change it to anything.<br>
+ Replace <code><i>&lt;your oper password&gt;</i></code> with a password generated by <code>./ergo genpasswd</code>, and you will have a new oper account to use.<br>
+ Note that to log into an oper account, clients have to enter <code>/OPER <i>&lt;oper name&gt;</i> <i>&lt;oper password&gt;</i></code> each time they log in.
+ This can be automated by most clients by setting the command to be executed when the client logs in.
+ In the case of HexChat, you can edit your network and add the command to the <code>Connect commands</code> tab of the menu.<br>
+ You can copy everything from <code>"gigachad"</code> to the end of the line, paste it again, and change the name to create another oper account.
+ Another, less privileged example of an oper is shown as a comment below the above configuration snippet.
+ </p>
+
+ <h3 id="configuring-history">Chat history</h3>
+ <p>
+ Traditionally, IRC networks do not store, relay, or handle chat history in any way.<br>
+ On a privacy standpoint, this is a good thing, since chats are entirely ephemeral and handled by clients.<br>
+ On a practicality standpoint, this is a bad thing, since people have to keep a client connected 24/7 to see message history.<br>
+ For normalfriends, this can be a big problem, not only because having to stay online 24/7 is just annoying or infeasible,
+ but also because they are likely used to chat platforms that handle history for them.<br>
+ With this in mind, enabling history is a good idea if you want to move friends over to IRC, and will make things a lot more pleasant for private networks.
+ </p>
+
+ <p>
+ Ergo's <code>history</code> configuration group is very long, so it is encouraged to read over it yourself.
+ This section will go over the most important pieces of that configuration group.
+ </p>
+
+ <p>
+ History is not endless (unless you want it to be), and the amount that can be stored for channels is configurable:
+ </p>
+
+<pre><code># how many channel-specific events (messages, joins, parts) should be tracked per channel?
+channel-length: 2048</code></pre>
+
+ <p>
+ History is already enabled by default, but that just means it is being collected, not relayed by default.
+ To relay history to clients when they connect, change the following to the amount of messages that you think is appropriate:
+ </p>
+
+<pre><code># number of messages to automatically play back on channel join (0 to disable):
+autoreplay-on-join: 250</code></pre>
+
+ <p>
+ History older than a certain time can be configured to be deleted or be inaccessible.
+ The default cutoff time is 1 week, but this is configurable as well.
+ </p>
+
+<pre><code>
+# options to delete old messages, or prevent them from being retrieved
+restrictions:
+ # if this is set, messages older than this cannot be retrieved by anyone
+ # (and will eventually be deleted from persistent storage, if that's enabled)
+ expire-time: 1w
+</code></pre>
+
+ <p>
+ By default, Ergo only stores chat history in memory, so when the server restarts, all history is lost.
+ If you wish to have chat history persist beyond restarts, you must store it in a MySQL database:
+ </p>
+
+<pre><code># options to store history messages in a persistent database (currently only MySQL).
+# in order to enable any of this functionality, you must configure a MySQL server
+# in the `datastore.mysql` section.
+persistent:
+ enabled: true
+
+ # store unregistered channel messages in the persistent database?
+ unregistered-channels: true</code></pre>
+
+<br>
+
+<pre><code># connection information for MySQL (currently only used for persistent history):
+mysql:
+ enabled: false
+ host: "localhost"
+ port: 3306
+ # if socket-path is set, it will be used instead of host:port
+ #socket-path: "/var/run/mysqld/mysqld.sock"
+ user: "ergo"
+ password: "hunter2"
+ history-database: "ergo_history"
+ timeout: 3s
+ max-conns: 4
+ # this may be necessary to prevent middleware from closing your connections:
+ #conn-max-lifetime: 180s</code></pre>
+
+ <p>
+ For privacy reasons, you may want to allow users to delete their own messages in history, or export their messages to JSON:
+ </p>
+
+<pre><code># options to control how messages are stored and deleted:
+retention:
+ # allow users to delete their own messages from history?
+ allow-individual-delete: true
+
+ # if persistent history is enabled, create additional index tables,
+ # allowing deletion of JSON export of an account's messages. this
+ # may be needed for compliance with data privacy regulations.
+ enable-account-indexing: true</code></pre>
+
+ <h3 id="configuring-spam">Spam reduction</h3>
+ <p>
+ Most IRC networks have measures in place to reduce chat spam. By default, "fakelag" is enabled in Ergo, and that can deal with most aggregious chat spam.<br>
+ If you are running a private network where user trust is high, you can disable it so that there are no limits on the speed that messages can be sent.
+ </p>
+
+<pre><code># fakelag: prevents clients from spamming commands too rapidly
+fakelag:
+ # whether to enforce fakelag
+ enabled: true
+
+ # time unit for counting command rates
+ window: 1s
+
+ # clients can send this many commands without fakelag being imposed
+ burst-limit: 5
+
+ # once clients have exceeded their burst allowance, they can send only
+ # this many commands per `window`:
+ messages-per-window: 2
+
+ # client status resets to the default state if they go this long without
+ # sending any commands:
+ cooldown: 2s</code></pre>
+
+ <h2 id="using">Starting and using your server</h3>
+ <p>
+ Now that Ergo is both installed and configured, you can actually start using it!
+ </p>
+
+ <h3 id="using-starting">Starting the server</h3>
+ <p>
+ First thing, make sure you're still using the <code>ergo</code> user, and are in the <code>~/server</code> directory.<br>
+ If you aren't, you can run the following to get back there:
+ </p>
+
+<pre><code>sudo -i -u ergo
+cd server</code></pre>
+
+ <p>
+ Starting the server is done in one command:
+ </p>
+
+ <pre><code>./ergo run</code></pre>
+
+ <p>
+ It will stay online until you close the terminal, or press CTRL+C. Don't worry, the next section goes over how to make it run like a normal server with a SystemD service.<br>
+ If you have not already, make sure the port <code>6697</code> is not blocked on your server. If you are using UFW as your firewall,
+ you need to run <code>ufw enable 6697</code> (not as the <code>ergo</code> user, of course).<br>
+ If you make and configuration changes while the server is running, you can apply them without restarting by typing <code>/rehash</code> as an operator.
+ </p>
+
+ <h3 id="using-connecting">Connecting to the server</h3>
+ <p>
+ To use IRC, you of course need an IRC client. There are many choices available, but the most widely used for Windows and Linux is <a href="https://hexchat.github.io/">HexChat</a>.
+ On Mac, you have a slightly nicer option with <a href="https://www.codeux.com/textual/">Textual</a>, although you have to <a href="https://github.com/Codeux-Software/Textual/#building-textual">compile it from source</a> if you want to use it for free.<br>
+ A more user-friendly and modern client choice is TheLounge, which is explained in the last section of this guide, if you want to look into it.
+ </p>
+
+ <p>
+ Connecting with HexChat is very easy. When you start it, you will see something like this:
+ </p>
+
+ <img src="pix/irc/hexchat-network-select.png" alt="HexChat network select">
+
+ <p>
+ From there, you should click <code>+ Add</code> and name the server whatever you like (so you can find it on the server list).<br>
+ Once you have created a new server and named it, select it and click <code>Edit...</code>.
+ A menu will show up like the one below. Change the domain to whatever domain your server is running on,
+ and make sure to put in your server password if you set one.
+ </p>
+
+ <img src="pix/irc/hexchat-network-edit.png" alt="HexChat network edit menu">
+
+ <p>
+ Once you're done editing the network, click <code>(X) Close</code>, select your network from the network list, and click <code>Connect</code>.<br>
+ If all is well, you should be connected!
+ </p>
+
+ <img src="pix/irc/hexchat-connection-complete.png" alt="HexChat connection complete">
+
+ <p>
+ The process is very similar on Textual.<br>
+ Create a new network and connect to it. Note that it will ask if you want to connect even though the certificate is unsigned.
+ This is due to the self-signed certificates generated for the server, and is not a problem or security vulnerability, it is just a little annoying.
+ </p>
+
+ <img src="pix/irc/textual-network-edit.png" alt="Textual network edit menu">
+
+ <h2 id="service">Surviving restarts with a SystemD service</h3>
+ <p>
+ In the beginning of the last section, Ergo was started by simply running <code>./ergo run</code>, but this is only suitable for testing.
+ To have a proper server setup, you need to run it as a service. This can be achieved via a SystemD service.
+ </p>
+
+ <p>
+ Before creating your service file, make sure you are in <code>~/server</code> as the <code>ergo</code> user.<br>
+ Once you have done that, create a file called <code>start.sh</code> with the following content:
+ </p>
+
+<pre><code>#!/bin/bash
+./ergo run</code></pre>
+
+ <p>Save the file, then mark it as executable:</p>
+
+ <pre><code>chmod +x start.sh</code></pre>
+
+ <p>Now, create a file called <code>ergo.service</code> with the following content:</p>
+
+<pre><code>[Unit]
+Description=Ergo IRC server
+After=network.target
+# If you are using MySQL for history storage, comment out the above line
+# and uncomment these two instead (you must independently install and configure
+# MySQL for your system):
+# Wants=mysql.service
+# After=network.target mysql.service
+
+[Service]
+Type=simple
+User=ergo
+WorkingDirectory=/home/ergo/server
+ExecStart=/home/ergo/server/start.sh
+ExecReload=/bin/kill -HUP $MAINPID
+Restart=on-failure
+LimitNOFILE=1048576
+# Uncomment this for a hidden service:
+# PrivateNetwork=true
+
+[Install]
+WantedBy=multi-user.target</code></pre>
+
+ <p>
+ You now have your service file, but it is not installed yet.
+ To install it, switch to your normal user, and execute the following lines to install, enable, and start the SystemD service:
+ </p>
+
+<pre><code>ln -s /home/ergo/server/ergo.service /etc/systemd/system/ergo.service
+systemctl enable ergo
+systemctl start ergo</code></pre>
+
+ <p>Ergo is now installed and running as a service, and will automatically start when the system boots.</p>
+
+ <h2 id="registering">Registering accounts and channels</h2>
+ <p>
+ Account and channel registration were mentioned multiple times in this guide, and are indeed very important parts of the modern IRC ecosystem.
+ You can connect to most IRC networks and talk without creating an account, but you will not be able to reserve your nickname or register channels, so it is important to register an account.
+ </p>
+
+ <h3 id="registering-accounts">Registering an account with NickServ</h3>
+ <p>
+ First, make sure you are connected to your IRC network.
+ Once you are, type <code>/nickserv help</code> to make sure NickServ (the registration system) is working propertly.<br>
+ If all is well, type the following, replacing <code><i>&lt;your password&gt;</i></code> with the password you want to use:
+ </p>
+
+ <pre><code>/nickserv register <i>&lt;your password&gt;</i></code></pre>
+
+ <p>
+ At this point, you are now registered!<br>
+ The final step is to configure authentication with your client.
+ </p>
+
+ <p>In HexChat, all that needs to be done is changing <code>Login method</code> to <code>SASL (username + password)</code>, and entering your NickServ password that you used earlier into the password field:</p>
+
+ <img src="pix/irc/hexchat-sasl.png" alt="HexChat SASL in network edit menu">
+
+ <p>
+ In Textual, open up your network in the menu, and click <code>Identity</code> under <code>Server Properties</code>.
+ Enter your password in <code>Personal Password</code>, and check <code>Wait for identification before joining channels</code>.
+ </p>
+
+ <img src="pix/irc/textual-identity.png" alt="Textual identity menu">
+
+ <p>You will now be logged into your account when you connect to your network.</p>
+
+ <h3 id="registering-channels">Registering channels with ChanServ</h3>
+ <p>
+ Once you have an account registered, you can register channels with ChanServ.<br>
+ To do so, join the channel you want to register, then type the following, replacing <code><i>&lt;your channel&gt;</i></code> with the name of the channel you want to register:
+ </p>
+
+ <pre><code>/chanserv register #<i>&lt;your channel&gt;</i></code></pre>
+
+ <p>
+ You are now the channel owner, and are free to appoint operators, administrators, etc for it.
+ When you go offline, you won't lose ownership, and you cannot be removed as the owner unless you unregister the channel later.
+ </p>
+
+ <h2 id="moderation">Moderation</h2>
+ <p>
+ Like any chat, there will come a point where you need to use moderation tools to keep things under control.
+ Many IRC setup guides do not go over moderation, so it can be stressful when operators need to actually use moderation tools.<br>
+ The main difference between IRC and other chat systems in terms of moderation is the difference between channel bans and network bans.
+ Channel ban keeps a person out of channel a channel, whereas a network ban keeps a person out of the entire network.
+ </p>
+
+ <h3 id="moderation-masks">Understanding masks</h3>
+ <p>
+ Bans are applied "masks", which are formatted pieces of text that contain a user's nick (username), their realname value, and their IP address or host.<br>
+ This is what a mask looks like: <code>nick!~nick-dude@127.0.0.1</code>.<br>
+ In bans, asterisks can be used as wildcards, which is useful for banning IP address ranges, patterns of nicknames, or whatever else you can think of.<br>
+ A ban on the nick <code>person</code>, for example, would look like this: <code>person!*@*</code>.<br>
+ A ban on anyone with the IP address <code>127.0.0.1</code> would look like this: <code>*!*@127.0.0.1</code>
+ </p>
+
+ <h3 id="moderation-real-ips">Discovering real IPs</h3>
+ <p>
+ Even if IP cloaking is enabled on your network, you can still obtain real IP addresses/hosts if you are an operator.
+ See the <b>Operators</b> part of the configuration section of this guide on how to become an operator.<br>
+ To find out a user's real IP, simply type <code>/whois</code> along with the user's nick, and you will see information about the user, along with their real IP address/host.<br>
+ <code>/whois</code> is not a command that is exclusive to operators, but it does not reveal as much information to non-operators.
+ </p>
+
+ <h3 id="moderation-network-ban">Banning someone from the network</h3>
+ <p>
+ Any netword-wide moderation action requires being an operator. See the <b>Operators</b> part of the configuration section of this guide on how to become an operator.<br>
+ Banning someone from the network is achieved with the <code>/kline</code> command. To see more info on the command, type <code>/helpop kline</code>.<br>
+ </p>
+
+ <p>To ban a nick from the network:</p>
+
+ <pre><code>/kline andkill <i>&lt;nick&gt;</i>!*@*</code></pre>
+
+ <p>To ban an IP address or host from the network:</p>
+
+ <pre><code>/kline andkill *!*@<i>&lt;IP or mask&gt;</i></code></pre>
+
+ <p>To unban a mask, you can use the <code>/unkline</code> command with the mask you want to unban.</p>
+
+ <h3 id="moderation-channel-ban">Banning someone from a channel</h3>
+ <p>
+ Channel owners, administrators, and operators can ban people from channels.
+ This is not the same as banning someone from the network, since it only has an effect on one channel.
+ Additionally, a channel operator is not the same as a network operator.
+ </p>
+
+ <p>To ban someone in a channel, type the following in that channel, replacing <code><i>&lt;mask&gt;</i></code> with the user's mask:</p>
+
+ <pre><code>/mode +b <i>&lt;mask&gt;</i></code></pre>
+
+ <p>
+ Note that this will only ban the user, not kick them immediately.
+ You will want to run <code>/kick</code> along with the user's nick to also kick them.<br>
+ To unban a user, run the command above, but replace the <code>+</code> with a <code>-</code>.<br>
+ You can see who is banned in a channel by typing <code>/banlist</code>.
+ </p>
+
+ <h3 id="moderation-muting">Muting people in a channel</h3>
+ <p>
+ By default, anyone can speak in an IRC channel. To change this, you must be a channel owner, administrator, or operator.<br>
+ Channels, along with users, have modes, which modify their behavior. There is a special mode for channels called <code>m</code> (moderated) which requires users to be privileged in some way to talk.<br>
+ To set a channel as moderated, type the following in the channel:
+ </p>
+
+ <pre><code>/mode +m</code></pre>
+
+ <p>
+ Now, users must be an owner, administrator, operator, or be voiced to talk in the channel
+ This be reversed by typing the command above, but changing the <code>+</code> to a <code>-</code>.<br>
+ To voice a user, run the following, replacing <i>&lt;nick&gt;</i> with the user's nick:
+ </p>
+
+ <pre><code>/mode +v <i>&lt;nick&gt;</i></code></pre>
+
+ <p>Unvoice the user by typing the above command, but replacing the <code>+</code> with a <code>-</code>.</p>
+
+ <h3 id="moderation-appointing">Appointing channel administrators and operators</h3>
+ <p>
+ Assuming you a channel owner, you can appoint both administrators and operators.
+ If you are only an operator, you may only appoint operators.<br>
+ The difference between administrator and operator is mainly that administrators cannot have their privileges taken away by operators, only owners.
+ To appoint an administrator, type the following, replacing <i>&lt;nick&gt;</i> with the user's nick:
+ </p>
+
+ <pre><code>/mode +a <i>&lt;nick&gt;</i></code></pre>
+
+ <p>To appoint an operator, type the following, replacing <i>&lt;nick&gt;</i> with the user's nick:</p>
+
+ <pre><code>/mode +o <i>&lt;nick&gt;</i></code></pre>
+
+ <p>
+ You can also use <code>/op</code> and <code>/deop</code> on most clients to appoint and remove an operator.<br>
+ To remove administrator or operator status, run either of the above commands, but replace the <code>+</code> with a <code>-</code>.
+ </p>
+
+ <h2 id="thelounge">Bringing modern-day features to IRC with TheLounge</h3>
+ <p>
+ A large downside to IRC as a protocol is just how old it is, and the limitations that exist because of it.
+ Other old protocols such as HTTP were built to be content-agnostic and versitile, but IRC was built with a very specific set of features, so it has not held up so well to contemporary chat systems.<br>
+ A notable thing that IRC as a protocol is missing is file uploads, and other fancy features that many other chats have.<br>
+ With that said, these problems can be fixed by clients, although many clients are still very primitive.
+ </p>
+
+ <p>
+ <a href="https://thelounge.chat/">TheLounge</a> is a modern self-hosted IRC web client that tries to make IRC as user-friendly as possible.
+ It can be the answer to many of the complaints that normalfriends may have about IRC. It runs on anything with a web browser, can be "installed" since it is a PWA (Progressive Web App),
+ and is optimized for both desktops and mobile devices. It keeps you logged in even when you are gone, and even supports file uploads and embeds.<br>
+ Effectively, it brings IRC up to the standard of most other chat systems.
+ </p>
+
+ <p>
+ If you would like to setup an instance of TheLounge for you and your friends, you can take a look at their <a href="https://thelounge.chat/docs/install-and-upgrade">installation guide</a>.<br>
+ It is a self-hosted web app, so you can run it for multiple people, not just yourself.
+ </p>
+
+ <hr>
+
+ <p><i>Written by <a href="https://termer.net/">Termer</a></i></p>
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/jitsi.html b/jitsi.html
new file mode 100644
index 0000000..0c7d427
--- /dev/null
+++ b/jitsi.html
@@ -0,0 +1,130 @@
+<!-- <!DOCTYPE html> -->
+<html lang="en">
+ <head>
+ <title>Jitsi Video Chat &ndash; LandChad.net</title>
+ <meta charset="utf-8" />
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel="stylesheet" type="text/css" href="style.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <link rel="alternate" type="application/rss+xml" title="Land Chad RSS" href="/rss.xml" />
+ </head>
+ <body>
+ <header><h1>Jitsi Video Chat</h1></header>
+ <nav></nav>
+ <main>
+ <img src="pix/jitsi.svg" alt="Jitsi" class=titleimg>
+ <p>
+ <dfn>Jitsi</dfn> is a set of open-source projects that allows you to easily build and deploy secure video conferencing solutions.
+ </p>
+ <p>
+ Is really easy to install, and also a really good private, federated and libre alternative to Zoom or other video conferencing software.
+ You can create calls just by typing the URL, and loging-in is not necessary.
+ </p>
+
+ <h2>Dependencies and Installation</h2>
+
+ <p>First, install some dependencies:</p>
+
+ <pre><code>apt install gpg apt-transport-https nginx python-certbot-nginx</code></pre>
+
+ <p>Jitsi has its own package repository, so let's add it.</p>
+
+ <pre class=wide><code>curl https://download.jitsi.org/jitsi-key.gpg.key | gpg --dearmor &#62; /usr/share/keyrings/jitsi-keyring.gpg
+echo 'deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/' > /etc/apt/sources.list.d/jitsi-stable.list
+apt update -y</code></pre>
+
+ <p>
+ Ok. So now we can install Jitsi, but before we do that, let's the firewall <code>ufw</code>, in case you
+ have it enabled, and the SSL certificate.
+ </p>
+
+ <h2>Enable Required Ports</h2>
+
+ <p>If you are using <a href="ufw.html">ufw</a> or another firewall, there are several ports we need to ensure are open:</p>
+ <pre><code>ufw allow 80/tcp
+ufw allow 443/tcp
+ufw allow 10000/udp
+ufw allow 3478/udp
+ufw allow 5349/tcp
+ufw enable</code></pre>
+
+ <p>For your information, these allow the following:</p>
+
+ <ul>
+ <li>80 TCP &ndash; Certbot.</li>
+ <li>443 TCP &ndash; General access to Jitsi Meet.</li>
+ <li>10000 UDP &ndash; General network video/audio communications.</li>
+ <li>3478 UDP &ndash; Quering the stun server (coturn, optional, needs config.js change to enable it).</li>
+ <li>
+ 5349 TCP &ndash; Fallback network video/audio communications over TCP (when UDP is blocked for example), served by coturn.
+ </li>
+ </ul>
+
+ <h2>SSL certificate</h2>
+
+ <p>
+ I'll be using <a href="./certbot.html" target="blank">certbot</a> and
+ <a href="./nginx.html" target="blank">Nginx</a> to generate a certificate
+ for the Jitsi subdomain to allow encrypted connections.
+ </p>
+
+ <pre><code>certbot --nginx certonly -d <strong>meet.example.org</strong></code></pre>
+
+ <p>
+ We will not create an Nginx config file for Jitsi because the Jitsi package we will be installing will do that automatically.
+ </p>
+
+ <h2>Installation</h2>
+
+ <p>To begin the installation process, just run:</p>
+ <pre><code>apt install jitsi-meet</code></pre>
+
+ <p>
+ It will ask you for your <code><strong>hostname</strong></code
+ >; there you'll need to input the subdomain you have just added to Nginx, like
+ <code><strong>meet.example.org</strong></code>.
+ </p>
+
+ <p>For the SSL certificate, choose <code>I want to use my own certificate</code>.</p>
+
+ <p>
+ When it ask you for the certification key and cert files, input
+ <code>/etc/letsencrypt/live/<strong>meet.example.org</strong>/privkey.pem</code> and
+ <code>/etc/letsencrypt/live/<strong>meet.example.org</strong>/cert.pem</code> respectively.
+ </p>
+
+ <h2>Using Jitsi</h2>
+
+ <img src="pix/jitsi-01.webp" alt="Jitsi once installed">
+
+ <p>Jitsi can be used in a browser by then just going to <code>meet.example.org</code>.</p>
+
+ <p>Note that there are also Jitsi clients for all major platforms:</p>
+
+ <ul>
+ <li><a href="https://desktop.jitsi.org/Main/Download.html">Desktop</a> (Windows, MacOS, GNU/Linux)</li>
+ <li>Android (<a href="https://f-droid.org/en/packages/org.jitsi.meet/">F-Droid</a> and <a href="https://play.google.com/store/apps/details?id=org.jitsi.meet">Google Play</a>)</li>
+ <li><a href="https://apps.apple.com/us/app/jitsi-meet/id1165103905">iPhone/iOS</a></li>
+ </ul>
+
+ <p>
+ <strong>When using a Jitsti app for the first time, remember to go to the "Settings" menu and change your server name to the Jitsi site you just created.</strong>
+ </p>
+
+ <p>When you create a video chatroom, its address will appear as <code><strong>meet.example.org/yourvideochatname</strong></code> and can be shared as such.</p>
+
+ <h2>More info</h2>
+
+ <p>
+ This article is based on <a href="https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart" target="blank">the original documentation</a>. There you can find more details and configurations.
+ </p>
+
+ <ul>
+ <li>Written by <a href="https://josefabio.com" target="blank">Jose Fabio.</a> Donate Monero: <code class="crypto">484RLdsXQCDGSthNatGApRPTyqcCbM3PkM97axXezEuPZppimXmwWegiF3Et4BHBgjWR7sVXuEUoAeVNpBiVznhoDLqLV7j</code> <a href="https://josefabio.com/figures/monero.jpg" class="crypto" target="blank">[QR]</a></li>
+ <li>Edited and revised by <a href="https://lukesmith.xyz">Luke</a>.</li>
+ </ul>
+ </main>
+
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+ </body>
+</html>
diff --git a/maintenance.html b/maintenance.html
index 264fe68..d3d9cb3 100644
--- a/maintenance.html
+++ b/maintenance.html
@@ -120,6 +120,6 @@ nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx /usr/share/man
<p>
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/matrix.html b/matrix.html
new file mode 100644
index 0000000..27f4993
--- /dev/null
+++ b/matrix.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Matrix Synapse Server &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Matrix Synapse Server</h1></header>
+ <nav></nav>
+ <main>
+ <p>Matrix is easy-to-use, decentralized and encrypted private chat software.
+ Matrix is federated, meaning that with a Matrix account on any server, including your own, you can talk to any other Matrix account on the internet, similar to email.
+ Matrix also allows fully end-to-end encrypted group chats.
+ </p>
+
+ <p><strong>Synapse</strong> is the name of the default Matrix server. It is written in Python.</p>
+
+ <h2>Installation</h2>
+
+ <p>Synapse is not in the Debian package repositories by default, but we can easily add Matrix's repository including it:</p>
+
+<pre><code>apt install -y lsb-release wget apt-transport-https
+wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
+echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" &gt; /etc/apt/sources.list.d/matrix-org.list</code></pre>
+ <p>After we update our packages lists, we will be able to install Synapse with <code>apt</code>.</p>
+
+<pre><code>apt update
+apt install matrix-synapse-py3</code></pre>
+
+<p>When prompted, give your main domain name (not a subdomain). This will be the domain appended to your Matrix address, e.g. <code>@chad:landchad.net</code>.</p>
+
+ <h2>Nginx configuration</h2>
+
+ <p>Create an Nginx configuration file for Matrix, say <code>/etc/nginx/sites-available/matrix</code> and add the content below:
+ </p>
+
+ <pre><code>server {
+ server_name matrix.<strong>example.org</strong> ;
+ listen 80;
+ listen [::]:80;
+ location / {
+ proxy_pass http://localhost:8008;
+ }
+ location ~* ^(\/_matrix|\/_synapse\/client) {
+ proxy_pass http://localhost:8008;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ client_max_body_size <strong>50M</strong> ;
+ }
+ location /.well-known/matrix/server {
+ return 200 '{"m.homeserver": {"base_url": "https://matrix.<strong>example.org</strong>"}}';
+ default_type application/json;
+ add_header Access-Control-Allow-Origin *;
+ }
+}</code></pre>
+
+ <aside>
+ <p>Note the <code>client_max_body_size</code> variable. By default, Nginx caps the size of files it can transfer. We increase that to 50M if needed by Matrix. (Note however that both Matrix and Nginx have seperate settings for this and to raise it to something much larger, you will have to increase the value in both congfiguration files.)
+ </p>
+ </aside>
+
+ <p>Now let's enable the Nginx Matrix site and reload Nginx to make it active.</p>
+
+ <pre><code>ln -s /etc/nginx/sites-available/matrix /etc/nginx/sites-enabled
+systemctl reload nginx</code></pre>
+
+ <h3>Encryption</h3>
+
+ <p>Obviously, we need to encrypt our <code>matrix</code> subdomain as well. Let's do that with certbot:</p>
+
+<pre><code>certbot --nginx -d matrix.<strong>example.org</strong></code></pre>
+
+ <h2>Configuration</h2>
+
+ <p>
+ The configuration file for Matrix is in <code>/etc/matrix-synapse/homeserver.yaml</code>.
+ It is well documented and commented, so you can read about the settings, but let's change the essential ones here.
+ </p>
+
+ <p><strong>This article isn't finished. Deal with basic settings and registering accounts.</strong></p>
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/monero.html b/monero.html
index 5827c85..498a28e 100644
--- a/monero.html
+++ b/monero.html
@@ -30,7 +30,7 @@
If you are a Windows user, note that you will <em>probably</em> get some kind of warning that you are installing something malicious.
This is because many malicious pieces of software include crypto miners in them.
This wallet, obviously, does include one as well, because it has the ability to mine if you want.
- You can disregard these messages and as that official site mentions, you can follow their directions to check the integrity of the download with SHA265.
+ You can disregard these messages and as that official site mentions, you can follow their directions to check the integrity of the download with SHA256.
</p>
</aside>
@@ -96,7 +96,7 @@
Here is the address we use for this site (i.e. not the compromised wallet generated above):
</p>
- <p style=font-size:small>84RXmrsE7ffCe1ADprxLMHRpmyhZuWYScDR4YghE8pFRFSyLtiZFYwD6EPijVzD3aZiEpg57MfHEr1pGJNPXyJgENMnWrSh</p>
+ <p style="font-size:small; word-wrap: break-word; ">84RXmrsE7ffCe1ADprxLMHRpmyhZuWYScDR4YghE8pFRFSyLtiZFYwD6EPijVzD3aZiEpg57MfHEr1pGJNPXyJgENMnWrSh</p>
<img style="max-height:200px" src="pix/xmr.png" alt="monero donation qr">
@@ -106,6 +106,6 @@
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/nextcloud.html b/nextcloud.html
index f0debc1..fbbe605 100644
--- a/nextcloud.html
+++ b/nextcloud.html
@@ -17,8 +17,6 @@
<p><a href="https://nextcloud.com" target="_blank"><img src="pix/nextcloud.svg" alt="logo">Nextcloud</a> is a free and open source solution for cloud storage. However it can also do other things, such as manage your email, notes, calender, tasks, and can even connect to the Fediverse (think Mastodon and Pleroma). Pretty much every service that Google has to offer has a much better alternative as a Nextcloud app and this is a must-have for anyone wanting to get away from Google services but still wants a traditional cloud experience (in the likes of Google Services, anyways).</p>
<h2 id="instructions">Instructions</h2>
- <p>First, we need to obtain a shell prompt by ssh-ing (remote machines or local machines) or just logging in (local machines). A traditional ssh might look like this if the domain you wished to ssh into is <code>landchad.net</code>:</p>
- <pre><code>ssh root@landchad.net</code></pre>
<p>We should upgrade the system and then install packages that we might need. Run the following command:</p>
<pre><code>apt-get full-upgrade -y && sudo apt-get install mariadb-server php-mysql php php-gd php-mbstring php-dom php-curl php-zip php-simplexml php-xml php-fpm -y</code></pre>
<p>Next, we need to set up our SQL database by running a Secure Installation and creating the tables that will store data that Nextcloud will need. Run the following command:</p>
@@ -40,26 +38,27 @@ EXIT;</code></pre>
<p>Now we need to configure PHP. Let's start my making sure that the PHP user is set to <code>www-data</code> and if that is not the case, add the <code>www-data</code> user if needed and set the correct variable in <code>nginx.conf</code>. Make sure this line is at the beginning of <code>/etc/nginx/nginx.conf</code>.</p>
<pre><code>user www-data;</code></pre>
<p>Check for the <code>www-data</code> user by running <code>id -u www-data</code>. If a number is output from that command, then the www-data user exists. If not. add the user simply by running <code>useradd www-data</code></p>
- <p>Next, we need to ensure that we have SSL certificates generated for your website. If you have not already done this, refer to <a href="certbot.html">this guide</a>. Although having SSL for your site is not required, it is highly recommended that you have it or you will risk attackers being able to steal passwords and data.</p>
+ <p>Next, we need to ensure that we have SSL certificates generated for your website. If you have not already done this, refer to <a href="certbot.html">this guide</a>.</p>
<p>In <code>/etc/nginx/sites-available/</code> we need to make a new configuration for Nextcloud (example: <code>/etc/nginx/sites-available/nextcloud</code>). Create it and open it, modify, and add the following lines:</p>
- <pre><code>server {
+ <pre class=wide><code>upstream php-handler {
+ server unix:/var/run/php/php<strong>7.4</strong>-fpm.sock;
+ server 127.0.0.1:9000;
+}
+
+server {
listen 80;
listen [::]:80;
- server_name <strong>yourwebsite.com</strong>;
+ server_name <strong>example.org</strong>;
- location /nextcloud {
- return 301 https://$server_name$request_uri;
- }
+ return 301 https://$server_name$request_uri;
}
server {
-
- <strong># If you have SSL ready for your website (DO NOT use Nextcloud without HTTPS, you will risk data leaks including passwords and files), use these lines:</strong>
listen 443 ssl http2;
listen [::]:443 ssl http2;
- server_name <strong>yourwebsite.com</strong>;
- ssl_certificate /etc/ssl/nginx/<strong>yourwebsite.com</strong>.crt;
- ssl_certificate_key /etc/ssl/nginx/<strong>yourwebsite.com</strong>.key;
+ server_name <strong>example.org</strong>;
+ ssl_certificate /etc/letsencrypt/live/<strong>example.org</strong>/cert.pem ;
+ ssl_certificate_key /etc/letsencrypt/live/<strong>example.org</strong>/privkey.pem ;
root /var/www;
@@ -90,8 +89,6 @@ server {
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
- pagespeed off;
-
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
@@ -140,7 +137,7 @@ server {
location ~ \.woff2?$ {
try_files $uri /nextcloud/index.php$request_uri;
- expires 7d;
+ expires 7d;
access_log off;
}
@@ -155,7 +152,7 @@ server {
}</code></pre>
<p>Enable the site by running this command:</p>
<pre><code>ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/</code></pre>
- <p>Next, we need to download the latest release tarball of Nextcloud. Go to <a>https://nextcloud.com/install/#instructions-server</a> and copy the URL of the the .tar.bz2 tarball from the More Downloads dropdown menu then go to your server's shell prompt and download the tarball with wget. Here is an example:</p>
+ <p>Next, we need to download the latest release tarball of Nextcloud. Go to <a>https://nextcloud.com/install/#instructions-server</a> and copy the URL of the .tar.bz2 tarball from the More Downloads dropdown menu then go to your server's shell prompt and download the tarball with wget. Here is an example:</p>
<pre><code>wget https://download.nextcloud.com/server/releases/nextcloud-21.0.2.tar.bz2</code></pre>
<p>Now we need to extract the Nextcloud tarball. Run the following command:</p>
<pre><code>tar -xjf nextcloud*.tar.bz2 -C /var/www</code></pre>
@@ -165,22 +162,22 @@ server {
chmod -R 755 /var/www/nextcloud</code>
</pre>
<p>Start and enable the php-fpm and the mariadb services (the name of the php-fpm service may have a version number ahead of it, use bash's tab autocomplete to help you out with that):</p>
- <pre><code>systemctl enable php-fpm
-systemctl start php-fpm
+ <pre><code>systemctl enable php<strong>7.4</strong>-fpm
+systemctl start php<strong>7.4</strong>-fpm
systemctl enable mariadb
systemctl start mariadb</code></pre>
<p>Reload the nginx service:</p>
<pre><code>systemctl reload nginx</code></pre>
- <p>Now we need to head to Nextcloud's web interface. Go to your web browser and go to your website, but go to the subdirectory "nextcloud" instead. For example, if your domain is landchad.net and you have set up HTTPS then go to <code>https://landchad.net/nextcloud</code>. This will launch the configuration wizard.</p>
+ <p>Now we need to head to Nextcloud's web interface. Go to your web browser and go to your website, but go to the subdirectory "nextcloud" instead. Go to <code>https://<strong>example.org</strong>/nextcloud</code>. This will launch the configuration wizard.</p>
<ul>
- <li>Choose an admin username and secure password.
- <li>Leave Data folder at the default value unless it is incorrect.
- <li>For Database user, enter the user you set for the SQL database.
- <li>For Database password, enter the password you chose for the new user in MariaDB.
- <li>For Database name, enter: nextcloud
- <li>Leave "localhost" as "localhost".
- <li>Click Finish
+ <li>Choose an admin username and secure password.</li>
+ <li>Leave Data folder at the default value unless it is incorrect.</li>
+ <li>For Database user, enter the user you set for the SQL database.</li>
+ <li>For Database password, enter the password you chose for the new user in MariaDB.</li>
+ <li>For Database name, enter: <code>nextcloud</code></li>
+ <li>Leave "localhost" as "localhost".</li>
+ <li>Click Finish.</li>
</ul>
<p>Congratulations, you have set up your own Nextcloud instance.</p>
@@ -189,13 +186,13 @@ systemctl start mariadb</code></pre>
<p>Now you may be wondering: What do I do now? Here are some suggestions:</p>
<ul>
- <li>Rice your Nextcloud instance by changing your themeing and installing new themes and plugins in Settings in the Nextcloud Web Interface.
- <li>Install the Nextcloud Client on your personal computer and sync your files to your instance.
- <li>Install the Nextcloud App on your mobile device and sync your files to your instance.
- <li>Set up your email account on the Nextcloud Mail app on the web interface to view and sync your email there (just like Gmail).
- <li>Schedule events with Nextcloud Calender.
- <li>Write notes in Markdown inside the Nextcloud Notes web and mobile app.
- <li>Set the Nextcloud Dashboard as your web browser's homepage (it is pretty nice).
+ <li>Rice your Nextcloud instance by changing your themeing and installing new themes and plugins in Settings in the Nextcloud Web Interface.</li>
+ <li>Install the Nextcloud Client on your personal computer and sync your files to your instance.</li>
+ <li>Install the Nextcloud App on your mobile device and sync your files to your instance.</li>
+ <li>Set up your email account on the Nextcloud Mail app on the web interface to view and sync your email there (just like Gmail).</li>
+ <li>Schedule events with Nextcloud Calender.</li>
+ <li>Write notes in Markdown inside the Nextcloud Notes web and mobile app.</li>
+ <li>Set the Nextcloud Dashboard as your web browser's homepage (it is pretty nice).</li>
</ul>
<p>Enjoy your cloud services in freedom.</p>
@@ -204,9 +201,7 @@ systemctl start mariadb</code></pre>
<p><em>Written by <a href="https://github.com/MattMadness">Matthew "Madness" Evan</a></em></p>
- <!--<span class=next><a href="<++>">Next:<++></a></span>--!>
-
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/nginx.html b/nginx.html
index 1b269db..067b5d9 100644
--- a/nginx.html
+++ b/nginx.html
@@ -16,7 +16,7 @@
As I said in previous articles, the instructions I will give will be for <strong>Debian 10</strong>.
In this article, other distributions might work a little differently.</p>
- <h2>Logging in the the server</h2>
+ <h2>Logging in to the server</h2>
<p>
We first want to log into our VPS to get a command prompt where we can set up the web server.
@@ -33,7 +33,7 @@
Now pull up a terminal and type:
</p>
- <pre><code>ssh root@<strong>yourdomain.com</strong></code></pre>
+ <pre><code>ssh root@<strong>example.org</strong></code></pre>
<p>
This command will attempt to log into your server.
@@ -44,7 +44,7 @@
<p>
If you get an error here, you might not have done your <a href="dns.html">DNS settings</a> right.
Double check those.
- Note you can also replace the <code>yourdomain.com</code> with your IP address, but you'll want to fix your DNS settings soon.
+ Note you can also replace the <code>example.org</code> with your IP address, but you'll want to fix your DNS settings soon.
</p>
</aside>
@@ -186,11 +186,11 @@ Now we can just <code>reload</code> or <code>restart</code> to make <code>nginx<
<pre><code>systemctl reload nginx</code></pre>
-<h2>The Firewall</h2>
+<h2 id=firewall>The Firewall</h2>
<p>
Vultr and some other VPS automatically install and enable <code>ufw</code>, a firewall program.
-This will block bacsically everything by default, so we have to change that.
+This will block basically everything by default, so we have to change that.
If you don't have <code>ufw</code> installed, you can skip this section.
</p>
@@ -230,9 +230,10 @@ Note the "Not secure" notification.
The next brief step is securing encrypted connections to your website.
</p>
-<span class=next><a href="certbot.html">Next: Enabling Encrypted Connections</a></span>
+ <span class=prev><a href="dns.html">Previous: Set up DNS.</a></span>
+ <span class=next><a href="certbot.html">Next: Enabling Encrypted Connections.</a></span>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/openalias.html b/openalias.html
index 2856560..dd11629 100644
--- a/openalias.html
+++ b/openalias.html
@@ -20,7 +20,7 @@
</p>
<ul>
- <li>84RXmrsE7ffCe1ADprxLMHRpmyhZuWYScDR4YghE8pFRFSyLtiZFYwD6EPijVzD3aZiEpg57MfHEr1pGJNPXyJgENMnWrSh</li>
+ <li><code class=crypto>84RXmrsE7ffCe1ADprxLMHRpmyhZuWYScDR4YghE8pFRFSyLtiZFYwD6EPijVzD3aZiEpg57MfHEr1pGJNPXyJgENMnWrSh</code></p>
</ul>
<p>
@@ -32,7 +32,7 @@
<p>
It would be nice if we could just input someone's email address or maybe a website and send Bitcoin or Monero to that instead.
- So instead of that long jumble, it would be eaiser to just type in someone's website or email and sending them money that way.
+ So instead of that long jumble, it would be easier to just type in someone's website or email and sending them money that way.
</p>
<h2>The Solution</h2>
@@ -67,7 +67,7 @@
Note here that I have create two entries:
</p>
- <img src="pix/openalias-01.png" alt="openalias">
+ <a href=pix/openalias-01.png><img src="pix/openalias-01.png" alt="openalias"></a>
<p>
One entry's "Host" is left empty, this will allow people to send Monero by merely typing <code>landchad.net</code>.
@@ -83,13 +83,13 @@
Let's check to see if it works.
In the Monero wallet, we can now type in <code>landchad.net</code> as a recipient:
</p>
- <img src="pix/openalias-02.png" alt="checking">
+ <a href=pix/openalias-02.png><img src="pix/openalias-02.png" alt="checking"></a>
<p>
And once we press the "Resolve" button, it automatically turns into that address we gave to the DNS!
</p>
- <img src="pix/openalias-03.png" alt="It works!">
+ <a href=pix/openalias-03.png><img src="pix/openalias-03.png" alt="It works!"></a>
<p>
Now people can donate Monero to you without having to worry about QR codes or copying-and-pasting super-long public addresses!
@@ -106,18 +106,18 @@
<p>Add the TXT entries in and save:</p>
- <img src="pix/openalias-04.png" alt="bitcoin openalias entries">
+ <a href=pix/openalias-04.png><img src="pix/openalias-04.png" alt="bitcoin openalias entries"></a>
<p>And we can then check that it's working by trying to send money to <code>landchad.net</code> in Electrum.
See that it automatically appends the address!
</p>
- <img src="pix/openalias-05.png" alt="electrum resolves an openalias">
+ <a href=pix/openalias-05.png><img src="pix/openalias-05.png" alt="electrum resolves an openalias"></a>
<p>
And that's it. Now users can easily send your website or email address Bitcoin or Monero without having to worry about hard to read addresses and QR codes.
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/peertube.html b/peertube.html
new file mode 100644
index 0000000..7939636
--- /dev/null
+++ b/peertube.html
@@ -0,0 +1,223 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>PeerTube Instance &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>PeerTube Instance</h1></header>
+ <nav></nav>
+ <main>
+
+ <img class=titleimg src="pix/peertube.svg" alt="PeerTube logo">
+
+ <p>PeerTube is a self-hosted and (optionally) federated video sharing platform that saves bandwith on videos the more people watch.
+ PeerTube instances can follow each other to share videos and grow the federated network,
+ but you can always keep your instance to yourself if you choose to.</p>
+
+ <h2>Note on Bandwidth</h2>
+
+ <p>
+ Video sharing is the most bandwidth intensive thing on the internet!
+ If you plan on just having a small personal site with a few viewers and friends, that won't be a big concern,
+ but most VPS providers like Vultr have caps on how much bandwidth can be used within a month without being throttled.
+ This level is far beyond what most sites need, but it might be an issue with a video site!
+ </p>
+
+ <p>
+ So if you plan on having a big video-sharing PeerTube site, it's a good idea to host it with a provider that offers infinite bandwidth.
+ I strongly recommend getting a separate VPS with <a href="https://my.frantech.ca/aff.php?aff=3886">Frantech/BuyVM</a>.
+ They have unmetered bandwidth, extremely cheap block storage for hosting many, many videos and they even have a good record of being censorship resistant.
+ </p>
+
+ <h2>Prerequisites</h2>
+
+ <p><strong>Most</strong> of PeerTube's dependencies can be installed with this command:</p>
+
+ <pre><code>apt install -y curl sudo unzip vim ffmpeg postgresql postgresql-contrib g++ make redis-server git python-dev cron wget</code></pre>
+
+ <p>It's also important to start all associated daemons:</p>
+
+ <pre><code>systemctl start postgresql redis</code></pre>
+
+ <p>PeerTube also requires <strong>NodeJS 14</strong> and <strong>yarn</strong> which cannot be installed from the Debian repositories. This means they have to be installed from separate, external repos:</p>
+
+ <pre><code>curl -fsSL https://deb.nodesource.com/setup_14.x | bash -
+apt install -y nodejs
+npm install --global yarn</code></pre>
+
+ <p>Now we create a PeerTube user to run and handle PeerTube with the proper permissions:</p>
+
+ <pre><code>useradd -m -d /var/www/peertube -s /bin/bash -p peertube peertube</code></pre>
+
+ <h2>Database</h2>
+
+ <p>PeerTube requires a PostgreSQL database to function. To create it, first make a new Postgres user named PeerTube:</p>
+
+ <pre><code>su -l postgres
+createuser -P peertube
+createdb -O peertube -E UTF8 -T template0 peertube_prod
+psql -c "CREATE EXTENSION pg_trgm;" peertube_prod
+psql -c "CREATE EXTENSION unaccent;" peertube_prod
+exit</code></pre>
+
+ <p>Be sure to <strong>make note of your Postgres user password,</strong> as it will be needed later when setting up PeerTube.</p>
+
+ <h2>Installation</h2>
+
+ <p>Using <code>su -l</code>, we will become the PeerTube user to create the required directories and download and install PeerTube itself with the proper permissions.
+ First, we create the required directories.</p>
+
+ <pre><code>su -l peertube
+mkdir config storage versions
+chmod 750 config</code></pre>
+
+ <h3>Downloading PeerTube</h3>
+ <p>Still as the PeerTube user, we can now check for the most recent PeerTube versions number, download and install it in the newly created <code>versiond</code> directory.</p>
+ <pre class=wide><code>VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4)
+cd /var/www/peertube/versions
+wget "https://github.com/Chocobozzz/PeerTube/releases/download/${VERSION}/peertube-${VERSION}.zip"
+unzip peertube-${VERSION}.zip
+rm peertube-${VERSION}.zip</code></pre>
+
+ <h3>Installation via Yarn</h3>
+
+<p>The downloaded release can then be symbolically linked to <code>/var/www/peertube/peertube-latest</code> and <strong>yarn</strong> is used to install PeerTube:</p>
+
+<pre><code>cd /var/www/peertube
+ln -s versions/peertube-${VERSION} ./peertube-latest
+cd ./peertube-latest
+yarn install --production --pure-lockfile</code></pre>
+
+ <h2>Configuration</h2>
+
+ <p>PeerTube's default config file can be copied over to <code>/var/www/peertube/config/production.yaml</code> so it can actually be used:</p>
+
+ <p>Note that we are still running these as the PeerTube user (having run <code>su -l peertube</code>).</p>
+
+ <pre><code>cd /var/www/peertube
+cp peertube-latest/config/production.yaml.example config/production.yaml</code></pre>
+
+ <p>Now the <code>production.yaml</code> file must be edited in the following ways:</p>
+
+ <p>First, add the hostname:</p>
+
+ <pre><code>webserver:
+ https: true
+ hostname: <strong>'example.org'</strong>
+ port: 443</code></pre>
+
+ <p>Then, the database:</p>
+
+ <pre><code>database:
+ hostname: 'localhost'
+ port: 5432
+ ssl: false
+ suffix: '_prod'
+ username: <strong>'peertube'</strong>
+ password: <strong>'your_password'</strong>
+ pool:
+ max: 5</code></pre>
+
+ <p>An email to generate the admin user:</p>
+
+ <pre><code>admin:
+ # Used to generate the root user at first startup
+ # And to receive emails from the contact form
+ email: <strong>'chad@example.org'</strong></code></pre>
+
+ <p>And <strong>optionally,</strong> email server information:</p>
+
+ <pre><code>smtp:
+ # smtp or sendmail
+ transport: smtp
+ # Path to sendmail command. Required if you use sendmail transport
+ sendmail: null
+ hostname: <strong>mail.example.org</strong>
+ port: 465 # If you use StartTLS: 587
+ username: <strong>your_email_username</strong>
+ password: <strong>your_email_password</strong>
+ tls: true # If you use StartTLS: false
+ disable_starttls: false
+ ca_file: null # Used for self signed certificates
+ from_address: <strong>'admin@example.org'</strong></code></pre>
+
+ <p>At this point, we have done all we need to do as the PeerTube user. Run <code>exit</code> or press <code>Ctrl-d</code> to log out and return to the root prompt where we will configure Nginx and other system settings.</p>
+
+ <h2>Certbot</h2>
+
+ <p>First, we will want a Certbot SSL certificate to encrypt connections to our PeerTube instance.
+ Just run the following:</p>
+
+ <pre><code>certbot --nginx -d <strong>peertube.example.org</strong> certonly</code></pre>
+
+ <h2>Nginx</h2>
+
+ <p>PeerTube includes an Nginx configuration that can be copied over to <code>/etc/nginx/sites-available:</code>
+
+ <pre><code>cp /var/www/peertube/peertube-latest/support/nginx/peertube /etc/nginx/sites-available/peertube</code></pre>
+
+ <p>Because the PeerTube config is so long, it's recommended to use <code>sed</code> to modify the contents of the file,
+ replacing <code>${WEBSERVER_HOST}</code> with your hostname,
+ and <code>$(PEERTUBE_HOST)</code> with your localhost and port, which by default should be <code>127.0.0.1:9000</code>:
+
+ <pre><code>sed -i 's/${WEBSERVER_HOST}/<strong>example.org</strong>/g' /etc/nginx/sites-available/peertube
+sed -i 's/${PEERTUBE_HOST}/127.0.0.1:9000/g' /etc/nginx/sites-available/peertube</code></pre>
+
+ <p>Once you're happy with the Nginx config file, link it to <code>sites-enabled</code> to activate it:</p>
+
+ <pre><code>ln -s /etc/nginx/sites-available/peertube /etc/nginx/sites-enabled/peertube</code></pre>
+
+ <h2>Running PeerTube</h2>
+
+ <p>A config file for a systemd daemon is included in PeerTube and can be setup and started like so:</p>
+
+ <pre><code>cp /var/www/peertube/peertube-latest/support/systemd/peertube.service /etc/systemd/system/
+systemctl daemon-reload
+systemctl start peertube</pre></code>
+
+ <p>
+ PeerTube will take a momemnt to start, but after it does, you can check its status with <code>systemctl status peertube</code> and at this point, your PeerTube site should be live!
+ </p>
+
+ <h2>Using PeerTube</h2>
+
+ <p>To set a password for your admin user, run:</p>
+
+ <pre><code>cd /var/www/peertube/peertube-latest
+NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run reset-password -- -u root</code></pre>
+
+ <p>Login to your PeerTube instance using the admin email specified in your <code>production.yaml</code> file and the admin password you just set.</p>
+
+ <img src="pix/peertube-login.jpg" height=400px>
+
+ <p>Once logged in, it's recommended to create a separate user without admin privileges for uploading videos to PeerTube.
+ This can be done easily from the users tab in the administration section.</p>
+
+ <p>Enjoy your PeerTube instance!</p>
+
+ <hr>
+
+ <h2>Updating PeerTube</h2>
+
+ <p>PeerTube is constantly adding new features, so it's a good idea to <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md">check for new updates</a> and add them if you wish. Just in the past year, they have added livestreaming and more.</p>
+
+ <p>Updating is fairly easy now since an <code>upgrade.sh</code> script has been added. Just run:</p>
+
+ <pre><code>cd /var/www/peertube/peertube-latest/scripts &amp;&amp; sudo -H -u peertube ./upgrade.sh</code></pre>
+
+ <p>
+ Although check the <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md">changelog</a> to see if there are additional manual requirements for particular updates.
+ </p>
+
+ <hr>
+ <p><em>Written by <a href="https://denshi.live">Denshi.</a> Donate Monero <a href="https://denshi.live/donate.html">here</a> <a href="https://denshi.live/images/monero.png">[QR]</a></em></p>
+
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/pix/calibre.png b/pix/calibre.png
new file mode 100644
index 0000000..81adc85
--- /dev/null
+++ b/pix/calibre.png
Binary files differ
diff --git a/pix/calibre/calibre-1.png b/pix/calibre/calibre-1.png
new file mode 100644
index 0000000..cf767e0
--- /dev/null
+++ b/pix/calibre/calibre-1.png
Binary files differ
diff --git a/pix/calibre/calibre-2.png b/pix/calibre/calibre-2.png
new file mode 100644
index 0000000..e0c76ba
--- /dev/null
+++ b/pix/calibre/calibre-2.png
Binary files differ
diff --git a/pix/gitea-push-create.png b/pix/gitea-push-create.png
new file mode 100644
index 0000000..ca79c71
--- /dev/null
+++ b/pix/gitea-push-create.png
Binary files differ
diff --git a/pix/gitea.svg b/pix/gitea.svg
new file mode 100644
index 0000000..9df6b83
--- /dev/null
+++ b/pix/gitea.svg
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.1" id="main_outline" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+ y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve">
+<g>
+ <path id="teabag" style="fill:#FFFFFF" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8
+ c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4
+ c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/>
+ <g>
+ <g>
+ <path style="fill:#609926" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2
+ c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5
+ c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5
+ c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3
+ c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1
+ C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4
+ c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7
+ S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55
+ c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8
+ l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/>
+ <path style="fill:#609926" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4
+ c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1
+ c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9
+ c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3
+ c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3
+ c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29
+ c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8
+ C343.2,346.5,335,363.3,326.8,380.1z"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/pix/irc.svg b/pix/irc.svg
new file mode 100644
index 0000000..0f48379
--- /dev/null
+++ b/pix/irc.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Inkscape (http://www.inkscape.org/) --><svg height="60.0000000" id="svg1" inkscape:version="0.38.1" sodipodi:docbase="/home/danny/flat/scalable/apps" sodipodi:docname="irc_protocol.svg" sodipodi:version="0.32" version="1.0" width="60.0000000" x="0" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" y="0">
+ <metadata>
+ <rdf:RDF xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <cc:Work rdf:about="">
+ <dc:title>Part of the Flat Icon Collection (Wed Aug 25 23:23:49 2004)</dc:title>
+ <dc:description></dc:description>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>hash</rdf:li>
+ <rdf:li></rdf:li>
+ <rdf:li>application</rdf:li>
+ <rdf:li>computer</rdf:li>
+ <rdf:li>icons</rdf:li>
+ <rdf:li>theme</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent rdf:about="http://www.openclipart.org">
+ <dc:title>Danny Allen</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Danny Allen</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>Danny Allen</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:date></dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <cc:license rdf:resource="http://web.resource.org/cc/PublicDomain"/>
+ <dc:language>en</dc:language>
+ </cc:Work>
+ <cc:License rdf:about="http://web.resource.org/cc/PublicDomain">
+ <cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
+ <cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview bordercolor="#ffffff" borderopacity="1.0" id="base" inkscape:cx="37.697545" inkscape:cy="22.126475" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="685" inkscape:window-width="1016" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="6.9465337" pagecolor="#ffffff" showguides="true" snaptoguides="true"/>
+ <defs id="defs3">
+ <linearGradient id="linearGradient772">
+ <stop id="stop773" offset="0" style="stop-color:#fff;stop-opacity:1;"/>
+ <stop id="stop774" offset="1" style="stop-color:#fff;stop-opacity:1;"/>
+ </linearGradient>
+ <linearGradient id="linearGradient775" xlink:href="#linearGradient772"/>
+ </defs>
+ <path d="M 11.934141,39.676628 C 11.934141,39.055534 12.066954,38.483269 12.332579,37.959831 C 12.598204,37.432487 12.969298,37.018425 13.445860,36.717644 C 13.926329,36.416862 14.473204,36.266472 15.086485,36.266472 C 15.410704,36.266472 15.744688,36.305534 16.088438,36.383659 C 16.432188,36.457878 16.721251,36.586784 16.955626,36.770378 C 17.190001,36.953972 17.307188,37.202019 17.307188,37.514519 C 17.307188,37.764519 17.232970,37.973503 17.084532,38.141472 C 16.940001,38.309441 16.758360,38.393425 16.539610,38.393425 C 16.434141,38.393425 16.330626,38.375847 16.229063,38.340691 C 16.131407,38.305534 16.031798,38.268425 15.930235,38.229362 C 15.832579,38.186394 15.727110,38.151237 15.613829,38.123894 C 15.504454,38.096550 15.365782,38.082878 15.197813,38.082878 C 14.893126,38.082878 14.635313,38.155144 14.424376,38.299675 C 14.217345,38.440300 14.061095,38.631706 13.955626,38.873894 C 13.854063,39.112175 13.803282,39.379753 13.803282,39.676628 C 13.803282,39.965691 13.854063,40.235222 13.955626,40.485222 C 14.057188,40.731316 14.203673,40.926628 14.395079,41.071159 C 14.590391,41.215691 14.820860,41.287956 15.086485,41.287956 C 15.387266,41.287956 15.690001,41.231316 15.994688,41.118034 C 16.299376,41.004753 16.481016,40.948112 16.539610,40.948112 C 16.680235,40.948112 16.809141,40.989128 16.926329,41.071159 C 17.043516,41.153191 17.135313,41.260612 17.201720,41.393425 C 17.272032,41.522331 17.307188,41.655144 17.307188,41.791862 C 17.307188,42.080925 17.180235,42.325066 16.926329,42.524284 C 16.676329,42.723503 16.377501,42.868034 16.029845,42.957878 C 15.682188,43.051628 15.367735,43.098503 15.086485,43.098503 C 14.621641,43.098503 14.195860,43.012566 13.809141,42.840691 C 13.426329,42.668816 13.092345,42.424675 12.807188,42.108269 C 12.522032,41.787956 12.305235,41.420769 12.156798,41.006706 C 12.008360,40.588737 11.934141,40.145378 11.934141,39.676628 z M 7.9614851,41.991081 L 7.9614851,37.362175 C 7.9614851,37.084831 8.0474226,36.854362 8.2192976,36.670769 C 8.3950789,36.483269 8.6196883,36.389519 8.8931258,36.389519 C 9.1196883,36.389519 9.3150008,36.450066 9.4790633,36.571159 C 9.6470320,36.688347 9.7642195,36.827019 9.8306258,36.987175 C 10.232970,36.506706 10.664610,36.266472 11.125548,36.266472 C 11.379454,36.266472 11.602110,36.358269 11.793516,36.541862 C 11.988829,36.721550 12.086485,36.953972 12.086485,37.239128 C 12.086485,37.532097 11.994688,37.744987 11.811095,37.877800 C 11.631407,38.010612 11.332579,38.137566 10.914610,38.258659 C 10.488829,38.379753 10.201720,38.532097 10.053282,38.715691 C 9.9048445,38.895378 9.8306258,39.219597 9.8306258,39.688347 L 9.8306258,41.991081 C 9.8306258,42.268425 9.7427351,42.502800 9.5669539,42.694206 C 9.3950789,42.881706 9.1704695,42.975456 8.8931258,42.975456 C 8.6196883,42.975456 8.3950789,42.881706 8.2192976,42.694206 C 8.0474226,42.502800 7.9614851,42.268425 7.9614851,41.991081 z M 5.2603133,41.991081 L 5.2603133,37.362175 C 5.2603133,37.084831 5.3462508,36.854362 5.5181258,36.670769 C 5.6939070,36.483269 5.9185164,36.389519 6.1919539,36.389519 C 6.4692976,36.389519 6.6939070,36.483269 6.8657820,36.670769 C 7.0415633,36.854362 7.1294539,37.084831 7.1294539,37.362175 L 7.1294539,41.991081 C 7.1294539,42.268425 7.0415633,42.502800 6.8657820,42.694206 C 6.6939070,42.881706 6.4692976,42.975456 6.1919539,42.975456 C 5.9185164,42.975456 5.6939070,42.881706 5.5181258,42.694206 C 5.3462508,42.502800 5.2603133,42.268425 5.2603133,41.991081 z M 5.0786726,34.696159 C 5.0786726,34.391472 5.1880476,34.127800 5.4067976,33.905144 C 5.6255476,33.682487 5.8872664,33.571159 6.1919539,33.571159 C 6.5005476,33.571159 6.7642195,33.680534 6.9829695,33.899284 C 7.2017195,34.118034 7.3110945,34.383659 7.3110945,34.696159 C 7.3110945,35.020378 7.2017195,35.289909 6.9829695,35.504753 C 6.7642195,35.719597 6.5005476,35.827019 6.1919539,35.827019 C 5.8872664,35.827019 5.6255476,35.717644 5.4067976,35.498894 C 5.1880476,35.280144 5.0786726,35.012566 5.0786726,34.696159 z M -0.95648360,42.055534 L -0.74554610,40.479362 L -1.1967180,40.479362 C -1.3959367,40.479362 -1.5424211,40.422722 -1.6361711,40.309441 C -1.7299211,40.192253 -1.7767961,40.053581 -1.7767961,39.893425 C -1.7767961,39.733269 -1.7299211,39.598503 -1.6361711,39.489128 C -1.5424211,39.375847 -1.3959367,39.319206 -1.1967180,39.319206 L -0.58734298,39.319206 L -0.39398360,37.877800 L -0.85101485,37.877800 C -1.0463274,37.877800 -1.1908586,37.821159 -1.2846086,37.707878 C -1.3783586,37.590691 -1.4252336,37.452019 -1.4252336,37.291862 C -1.4252336,37.127800 -1.3783586,36.991081 -1.2846086,36.881706 C -1.1908586,36.768425 -1.0463274,36.711784 -0.85101485,36.711784 L -0.21820235,36.711784 L 0.039610147,34.830925 C 0.066953897,34.631706 0.12945390,34.477409 0.22711015,34.368034 C 0.32867265,34.258659 0.48882890,34.203972 0.70757890,34.203972 C 0.86382890,34.203972 0.99273515,34.248894 1.0942976,34.338737 C 1.1958601,34.424675 1.2466414,34.543816 1.2466414,34.696159 C 1.2466414,34.762566 1.2310164,34.907097 1.1997664,35.129753 L 0.98296952,36.711784 L 2.0669539,36.711784 L 2.3189070,34.830925 C 2.3462508,34.631706 2.4087508,34.477409 2.5064070,34.368034 C 2.6079695,34.258659 2.7681258,34.203972 2.9868758,34.203972 C 3.1431258,34.203972 3.2720320,34.248894 3.3735945,34.338737 C 3.4751570,34.428581 3.5259383,34.547722 3.5259383,34.696159 C 3.5259383,34.762566 3.5103133,34.907097 3.4790633,35.129753 L 3.2622664,36.711784 L 3.7192976,36.711784 C 3.9224226,36.711784 4.0689070,36.768425 4.1587508,36.881706 C 4.2525008,36.991081 4.2993758,37.127800 4.2993758,37.291862 C 4.2993758,37.452019 4.2525008,37.590691 4.1587508,37.707878 C 4.0650008,37.821159 3.9185164,37.877800 3.7192976,37.877800 L 3.1099226,37.877800 L 2.9165633,39.319206 L 3.3735945,39.319206 C 3.5767195,39.319206 3.7232039,39.373894 3.8130476,39.483269 C 3.9028914,39.592644 3.9478133,39.729362 3.9478133,39.893425 C 3.9478133,40.057487 3.9009383,40.196159 3.8071883,40.309441 C 3.7173445,40.422722 3.5728133,40.479362 3.3735945,40.479362 L 2.7349226,40.479362 L 2.4829695,42.354362 C 2.4556258,42.549675 2.3931258,42.702019 2.2954695,42.811394 C 2.1978133,42.920769 2.0376570,42.975456 1.8150008,42.975456 C 1.6587508,42.975456 1.5278914,42.932487 1.4224226,42.846550 C 1.3208601,42.756706 1.2700789,42.635612 1.2700789,42.483269 C 1.2700789,42.405144 1.2876570,42.262566 1.3228133,42.055534 L 1.5396101,40.479362 L 0.45562577,40.479362 L 0.20367265,42.354362 C 0.17632890,42.553581 0.11187577,42.707878 0.010313272,42.817253 C -0.087342978,42.922722 -0.24749923,42.975456 -0.47015548,42.975456 C -0.62249923,42.975456 -0.75140548,42.932487 -0.85687423,42.846550 C -0.95843673,42.756706 -1.0092180,42.635612 -1.0092180,42.483269 C -1.0092180,42.405144 -0.99163985,42.262566 -0.95648360,42.055534 z M 1.7153914,39.319206 L 1.9087508,37.877800 L 0.81890702,37.877800 L 0.62554765,39.319206 L 1.7153914,39.319206 z " id="path832" style="font-size:12.000000;font-weight:900;fill:#ffffff;stroke-width:1.0000000pt;font-family:VAG Rounded Black SSi;" transform="matrix(2.687231,-1.389012e-16,1.389012e-16,2.687231,8.790176,-72.34898)"/>
+</svg>
diff --git a/pix/irc/hexchat-connection-complete.png b/pix/irc/hexchat-connection-complete.png
new file mode 100644
index 0000000..096ae01
--- /dev/null
+++ b/pix/irc/hexchat-connection-complete.png
Binary files differ
diff --git a/pix/irc/hexchat-network-edit.png b/pix/irc/hexchat-network-edit.png
new file mode 100644
index 0000000..4a0fb6f
--- /dev/null
+++ b/pix/irc/hexchat-network-edit.png
Binary files differ
diff --git a/pix/irc/hexchat-network-select.png b/pix/irc/hexchat-network-select.png
new file mode 100644
index 0000000..9f4ffe3
--- /dev/null
+++ b/pix/irc/hexchat-network-select.png
Binary files differ
diff --git a/pix/irc/hexchat-sasl.png b/pix/irc/hexchat-sasl.png
new file mode 100644
index 0000000..ce77149
--- /dev/null
+++ b/pix/irc/hexchat-sasl.png
Binary files differ
diff --git a/pix/irc/textual-identity.png b/pix/irc/textual-identity.png
new file mode 100644
index 0000000..a2fce22
--- /dev/null
+++ b/pix/irc/textual-identity.png
Binary files differ
diff --git a/pix/irc/textual-network-edit.png b/pix/irc/textual-network-edit.png
new file mode 100644
index 0000000..1eb4dc7
--- /dev/null
+++ b/pix/irc/textual-network-edit.png
Binary files differ
diff --git a/pix/jitsi-01.webp b/pix/jitsi-01.webp
new file mode 100644
index 0000000..a71f1ae
--- /dev/null
+++ b/pix/jitsi-01.webp
Binary files differ
diff --git a/pix/jitsi.svg b/pix/jitsi.svg
new file mode 100644
index 0000000..5a3526a
--- /dev/null
+++ b/pix/jitsi.svg
@@ -0,0 +1,650 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg5488"
+ version="1.1"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="New document 5">
+ <defs
+ id="defs5490">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective5496" />
+ <inkscape:perspective
+ id="perspective5347"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8896"
+ id="linearGradient4242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-297.23084,320.86007)"
+ x1="439.90353"
+ y1="455.73935"
+ x2="469.71744"
+ y2="557.74847" />
+ <linearGradient
+ id="linearGradient8896">
+ <stop
+ id="stop8898"
+ offset="0"
+ style="stop-color:#0f3060;stop-opacity:1;" />
+ <stop
+ style="stop-color:#0575ce;stop-opacity:1;"
+ offset="0.27115166"
+ id="stop8902" />
+ <stop
+ id="stop12553"
+ offset="0.7327472"
+ style="stop-color:#0575ce;stop-opacity:1;" />
+ <stop
+ style="stop-color:#0f3060;stop-opacity:1;"
+ offset="1"
+ id="stop8900" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5041"
+ id="linearGradient4244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-297.23084,320.86007)"
+ x1="382.80234"
+ y1="585.22589"
+ x2="347.44287"
+ y2="645.02435" />
+ <linearGradient
+ id="linearGradient5041">
+ <stop
+ style="stop-color:#092d61;stop-opacity:1;"
+ offset="0"
+ id="stop5043" />
+ <stop
+ id="stop5047"
+ offset="1"
+ style="stop-color:#0575ce;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3493"
+ id="linearGradient4246"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-297.23084,320.86007)"
+ x1="415.81378"
+ y1="620.09808"
+ x2="436.35599"
+ y2="486.43097" />
+ <linearGradient
+ id="linearGradient3493">
+ <stop
+ style="stop-color:#0f3060;stop-opacity:1;"
+ offset="0"
+ id="stop3495" />
+ <stop
+ id="stop3497"
+ offset="0.45698157"
+ style="stop-color:#0575ce;stop-opacity:1;" />
+ <stop
+ style="stop-color:#0575ce;stop-opacity:1;"
+ offset="0.73828435"
+ id="stop3501" />
+ <stop
+ id="stop3507"
+ offset="1"
+ style="stop-color:#0f3060;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3529"
+ id="linearGradient4248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,34.35214,723.04037)"
+ x1="389.59329"
+ y1="763.3017"
+ x2="308.98642"
+ y2="420.01578" />
+ <linearGradient
+ id="linearGradient3529">
+ <stop
+ id="stop3531"
+ offset="0"
+ style="stop-color:#ff8000;stop-opacity:1;" />
+ <stop
+ style="stop-color:#fff4e1;stop-opacity:1;"
+ offset="0.6627211"
+ id="stop3533" />
+ <stop
+ id="stop3535"
+ offset="0.75"
+ style="stop-color:#fff4e1;stop-opacity:1;" />
+ <stop
+ id="stop3537"
+ offset="1.0000000"
+ style="stop-color:#ff8400;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3591"
+ id="linearGradient4250"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-297.23084,320.86007)"
+ x1="528.82031"
+ y1="511.71811"
+ x2="458.46918"
+ y2="527.10736" />
+ <linearGradient
+ id="linearGradient3591">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3593" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3595" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7434"
+ id="linearGradient4252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,34.35214,723.04037)"
+ x1="197.17841"
+ y1="703.80151"
+ x2="146.54216"
+ y2="785.90436" />
+ <linearGradient
+ id="linearGradient7434">
+ <stop
+ id="stop7436"
+ offset="0"
+ style="stop-color:#ffc768;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ff8400;stop-opacity:1.0000000;"
+ offset="0.37842149"
+ id="stop7438" />
+ <stop
+ id="stop7440"
+ offset="0.77420431"
+ style="stop-color:#ff8400;stop-opacity:1.0000000;" />
+ <stop
+ id="stop7442"
+ offset="1"
+ style="stop-color:#ffc768;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3591"
+ id="linearGradient4254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0334058,0,0,1.0138319,-309.91012,314.18347)"
+ x1="413.63229"
+ y1="484.60083"
+ x2="423.52518"
+ y2="541.83301" />
+ <linearGradient
+ id="linearGradient5384">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5386" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop5388" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3509"
+ id="linearGradient4256"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,34.35214,723.04037)"
+ x1="409.69571"
+ y1="559.36359"
+ x2="467.88617"
+ y2="676.03516" />
+ <linearGradient
+ id="linearGradient3509">
+ <stop
+ id="stop3511"
+ offset="0"
+ style="stop-color:#ff8000;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffc768;stop-opacity:1.0000000;"
+ offset="0.34144846"
+ id="stop3513" />
+ <stop
+ id="stop3515"
+ offset="0.71198046"
+ style="stop-color:#ffc768;stop-opacity:1.0000000;" />
+ <stop
+ id="stop3517"
+ offset="1.0000000"
+ style="stop-color:#ff8400;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3651"
+ id="linearGradient4258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,34.35214,723.04037)"
+ x1="522.63641"
+ y1="168.68723"
+ x2="585.93317"
+ y2="161.10866" />
+ <linearGradient
+ id="linearGradient3651">
+ <stop
+ style="stop-color:#ff8000;stop-opacity:1;"
+ offset="0"
+ id="stop3653" />
+ <stop
+ id="stop16786"
+ offset="0.5"
+ style="stop-color:#fff4e1;stop-opacity:1;" />
+ <stop
+ style="stop-color:#fff4e1;stop-opacity:1;"
+ offset="0.75"
+ id="stop17514" />
+ <stop
+ style="stop-color:#ff8400;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3655" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3509"
+ id="linearGradient4260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,34.35214,723.04037)"
+ x1="481.48975"
+ y1="417.49979"
+ x2="405.41116"
+ y2="316.78976" />
+ <linearGradient
+ id="linearGradient5403">
+ <stop
+ id="stop5405"
+ offset="0"
+ style="stop-color:#ff8000;stop-opacity:1;" />
+ <stop
+ style="stop-color:#ffc768;stop-opacity:1.0000000;"
+ offset="0.34144846"
+ id="stop5407" />
+ <stop
+ id="stop5409"
+ offset="0.71198046"
+ style="stop-color:#ffc768;stop-opacity:1.0000000;" />
+ <stop
+ id="stop5411"
+ offset="1.0000000"
+ style="stop-color:#ff8400;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3591"
+ id="linearGradient4262"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-297.23084,320.86007)"
+ x1="473.09195"
+ y1="499.58444"
+ x2="457.68967"
+ y2="477.5997" />
+ <linearGradient
+ id="linearGradient5414">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5416" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop5418" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3591"
+ id="linearGradient4264"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-297.23084,320.86007)"
+ x1="394.34113"
+ y1="501.80154"
+ x2="446.31302"
+ y2="485.37762" />
+ <linearGradient
+ id="linearGradient5421">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5423" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop5425" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3591"
+ id="linearGradient4266"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-297.23084,320.86007)"
+ x1="395.81326"
+ y1="590.73315"
+ x2="369.55322"
+ y2="572.16907" />
+ <linearGradient
+ id="linearGradient5428">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5430" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop5432" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2937"
+ id="linearGradient4268"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,34.35214,723.04037)"
+ x1="297.05316"
+ y1="667.16193"
+ x2="310.45529"
+ y2="713.86633" />
+ <linearGradient
+ id="linearGradient2937">
+ <stop
+ style="stop-color:#212a3a;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2939" />
+ <stop
+ style="stop-color:#404e67;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop2941" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2937"
+ id="linearGradient4270"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.09307993,0,0,0.1860535,131.94157,665.87199)"
+ x1="246.30438"
+ y1="690.02673"
+ x2="366.87921"
+ y2="632.15985" />
+ <linearGradient
+ id="linearGradient5439">
+ <stop
+ style="stop-color:#212a3a;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop5441" />
+ <stop
+ style="stop-color:#404e67;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop5443" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2937"
+ id="linearGradient4272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.09281332,-0.00703915,0.01407026,-0.1855207,186.19996,929.70821)"
+ x1="301.05194"
+ y1="645.89917"
+ x2="367.94604"
+ y2="654.72131" />
+ <linearGradient
+ id="linearGradient5446">
+ <stop
+ style="stop-color:#212a3a;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop5448" />
+ <stop
+ style="stop-color:#404e67;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop5450" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2937"
+ id="linearGradient4274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,98.31046,642.63728)"
+ x1="279.81714"
+ y1="688.32355"
+ x2="386.78625"
+ y2="667.6355" />
+ <linearGradient
+ id="linearGradient5453">
+ <stop
+ style="stop-color:#212a3a;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop5455" />
+ <stop
+ style="stop-color:#404e67;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop5457" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2937"
+ id="linearGradient4276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.245729,0,0,0.245729,25.55056,660.77045)"
+ x1="338.14404"
+ y1="668.3009"
+ x2="266.215"
+ y2="702.89276" />
+ <linearGradient
+ id="linearGradient5460">
+ <stop
+ style="stop-color:#212a3a;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop5462" />
+ <stop
+ style="stop-color:#404e67;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop5464" />
+ </linearGradient>
+ <linearGradient
+ y2="702.89276"
+ x2="266.215"
+ y1="668.3009"
+ x1="338.14404"
+ gradientTransform="matrix(0.245729,0,0,0.245729,25.55056,660.77045)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5486"
+ xlink:href="#linearGradient2937"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="375"
+ inkscape:cy="520"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="798"
+ inkscape:window-height="690"
+ inkscape:window-x="20"
+ inkscape:window-y="20"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata5493">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g4202"
+ transform="matrix(4.2070673,0,0,4.2070673,-152.93197,-3059.7049)">
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="csssssssssssssssssssssssssssssssssccssssssssssccsssssssssccsssssssssscssssssssssccssssssscssssssssc"
+ id="path4204"
+ d="m 52.51386,963.95968 c -0.59762,-1.31419 -1.08659,-2.49776 -1.08659,-2.63031 0,-0.13252 -2.08061,-11.07486 -2.31769,-13.88681 -1.03506,-12.27691 -2.66752,-13.45265 -2.21175,-24.39857 0.2761,-6.63061 -0.64392,-8.89235 1.31344,-14.31478 4.03102,-11.16694 6.98662,-15.56085 12.2251,-18.17414 4.24974,-2.12004 8.23695,-1.83207 11.97929,0.86518 0.98634,0.71092 4.29577,2.95048 7.35426,4.97678 3.05851,2.02634 6.69103,4.48296 8.07229,5.45919 1.38125,0.97628 3.68511,2.38497 5.11972,3.13046 2.53058,1.3151 2.62411,1.3351 3.13729,0.67104 1.12761,-1.45907 3.84947,-5.55395 5.32124,-7.50854 7.37209,-9.79052 0.42914,-8.70222 -1.30592,-9.21291 -2.72783,-0.80294 -3.87684,-1.97938 -6.42642,-4.96758 -5.92163,-6.94035 -8.72797,-14.66214 -9.14262,-24.20339 -0.48154,-11.07972 0.63266,-20.01531 5.49789,-25.10088 2.08527,-2.17973 6.49949,-5.34524 10.53505,-7.55495 3.4177,-1.87139 24.37883,-5.78232 26.21837,-4.96975 0.91898,0.40593 -3.63796,-11.63862 -1.01552,-27.29896 0.52096,-3.11103 4.05934,-12.73788 4.43322,-13.39298 0.92313,-1.61744 16.13503,-6.82395 20.46221,-9.36515 4.83486,-2.83935 15.29074,-9.67883 16.07843,-14.76568 1.73099,-11.1786 2.03825,-15.9556 2.75981,-16.37531 1.07388,-0.62465 8.25251,14.17566 3.39352,28.13116 -0.95893,2.75414 -5.53206,9.14865 -7.57975,11.8233 -1.47452,1.92602 1.72775,2.82621 3.56985,5.60679 1.67534,2.52882 2.77675,8.71086 2.9918,11.91416 0.21959,3.27101 -0.81543,9.98235 -1.7425,11.2988 -0.37549,0.53325 -0.52929,1.05709 -0.34387,1.17136 0.18449,0.11368 1.43417,-0.0352 2.77708,-0.33076 1.34289,-0.29559 4.25366,-0.7663 6.46837,-1.046 3.94259,-0.49787 4.08384,-0.49095 6.7595,0.33213 4.01386,1.23476 23.53789,5.95177 11.07947,60.50742 -4.12753,18.07453 -23.38873,41.92489 -25.8106,40.0783 l -5.96407,-4.5474 -6.87325,10.19022 c -3.50798,3.60293 -7.29065,7.08029 -9.52167,8.75312 -3.52051,2.63972 -10.56453,6.79799 -11.51562,6.79799 -0.24492,0 -1.63251,0.56931 -3.08354,1.26516 -4.19508,2.01176 -10.47851,3.66081 -17.13429,4.09795 -25.77135,1.66956 -15.93975,-1.44192 -37.27858,-11.77515 -1.68316,-0.81506 -5.55753,3.29679 -10.22719,7.54571 -4.98524,4.53606 -7.60226,7.98846 -9.57996,12.63792 -0.66947,1.57389 -1.71168,3.98838 -2.31602,5.36552 -1.64444,3.74731 -2.99719,8.93229 -3.19818,12.25814 -0.0983,1.62685 -0.31514,3.04193 -0.48187,3.14469 -0.16673,0.10272 -0.7921,-0.88841 -1.38973,-2.20249 z m 28.33197,-45.90886 c 3.30313,-0.83536 3.66477,-1.01966 7.21765,-3.67825 2.54576,-1.90501 4.12321,-5.3446 4.8004,-5.64508 4.4324,-1.96673 -3.3083,-3.73691 -6.20226,-5.68891 -2.89398,-1.95202 -6.65724,-3.39508 -9.2209,-5.3521 -2.56367,-1.95698 -4.78356,-3.48279 -4.93308,-3.39068 -0.14952,0.0921 -0.27471,1.40551 -0.27821,2.91861 -0.01023,4.41323 -0.6021,8.84164 -1.42935,10.69448 -0.42105,0.94301 -0.84611,2.76087 -0.94461,4.03969 -0.22816,2.96221 0.46109,4.38683 2.91271,6.02036 2.06595,1.3766 2.92385,1.38532 8.07765,0.0819 z m 119.70575,-83.58495 c -1.07558,-7.22468 -0.18498,-17.16053 -5.81444,-20.77728 -12.98767,-8.34415 -14.4135,-0.0696 -15.21021,1.75899 -1.31072,3.0083 -2.11753,5.46892 -1.12273,8.7761 3.05641,10.16086 6.96643,19.15821 8.82255,26.38029 2.13021,8.28856 4.47797,13.53077 4.71288,20.02986 0.16678,4.61378 0.12302,5.09887 -0.55601,6.16474 -0.9655,1.51542 -15.55215,5.22752 -22.89767,7.39176 -2.52211,0.74311 -0.28804,6.12175 -0.57696,7.89239 -0.28892,1.77059 -4.23701,11.66713 -2.96729,13.65682 12.52923,19.63374 40.23506,-40.20634 35.60988,-71.27367 z m -26.98831,48.27201 c 1.95984,-0.47131 3.79219,-1.04626 4.0719,-1.27773 0.27971,-0.23143 0.99066,-0.38419 1.57991,-0.33941 1.05432,0.0801 5.18218,-1.21949 5.4995,-1.73148 0.0894,-0.14415 3.7722,-2.06556 3.0355,-2.55357 -0.73674,-0.48803 -15.13237,-11.07005 -17.19649,-12.14627 -23.77004,-12.39364 -36.26526,-13.24685 -44.11407,-11.66556 -13.44457,2.70866 -25.05657,9.52598 -26.45346,11.20755 -0.42178,0.50774 21.04913,-6.66097 36.28977,0.87085 2.81591,1.39161 8.62965,3.78304 13.00058,8.46269 3.99268,4.27467 7.63329,8.79778 10.49869,9.5617 3.10695,0.82834 9.47337,0.64882 13.78817,-0.38877 z m -28.65731,-51.09687 c 7.52619,-1.317 19.18627,-16.95235 18.27894,-18.41606 -0.12276,-0.19808 2.25527,-4.14459 1.86904,-4.22161 -14.0842,-2.80833 -13.74485,-16.83242 -13.94793,-16.95753 -0.20308,-0.12514 -20.76525,9.71022 -25.50376,11.75869 -4.02092,1.73825 0.57503,12.10208 2.99929,18.53437 1.07855,2.86172 7.01744,6.67785 9.40766,8.23365 2.82773,1.84055 6.25378,1.181 6.89676,1.06849 z m 16.21969,-47.71727 c 4.06405,-3.20289 14.88802,-19.23422 13.73961,-25.73988 -4.67874,-26.5048 -6.69569,-10.0962 -6.99598,-7.73088 -0.12436,0.97963 -0.47868,3.14936 -0.7874,4.82161 -0.30868,1.67227 -0.70224,4.08678 -0.87456,5.36555 -0.1723,1.2788 -0.64865,3.53233 -1.05855,5.00784 -0.4099,1.47554 -1.05724,3.92831 -1.43856,5.45066 -0.38128,1.52232 -1.66486,5.27236 -2.85234,8.33339 -1.18749,3.06104 -2.15908,5.63846 -2.15908,5.72759 0,0.447 0.82393,0.0274 2.42686,-1.23588 z"
+ style="fill:url(#linearGradient4242);fill-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccssc"
+ id="path4206"
+ d="m 53.57922,963.11994 c 6.35309,-26.31992 12.10112,-29.26957 27.22751,-39.0261 -3.32781,-1.89079 -11.51745,-8.1594 -11.49606,-11.49606 0.05726,-9.74197 1.6676,-26.72201 -9.07584,-19.66431 -20.38515,13.39167 -13.0087,55.96766 -6.65561,70.18647 z"
+ style="fill:url(#linearGradient4244);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="ccccsc"
+ id="path4208"
+ d="m 75.93257,920.7226 c 8.98173,6.78619 16.91991,12.78559 22.55412,15.96751 54.94138,2.77762 68.66033,-27.59386 69.6583,-52.49321 -4.89006,0.22454 -13.22311,-0.97302 -17.71397,-7.7405 -11.21439,3.68089 -45.16617,14.00314 -45.75692,16.32304 -3.06467,12.03515 -12.17523,21.75574 -28.74153,27.94316 z"
+ style="fill:url(#linearGradient4246);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="cssssss"
+ id="path4210"
+ d="m 171.27539,910.58112 c 33.18508,-24.69965 28.91369,-74.159 29.44979,-76.69151 1.36299,-6.43866 -6.64955,-28.25155 -16.27383,-24.24947 -16.02424,6.66336 11.2767,44.44456 7.61407,65.1661 -0.76342,4.31907 -13.98948,7.50294 -22.98022,8.89864 -1.03689,0.16096 -0.1163,14.0955 -4.62673,20.50927 -0.64571,0.91818 6.21023,6.81854 6.81692,6.36697 z"
+ style="fill:url(#linearGradient4248);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4212"
+ d="m 175.90353,907.19115 c 42.49251,-41.74886 20.98218,-116.27813 6.14636,-94.50993 20.37687,-4.1207 23.61854,64.2671 -6.14636,94.50993 z"
+ style="fill:url(#linearGradient4250);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="csszs"
+ id="path4214"
+ d="m 95.21705,907.77562 c 0.78602,-1.06057 -13.88152,-6.08284 -22.74639,-14.06472 -0.98292,-0.88501 -1.14144,12.91242 -2.0703,18.66551 -0.57712,3.57451 5.4925,7.17351 6.87977,7.62184 1.15081,0.37191 14.71014,-7.86884 17.93692,-12.22263 z"
+ style="fill:url(#linearGradient4252);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path4216"
+ d="m 83.58536,868.01334 c -5.099007,-25.84347 4.179267,-41.03939 41.3579,-46.37791 0.18024,0.56879 41.31909,-13.25606 55.79189,-13.35001 -3.92283,6.23323 0.0433,21.62385 4.80916,34.27609 0,0 -34.8276,9.08768 -101.95895,25.45183 z"
+ style="fill:url(#linearGradient4254);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="csssss"
+ id="path4218"
+ d="m 101.65537,863.89391 c 4.41182,-1.58073 17.00722,-5.39035 32.05421,-0.1519 10.3057,3.58781 16.2195,12.63312 20.66816,16.112 10.4789,8.19457 29.82289,-0.90843 33.32172,-0.85341 1.43753,0.0226 -25.96694,-24.60193 -46.62844,-25.8478 -27.77538,-1.67482 -45.11147,12.78188 -39.41565,10.74111 z"
+ style="fill:url(#linearGradient4256);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="csss"
+ id="path4220"
+ d="m 169.42704,741.43522 c -0.1528,8.40398 -2.79669,28.46338 -11.30718,42.1727 -3.89274,6.27072 14.52008,-8.27661 16.50236,-20.78075 1.09029,-6.8775 -5.06881,-28.08959 -5.19518,-21.39195 z"
+ style="fill:url(#linearGradient4258);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="cssscsc"
+ id="path4222"
+ d="m 141.79058,833.10697 c 9.23931,-4.71783 17.65654,-10.92192 22.99128,-22.44259 0.9032,-1.9505 -4.39968,-0.0586 -8.47555,-5.84433 -4.0357,-5.72867 -3.08341,-11.54295 -6.54001,-11.07789 -10.80021,1.4531 -25.20082,11.63758 -25.20082,11.63758 0,0 0.82824,11.14408 3.74751,15.67372 6.01898,9.33928 13.47759,12.05351 13.47759,12.05351 z"
+ style="fill:url(#linearGradient4260);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4224"
+ d="m 156.09152,803.78111 c 2.72579,9.88879 17.87347,8.09668 14.70668,-11.15251 -1.36528,1.99619 -4.77608,12.95694 -14.70668,11.15251 z"
+ style="opacity:0.55223843;fill:url(#linearGradient4262);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ sodipodi:nodetypes="csccsc"
+ id="path4226"
+ d="m 140.48504,832.28297 c -5.10096,-3.46887 -9.50419,-7.78444 -12.32504,-12.34966 -2.82085,-4.56521 -4.0593,-27.84724 0.68685,-33.63375 2.60826,-6.3637 11.84132,-12.51424 22.09721,-15.2308 -19.49494,22.60506 -13.17796,56.86685 4.07359,53.53526 0.86206,-0.16648 -12.82587,7.73026 -14.53261,7.67895 z"
+ style="fill:url(#linearGradient4264);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4228"
+ d="m 72.32239,893.02911 c 3.80886,2.81881 20.23882,15.53557 23.85984,13.52306 -8.41018,20.55895 -30.55349,3.14238 -23.85984,-13.52306 z"
+ style="fill:url(#linearGradient4266);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="ccsssccssscccsssscscsccsssssccssssssccsssccssssccsscssssssssssssccsssccssssssccssssssssssssscsssscssscssc"
+ id="path4230"
+ d="m 140.05745,777.56053 c -3.94728,2.30056 -8.69302,4.87373 -9.63531,7.20019 -3.16217,6.64336 -4.34745,18.56552 -3.38465,17.88089 9.38401,-6.67285 20.24871,-8.52283 24.20205,-12.0967 11.71489,-10.59045 16.26287,-32.48353 13.80119,-29.2383 -7.96915,10.50564 -20.9111,13.88057 -24.98328,16.25392 z m -61.4085,147.01185 c 0,0 -11.08091,-7.66436 -10.87669,-10.1233 1.697,-20.4327 -1.92942,-21.625 -3.75706,-21.40828 -2.20803,0.26184 -13.6822,7.50553 -15.92058,27.95835 -1.62427,14.84147 4.24013,38.0296 5.13347,39.28426 4.62276,-12.42378 2.81919,-22.42331 25.42086,-35.71103 z m 121.05779,-90.52225 c -0.55133,-15.31772 -9.77382,-25.84979 -16.03746,-23.38322 -2.65737,1.04645 -4.4415,8.17887 -3.50846,12.60125 0.82755,3.92256 6.46634,19.10152 6.87179,20.38471 0.95868,3.03418 7.43087,21.62978 6.28035,30.56471 -1.00846,7.8316 -23.7097,10.5413 -23.7097,10.5413 0,0 -0.38149,6.37449 -1.16407,10.68177 -0.96202,5.29492 -2.86934,9.45033 -2.86934,9.45033 0,0 4.94251,4.60429 5.14224,4.59918 0.19973,-0.005 31.10844,-16.7127 28.99465,-75.44003 z m -23.69666,47.44964 c 1.59781,-0.44722 11.03201,-2.94175 10.52638,-3.27341 -3.50095,-2.2964 -7.48504,-5.18714 -14.1578,-10.37693 -37.04552,-28.81248 -70.69468,-4.54502 -70.03165,-4.76554 6.15153,-2.04594 12.64754,-3.20211 21.67232,-2.5993 7.26918,0.48555 18.69619,4.17029 28.70607,16.10244 3.72328,4.43828 7.94798,7.4497 23.28468,4.91274 z M 159.4851,818.95922 c 1.12085,-0.96962 5.01656,-8.31336 4.31505,-8.48395 -9.83076,-2.39074 -10.78824,-6.74031 -11.75043,-11.4727 -0.90123,-4.43254 -0.76219,-5.06465 -2.62452,-4.44953 -15.04703,4.96997 -19.20919,7.70131 -21.51157,9.61214 -3.60666,2.99331 -1.0768,11.03634 0.33349,14.23298 1.96563,4.4554 9.19232,12.51758 12.55437,13.16681 4.90391,0.94697 16.49344,-9.09974 18.68361,-12.60575 z m 10.93597,-27.14087 c -0.81548,-3.33524 -3.43538,-7.63066 -4.13349,-7.63066 -0.65744,0 -7.61876,5.38666 -9.4168,7.26354 -4.08086,4.25969 -2.09206,11.97893 2.43483,14.62671 7.66207,4.48154 13.28874,-5.37111 11.11546,-14.25959 z m -5.77705,-12.75642 c 3.35221,-3.34862 7.80844,-8.84532 8.99344,-17.19839 0.46443,-3.27384 0.73411,-6.15364 -1.30205,-12.62655 -0.47191,-1.50022 -1.90642,-5.8148 -1.96005,-5.24636 -1.05907,11.22382 -2.61083,23.68653 -9.93627,36.93167 -2.29934,4.15745 -1.06286,3.40174 4.20493,-1.86037 z m -78.6191,66.84814 c -3.99349,16.75103 6.58927,38.75062 15.16215,40.00456 8.28707,1.21213 32.04487,-5.96093 44.50484,-9.42568 3.26456,-0.90778 5.02074,-0.43427 -2.20131,-6.48455 -11.3226,-7.69755 -20.46099,-8.68868 -29.5776,-7.65392 -10.05581,1.14135 -17.59102,4.11772 -16.88606,3.52743 4.61053,-3.86056 12.8225,-10.76401 28.68812,-13.89013 6.89585,-1.35875 17.53788,-1.47808 30.38613,3.54005 15.93675,6.2244 24.23739,15.45542 30.97531,18.58381 2.39935,1.11401 3.25644,0.59604 4.20446,-2.18817 1.5883,-4.66452 -8.06663,-33.78938 -11.56456,-42.28236 -5.33802,-12.96073 0.89004,-19.15557 -0.47125,-18.85551 -6.6027,1.45543 -12.42508,5.69932 -17.306,10.06932 -11.93084,10.68198 -19.20273,12.95753 -20.28189,12.86579 -3.40727,-0.28972 -9.78249,-6.32022 -12.09877,-9.38241 -1.47795,-1.95389 -27.92949,3.15177 -35.72972,9.92827 -0.17845,0.15503 -6.19704,4.01498 -7.80385,11.6435 z M 77.5498,918.8389 c 8.72435,-3.6605 17.26585,-11.43939 16.52709,-11.56787 -4.52939,-0.78772 -21.23379,-12.23383 -21.22226,-12.11514 0.57378,5.90697 -0.71357,11.21473 -1.30092,17.06944 -0.24494,2.44161 3.00975,6.22428 5.99609,6.61357 z m 28.15174,-25.60492 c -1.66901,3.72058 -3.41156,18.3512 -27.53028,27.73991 -0.69864,0.27195 20.21205,14.57036 21.35002,14.62032 69.0544,3.03144 68.46916,-49.55437 67.5526,-50.88016 -0.13265,-0.19188 -6.03889,0.0138 -10.61352,-2.15692 -0.34887,-0.1655 -3.45204,-1.76502 -5.30227,-4.17423 -0.62757,-0.81715 -0.72524,-1.26122 -3.05074,-0.58541 -10.76269,3.12776 -42.89539,14.65696 -42.40581,15.43649 z M 84.18935,867.5847 c -12.33127,-43.08647 30.94329,-45.08535 37.80451,-46.74439 5.30593,-1.28297 4.14977,-1.78189 3.03089,-6.80033 -1.57099,-7.04629 -1.0816,-13.18841 0.26513,-19.77217 1.27351,-6.2258 1.93035,-9.37394 4.61998,-12.49571 2.16789,-2.51621 14.38379,-8.27049 17.4121,-9.72295 12.90529,-6.18974 17.83586,-12.99328 19.27422,-18.34465 1.014,-3.77255 2.49779,-13.07094 1.83081,-19.71727 -0.16416,-1.6359 0.89135,0.92745 6.14205,17.24159 2.68293,8.33593 1.36177,18.34502 -7.09994,27.38172 -1.14918,1.22726 -0.59185,1.4703 0.95354,4.02388 3.21078,5.30554 4.98573,11.93993 4.48566,16.76662 -0.40972,3.95432 -2.10008,7.6934 0.31754,7.40286 0.34951,-0.042 11.02834,-1.65875 18.33848,2.98757 4.95048,3.14653 12.00258,9.17808 10.17204,34.37342 -4.00842,55.17187 -30.9649,67.17892 -31.15387,67.18542 -0.4563,0.0156 -5.49956,-5.22074 -5.79806,-4.60407 -15.45677,31.93103 -47.3506,30.78387 -65.13826,31.11951 -3.55635,0.0671 -18.34444,-12.38469 -19.59088,-11.53286 -15.74294,10.75882 -20.11352,13.44589 -26.18374,40.94381 -0.23264,-0.43595 -8.41803,-14.95561 -8.07826,-44.15673 0.27838,-23.92523 13.34923,-35.21616 19.15997,-34.56498 7.05422,0.79055 10.59443,4.47084 20.52923,10.99795 1.77335,1.16509 8.0388,4.95377 9.46457,4.91926 3.5521,-0.0838 5.97534,-6.60969 6.55509,-10.83484 0.58475,-4.26168 1.15009,-3.23167 -2.17605,-4.37633 -4.1934,-1.44311 -11.42652,-9.296 -15.13675,-21.67633 z"
+ style="fill:#2c3b54;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="czssss"
+ id="path4232"
+ d="m 106.11345,892.83442 c 6.47531,-3.53335 43.23312,-15.02538 43.56314,-15.74675 0.24089,-0.52655 -43.11579,17.30875 -52.93537,10.69734 -0.59185,-0.39849 2.29344,1.72127 4.90219,2.25652 0.18326,0.0376 0.17092,6.89208 -2.30068,10.77041 -0.6931,1.08758 5.26729,-7.15715 6.77072,-7.97752 z"
+ style="fill:url(#linearGradient4268);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="csss"
+ id="path4234"
+ d="m 166.00752,784.18642 c -4.02929,2.81265 -9.5846,6.74255 -10.72057,9.77333 -0.66996,1.78745 -1.12247,-4.99153 3.45182,-9.03009 2.57716,-2.27533 8.09315,-1.31871 7.26875,-0.74324 z"
+ style="fill:url(#linearGradient4270);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="csss"
+ id="path4236"
+ d="m 160.58968,806.82846 c 4.57007,1.3627 8.10001,-1.42847 10.03503,-7.4422 0.22874,-0.71087 -0.56553,5.2666 -3.40562,7.48857 -2.70767,2.11837 -7.59288,-0.33365 -6.62941,-0.0464 z"
+ style="fill:url(#linearGradient4272);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="cscss"
+ id="path4238"
+ d="m 172.18948,813.03639 c 6.47531,-3.53335 13.10498,-2.9926 18.75586,-2.73805 3.75103,0.16896 -7.06591,-4.20527 -19.35477,-3.52147 -1.31254,1.11755 -5.21285,7.63595 -10.70973,14.23704 -0.82526,0.99104 9.80521,-7.15715 11.30864,-7.97752 z"
+ style="fill:url(#linearGradient4274);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:export-ydpi="19.25"
+ inkscape:export-xdpi="19.25"
+ inkscape:export-filename="/home/emcho/storage/images/sc_logo/sc_logo136x203.png"
+ sodipodi:nodetypes="csccscs"
+ id="path4240"
+ d="m 110.55877,827.01111 c 3.80202,-0.78266 8.57073,-2.07478 11.72698,-2.39299 2.63172,-0.26532 5.92925,-1.74739 8.46259,0.97744 -1.41052,-1.93357 -4.10815,-5.83882 -4.94871,-8.39667 0.76528,3.00553 -2.65492,3.42931 -3.50504,3.56438 -19.11709,3.02037 -30.61745,8.16849 -36.41981,17.74206 10.99033,-8.50263 23.96641,-11.34651 24.68399,-11.49422 z"
+ style="fill:url(#linearGradient5486);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ </g>
+ </g>
+</svg>
diff --git a/pix/landchad.gif b/pix/landchad.gif
new file mode 100644
index 0000000..302cd26
--- /dev/null
+++ b/pix/landchad.gif
Binary files differ
diff --git a/pix/peertube-login.jpg b/pix/peertube-login.jpg
new file mode 100644
index 0000000..d191cc4
--- /dev/null
+++ b/pix/peertube-login.jpg
Binary files differ
diff --git a/pix/peertube.svg b/pix/peertube.svg
new file mode 100644
index 0000000..38992a5
--- /dev/null
+++ b/pix/peertube.svg
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ viewBox="2799 -911 16 22"
+ version="1.1"
+ id="svg13"
+ sodipodi:docname="logo.svg"
+ width="16"
+ height="22"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06">
+ <metadata
+ id="metadata17">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1916"
+ inkscape:window-height="1040"
+ id="namedview15"
+ showgrid="false"
+ inkscape:zoom="29.790476"
+ inkscape:cx="-1.1827326"
+ inkscape:cy="12.088"
+ inkscape:window-x="0"
+ inkscape:window-y="18"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg13" />
+ <defs
+ id="defs4">
+ <style
+ id="style2">
+ .cls-3 {
+ fill: #211f20;
+ }
+
+ .cls-4 {
+ fill: #737373;
+ }
+
+ .cls-5 {
+ fill: #f1680d;
+ }
+
+ .cls-6 {
+ fill: rgba(255, 255, 255, 0);
+ }
+ </style>
+ </defs>
+ <g
+ id="Artboard_1"
+ data-name="Artboard – 1"
+ class="cls-1"
+ transform="translate(0.03356777,-1.9929667)">
+ <g
+ id="Symbol_3_1"
+ data-name="Symbol 3 – 1"
+ transform="translate(2759,-975)">
+ <g
+ id="Group_44"
+ data-name="Group 44"
+ transform="translate(0,2.333)">
+ <path
+ id="Path_4"
+ data-name="Path 4"
+ class="cls-3"
+ d="m -949,-500 v 10.667 l 8,-5.333"
+ transform="translate(989,564)"
+ inkscape:connector-curvature="0"
+ style="fill:#211f20" />
+ <path
+ id="Path_5"
+ data-name="Path 5"
+ class="cls-4"
+ d="m -949,-500 v 10.667 l 8,-5.333"
+ transform="translate(989,574.667)"
+ inkscape:connector-curvature="0"
+ style="fill:#737373" />
+ <path
+ id="Path_6"
+ data-name="Path 6"
+ class="cls-5"
+ d="m -949,-500 v 10.667 l 8,-5.333"
+ transform="translate(997,569.333)"
+ inkscape:connector-curvature="0"
+ style="fill:#f1680d" />
+ <path
+ id="Path_7"
+ data-name="Path 7"
+ class="cls-6"
+ d="M 0,0 V 10.667 L 8,5.333 Z"
+ transform="rotate(180,24,40)"
+ inkscape:connector-curvature="0"
+ style="fill:rgba(255,255,255,0)" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/pleroma.html b/pleroma.html
new file mode 100644
index 0000000..b7e149e
--- /dev/null
+++ b/pleroma.html
@@ -0,0 +1,169 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Setup a Pleroma Server &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Setup a Pleroma Server</h1></header>
+ <nav></nav>
+ <main>
+
+ <p>Hopefully by now you won't have to be sold on the invasive practices that social media companies conduct. Websites such as Facebook and Twitter aquire so much data on users that they often know more about you than you know about yourself.
+
+The simple solution to this is to not use social media. However, that just isn't an option for most people. So the next best thing is to setup a self-hosted and federalised social media site so that you have full control over your data.
+
+I've previously made<a href="https://www.youtube.com/watch?v=l7mVsLSsotU"> a video showing all the steps in depth if you want to check it out.</a> If you run into any issues I suggest you look at the video.
+</p>
+
+ <p>You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address <a href="https://landchad.net/dns.html">which is explained in this tutorial.</a>
+ </p>
+
+
+
+<h2>Installation</h2>
+
+<h3>Setting Up and Configuring</h3>
+
+<p>First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban.
+There's a great tutorial on how to do this <a href="https://landchad.net/sshkeys.html">which can be read here.</a>
+</p>
+
+<p>
+Next we'll install the required packages:
+</p>
+
+<pre><code>apt install -y curl unzip libncurses5 postgresql postgresql-contrib nginx certbot libmagic-dev</code></pre>
+
+<p>
+You can manually configure postgreSQL to suit your system better. <a href="https://docs-develop.pleroma.social/backend/configuration/postgresql/">Check out the documentation here</a> and then run the below command:
+</p>
+
+<pre><code>systemctl restart postgresql</code></pre>
+
+
+<h3>Installing the Pleroma App</h3>
+
+<h4>First as the root user</h4>
+<p>
+Pleroma is not in the Debian app repositories, so we will install it manually.
+First create the Pleroma user by running the below command:
+</p>
+
+<pre><code>useradd -m -s /bin/bash -d /opt/pleroma pleroma</code></pre>
+
+<p>
+Then, still as root, we will create the required directories and give the Pleroma user ownership of them.
+</p>
+
+<pre><code>mkdir -p /var/lib/pleroma/uploads
+chown -R pleroma /var/lib/pleroma
+mkdir -p /var/lib/pleroma/static
+chown -R pleroma /var/lib/pleroma
+mkdir -p /etc/pleroma
+chown -R pleroma /etc/pleroma</code></pre>
+
+<h4>Now, as the new Pleroma user</h4>
+
+<p>
+Now run <code>su -l pleroma</code> to login as the Pleroma user.
+Now use the <code>curl</code> command below to download the Pleroma software and unzip it.
+</p>
+
+<pre><code>curl 'https://git.pleroma.social/api/v4/projects/2/jobs/artifacts/stable/download?job=<strong>amd64</strong>' -o /tmp/pleroma.zip
+unzip /tmp/pleroma.zip -d /tmp/</code></pre>
+
+<aside><p>Note that we are downloading the <strong>amd64</strong> version here. If you know you have a different CPU architecture, replace that with whatever your architecture is.</p></aside>
+
+<pre><code>mv /tmp/release/* /opt/pleroma
+rmdir /tmp/release
+rm /tmp/pleroma.zip
+./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql</code></pre>
+
+<p>We need to briefly return to the root user so we can run the following command (via the postgres user) to set up the database.
+Type <code>ctrl-d</code> or run <code>exit</code> to return to the root user, then run:
+</p>
+
+<pre><code>su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"</code></pre>
+
+<p>Then return to the pleroma user with <code>su -l pleroma</code> and we will test to see that Pleroma can run:</p>
+
+<pre><code>./bin/pleroma_ctl migrate
+./bin/pleroma daemon</code></pre>
+
+<p>
+That will initialize Pleroma. It might take as long as a minute to get started, so wait a bit, then run the following:
+</p>
+<pre><code>curl http://localhost:4000/api/v1/instance</code></pre>
+
+<p>If everything is working, this command will give you a long line of messy output. If it is not, you will get a connection error message.
+Once it is working successfully, stop the Pleroma daemon and we will interface Pleroma with the web server.</p>
+
+<pre><code>./bin/pleroma stop</code></pre>
+
+<h3>Setup and Configure Nginx</h3>
+
+<p>
+Return again to the root user. Let's copy Pleroma's Nginx configuration file from the template given in the installation and enable it:
+</p>
+
+<pre><code>cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.conf
+ln -s /etc/nginx/sites-available/pleroma.conf /etc/nginx/sites-enabled/pleroma.conf</code></pre>
+
+<p>Edit the <code>etc/nginx/sites-available/pleroma.conf</code> file and replace <strong>example.tld</strong> with your domain name.</p>
+
+<p>
+We now have to get a SSL certificate to enable encryption, since we have a model configuration that already includes SSL information,
+just check the brief <a href="standalone.html">the standalone certificate page</a> to get the needed certificate.
+Once you've got your cert setup, copy over the Nginx configuration with the below command:
+</p>
+
+<p>
+Once everything, including your Cerbot certificate is ready, simply reload Nginx with this command:
+</p>
+
+<pre><code>systemctl reload nginx</code></pre>
+
+
+<h3>Setting up the service</h3>
+
+<p>
+Pleroma itself runs on a SystemD service similar to other things running on your server like Nginx. To start the service up run the below commands:
+</p>
+
+<pre><code>cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service
+systemctl start pleroma
+systemctl enable pleroma</code></pre>
+
+<p>
+If everything worked then when you go to your domain in the web browser you should see a bare-bones Pleroma instance.
+</p>
+
+
+<h3>Creating an Admin User</h3>
+
+<p>You'll be able to create new accounts on the Pleroma instance in the login section on the website but the easiest way to setup an admin account is with the CLI. Simply run the below command replaced with your username:
+</p>
+
+<pre><code>su -l pleroma
+./bin/pleroma_ctl user new <strong>username</strong> <strong>username</strong>@<strong>example.org</strong> --admin</code></pre>
+
+<p>
+If you run into any issues then <a href="https://docs-develop.pleroma.social/backend/installation/otp_en/">feel free to checkout the documentation</a> or send me an email or message. My details are below.
+</p>
+
+<ul>
+ <li><a href="https://biasedriot.co">biasedriot.co</a></li>
+ <li><a href="https://www.youtube.com/channel/UCehh50T6qtDpt_kEUF33GJw">youtube</a></li>
+ <li>Bitcoin: <code class=crypto>1Dmn9jEtWAhdLk1HHWkUVNeDdAaBCwNajm</code></li>
+ <li>Monero: <code>84Y4FZiTbLeR5qc1fBrBhB1yq5agKtEdoixq2w1ysXJv486MiBCz3czGT15bqeXDPpdLoNyF93inxY3BCk6g8mrDMNKoArS</code></li>
+</ul>
+
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/rss-bridge.html b/rss-bridge.html
new file mode 100644
index 0000000..59f51c0
--- /dev/null
+++ b/rss-bridge.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Setting up RSS Bridge &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Setting up RSS Bridge</h1></header>
+ <nav></nav>
+ <main>
+
+ <p>RSS Bridge is a useful utility you can use to help you avoid the big tech sites, like Facebook and Twitter, which instead of the feed you usually would see, will be a based and minimalist RSS feed. </p>
+
+
+ <p>You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address <a href="https://landchad.net/dns.html">which is explained in this tutorial.</a>
+ </p>
+
+
+
+<h2>Installation</h2>
+
+<h3>Setting Up and Configuring</h3>
+
+<p>First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban.
+There's a great tutorial on how to do this <a href="https://landchad.net/sshkeys.html">which can be read here.</a>
+</p>
+
+<p>
+Next we'll install the required packages:
+</p>
+
+<pre><code>apt install -y curl unzip nginx certbot php-fpm php-mysql php-cli php7.3-mbstring php7.3-curl php7.3-xml php7.3-sqlite3 php7.3-json</code></pre>
+
+<p>We now have to create the website configuration file. Create/open the a file below:</p>
+<pre><code>nano /etc/nginx/sites-available/rss-bridge</code></pre>
+<p>And add the following content:</p>
+
+<pre><code>server {
+ root /var/www/rss-bridge;
+ index index.php index.html index.htm index.nginx-debian.html;
+ server_name rss-bridge.<strong>example.org</strong>;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location ~ \.php$ {
+ include snippets/fastcgi-php.conf;
+ fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
+ }
+
+ location ~ /\.ht {
+ deny all;
+ }
+}
+</code></pre>
+
+<p>After you have saved the file, you need to create a symlink so the server actually will read the file.</p>
+<pre><code>ln -s /etc/nginx/sites-available/rss-bridge /etc/nginx/sites-enabled/rss-bridge</code></pre>
+
+<p>Then we have to create the folder where the service will reside in.</p>
+<pre><code>mkdir -p /var/www/rss-bridge
+cd /var/www/rss-bridge
+</code></pre>
+
+<p>Lets download the latest version of RSS-Bridge in the directory.</p>
+<p>The newest version can be found <a href="https://github.com/RSS-Bridge/rss-bridge/releases">here</a>, at the time of writing that is "RSS-Bridge 2021-04-25."</p>
+ <pre><code>wget https://github.com/RSS-Bridge/rss-bridge/archive/refs/tags/<strong>2021-04-25.zip</strong></code></pre>
+<p>Unzip the file:</p>
+<pre><code>unzip <strong>2021-04-25.zip</strong></code></pre>
+<p>This will create a directory called rss-bridge-version-number, we now want to move all the file contents of the newly created directory to the one we are in</p>
+<pre><code>mv <strong>rss-bridge-2021-04-25</strong>/* .
+rm -rf <strong>rss-bridge-2021-04-25 2021-04-25.zip</strong>
+</code></pre>
+
+<p>Now all we need to do is grant read/write permissions and reload the web server.</p>
+
+<pre><code>chown -R www-data:www-data /var/www/rss-bridge
+systemctl reload nginx
+</code></pre>
+
+<p>That's it, you should now have a working rss-bridge installed. But you should definately get an SSL certifcate installed <a href="https://landchad.net/certbot.html">which is done briefly here</a>.</p>
+
+
+<ul>
+ <li><a href="https://handskemager.xyz">handskemager.xyz</a></li>
+ <li>Bitcoin: <code class=crypto>bc1qhfjgwjzksf2auqjefwpvq20wvyugq3lhqgkxvu</code></li>
+ <li>Monero: <code class=crypto>88cPx6Gzv5RWRRJLstUt6hACF1BRKPp1RMka1ukyu2iuHT7iqzkNfMogYq3YdDAC8AAYRqmqQMkCgBXiwdD5Dvqw3LsPGLU</code></li>
+</ul>
+
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/rss.xml b/rss.xml
index 50dda18..430d60b 100644
--- a/rss.xml
+++ b/rss.xml
@@ -16,7 +16,1827 @@
<!-- LB -->
<item>
-<title>Hosting Your Own Git Repositories &ndash; LandChad.net</title>
+<title>Setting up a Calibre library server</title>
+<guid>https://landchad.net/calibre.html</guid>
+<link>https://landchad.net/calibre.html</link>
+<pubDate>Tue, 03 Aug 2021 13:49:21 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Setting up a Calibre library server</h1></header>
+
+ <main>
+ <img src="pix/calibre.png" alt="Calibre logo" class=titleimg>
+ <p>
+ The Calibre library server is a great way to store your eBooks.
+ It allows you to:
+ </p>
+ <ul>
+ <li>Share your books with others.</li>
+ <li>Easily transfer your books between devices and access them from anywhere.</li>
+ </ul>
+ <h2>Installation</h2>
+ <p>Install the Calibre package.
+ You might also want rsync to upload books.</p>
+ <pre><code>apt install -y calibre rsync
+mkdir /opt/calibre</code></pre>
+ <p>
+ Either upload your existing library using <code>rsync</code>. For example to <code>/opt/calibre/</code>.
+ </p>
+ <p>
+ On client:
+ </p>
+ <pre><code>cd ~/Documents
+rsync -avuP <strong>your-library-dir</strong> root@<strong>example.org</strong>:/opt/calibre/</code></pre>
+ <p>
+ Or create a library and add a book to it:
+ </p>
+<pre><code>cd /opt/calibre
+calibredb add <strong>book.epub</strong> --with-library <strong>your-library</strong></code></pre>
+ <aside>
+ <p>
+ For more information about the <code>calibredb</code> command see <code>man calibredb</code>.
+ </p>
+ </aside>
+ <p>
+ Add a new user to protect your server:
+ </p>
+ <pre><code>calibre-server --manage-users</code></pre>
+ <h2>Creating a service</h2>
+ <p>
+ Create a new file <code>/etc/systemd/system/calibre-server.service</code> and add the following:
+ </p>
+<pre><code>[Unit]
+Description=Calibre library server
+After=network.target
+[Service]
+Type=simple
+User=root
+Group=root
+ExecStart=/usr/bin/calibre-server --enable-auth --enable-local-write /opt/calibre/your_library --listen-on 127.0.0.1
+[Install]
+WantedBy=multi-user.target
+</code></pre>
+ <aside>
+ <p>
+ You can change the port with the <code>--port</code> prefix. Additional information <code>man calibre-server</code>.
+ </p>
+ </aside>
+ <p>
+ Issue <code>systemctl daemon-reload</code> to apply the changes.
+ </p>
+ <p>
+ Enable and start the service.
+ </p>
+<pre><code>systemctl enable calibre-server
+systemctl start calibre-server</code></pre>
+ <h2>A reverse proxy with Nginx</h2>
+ <p>
+ Create a new file <code>/etc/nginx/sites-available/calibre</code> and enter the following:
+ </p>
+<pre><code>server {
+ listen 80;
+ client_max_body_size 64M; # to upload large books
+ server_name <strong>calibre.example.org</strong> ;
+ location / {
+ proxy_pass http://127.0.0.1:8080;
+ }
+}</code></pre>
+ <p>Issue a Let's Encrypt certificate. <a href="certbot.html">Detailed instructions and additional information</a>.</p>
+ <pre><code>certbot --nginx</code></pre>
+ <p>Now just go to <strong>calibre.example.org</strong>. The server will request an username and a password.</p>
+ <a href="pix/calibre-1.png">
+ <img src="pix/calibre/calibre-1.png" alt="calibre">
+ </a>
+ <p>After login you will see something like this.</p>
+ <a href="pix/calibre-1.png">
+ <img src="pix/calibre/calibre-2.png" alt="calibre">
+ </a>
+ <h2>Contribution</h2>
+ <li>Author: rflx &ndash; <a href="https://rflx.xyz">website</a> -- XMR: <code class=crypto>48T5XpHTXAZ5Nn8YCypA4aWn1ffQLHJkFGDArXQB6cmrP6cqLY72cu7CR2iq2MmL5Ndu3d47e5MKjGpL4prYgdrTCFAHD9c</code>
+ </li>
+ </main>
+]]></description>
+</item>
+
+
+<item>
+<title>Jitsi Video Chat</title>
+<guid>https://landchad.net/jitsi.html</guid>
+<link>https://landchad.net/jitsi.html</link>
+<pubDate>Tue, 03 Aug 2021 13:00:23 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Jitsi Video Chat</h1></header>
+
+ <main>
+ <img src="pix/jitsi.svg" alt="Jitsi" class=titleimg>
+ <p>
+ <dfn>Jitsi</dfn> is a set of open-source projects that allows you to easily build and deploy secure video conferencing solutions.
+ </p>
+ <p>
+ Is really easy to install, and also a really good private, federated and libre alternative to Zoom or other video conferencing software.
+ You can create calls just by typing the URL, and loging-in is not necessary.
+ </p>
+ <h2>Dependencies and Installation</h2>
+ <p>First, install some dependencies:</p>
+ <pre><code>apt install gpg apt-transport-https nginx python-certbot-nginx</code></pre>
+ <p>Jitsi has its own package repository, so let's add it.</p>
+ <pre class=wide><code>curl https://download.jitsi.org/jitsi-key.gpg.key | gpg --dearmor &#62; /usr/share/keyrings/jitsi-keyring.gpg
+echo 'deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/' > /etc/apt/sources.list.d/jitsi-stable.list
+apt update -y</code></pre>
+ <p>
+ Ok. So now we can install Jitsi, but before we do that, let's the firewall <code>ufw</code>, in case you
+ have it enabled, and the SSL certificate.
+ </p>
+ <h2>Enable Required Ports</h2>
+ <p>If you are using <a href="ufw.html">ufw</a> or another firewall, there are several ports we need to ensure are open:</p>
+ <pre><code>ufw allow 80/tcp
+ufw allow 443/tcp
+ufw allow 10000/udp
+ufw allow 3478/udp
+ufw allow 5349/tcp
+ufw enable</code></pre>
+ <p>For your information, these allow the following:</p>
+ <ul>
+ <li>80 TCP &ndash; Certbot.</li>
+ <li>443 TCP &ndash; General access to Jitsi Meet.</li>
+ <li>10000 UDP &ndash; General network video/audio communications.</li>
+ <li>3478 UDP &ndash; Quering the stun server (coturn, optional, needs config.js change to enable it).</li>
+ <li>
+ 5349 TCP &ndash; Fallback network video/audio communications over TCP (when UDP is blocked for example), served by coturn.
+ </li>
+ </ul>
+ <h2>SSL certificate</h2>
+ <p>
+ I'll be using <a href="./certbot.html" target="blank">certbot</a> and
+ <a href="./nginx.html" target="blank">Nginx</a> to generate a certificate
+ for the Jitsi subdomain to allow encrypted connections.
+ </p>
+ <pre><code>certbot --nginx certonly -d <strong>meet.example.org</strong></code></pre>
+ <p>
+ We will not create an Nginx config file for Jitsi because the Jitsi package we will be installing will do that automatically.
+ </p>
+ <h2>Installation</h2>
+ <p>To begin the installation process, just run:</p>
+ <pre><code>apt install jitsi-meet</code></pre>
+ <p>
+ It will ask you for your <code><strong>hostname</strong></code
+ >; there you'll need to input the subdomain you have just added to Nginx, like
+ <code><strong>meet.example.org</strong></code>.
+ </p>
+ <p>For the SSL certificate, choose <code>I want to use my own certificate</code>.</p>
+ <p>
+ When it ask you for the certification key and cert files, input
+ <code>/etc/letsencrypt/live/<strong>meet.example.org</strong>/privkey.pem</code> and
+ <code>/etc/letsencrypt/live/<strong>meet.example.org</strong>/cert.pem</code> respectively.
+ </p>
+ <h2>Using Jitsi</h2>
+ <img src="pix/jitsi-01.webp" alt="Jitsi once installed">
+ <p>Jitsi can be used in a browser by then just going to <code>meet.example.org</code>.</p>
+ <p>Note that there are also Jitsi clients for all major platforms:</p>
+ <ul>
+ <li><a href="https://desktop.jitsi.org/Main/Download.html">Desktop</a> (Windows, MacOS, GNU/Linux)</li>
+ <li>Android (<a href="https://f-droid.org/en/packages/org.jitsi.meet/">F-Droid</a> and <a href="https://play.google.com/store/apps/details?id=org.jitsi.meet">Google Play</a>)</li>
+ <li><a href="https://apps.apple.com/us/app/jitsi-meet/id1165103905">iPhone/iOS</a></li>
+ </ul>
+ <p>
+ <strong>When using a Jitsti app for the first time, remember to go to the "Settings" menu and change your server name to the Jitsi site you just created.</strong>
+ </p>
+ <p>When you create a video chatroom, its address will appear as <code><strong>meet.example.org/yourvideochatname</strong></code> and can be shared as such.</p>
+ <h2>More info</h2>
+ <p>
+ This article is based on <a href="https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart" target="blank">the original documentation</a>. There you can find more details and configurations.
+ </p>
+ <ul>
+ <li>Written by <a href="https://josefabio.com" target="blank">Jose Fabio.</a> Donate Monero: <code class="crypto">484RLdsXQCDGSthNatGApRPTyqcCbM3PkM97axXezEuPZppimXmwWegiF3Et4BHBgjWR7sVXuEUoAeVNpBiVznhoDLqLV7j</code> <a href="https://josefabio.com/figures/monero.jpg" class="crypto" target="blank">[QR]</a></li>
+ <li>Edited and revised by <a href="https://lukesmith.xyz">Luke</a>.</li>
+ </ul>
+ </main>
+
+
+]]></description>
+</item>
+
+
+<item>
+<title>PeerTube Instance</title>
+<guid>https://landchad.net/peertube.html</guid>
+<link>https://landchad.net/peertube.html</link>
+<pubDate>Thu, 29 Jul 2021 10:44:56 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>PeerTube Instance</h1></header>
+
+ <main>
+ <img class=titleimg src="pix/peertube.svg" alt="PeerTube logo">
+ <p>PeerTube is a self-hosted and (optionally) federated video sharing platform that saves bandwith on videos the more people watch.
+ PeerTube instances can follow each other to share videos and grow the federated network,
+ but you can always keep your instance to yourself if you choose to.</p>
+ <h2>Prerequisites</h2>
+ <p><strong>Most</strong> of PeerTube's dependencies can be installed with this command:</p>
+ <pre><code>apt install -y curl sudo unzip vim ffmpeg postgresql postgresql-contrib g++ make redis-server git python-dev cron wget</code></pre>
+ <p>It's also important to start all associated daemons:</p>
+ <pre><code>systemctl start postgresql redis</code></pre>
+ <p>PeerTube also requires <strong>NodeJS 14</strong> and <strong>yarn</strong> which cannot be installed from the Debian repositories. This means they have to be installed from separate, external repos:</p>
+ <pre><code>curl -fsSL https://deb.nodesource.com/setup_14.x | bash -
+apt install -y nodejs
+npm install --global yarn</code></pre>
+ <p>In addition to these dependencies, it's recommended to create a dedicated PeerTube user to install and manage PeerTube.</p>
+ <pre><code>useradd -m -d /var/www/peertube -s /bin/bash -p peertube peertube</code></pre>
+ <h2>Database</h2>
+ <p>PeerTube requires a PostgreSQL database to function. To create it, first make a new Postgres user named PeerTube:</p>
+ <pre><code>su postgres
+createuser -P peertube
+createdb -O peertube -E UTF8 -T template0 peertube_prod
+psql -c "CREATE EXTENSION pg_trgm;" peertube_prod
+psql -c "CREATE EXTENSION unaccent;" peertube_prod
+exit</code></pre>
+ <p>Be sure to <strong>make note of your Postgres user password,</strong> as it will be needed later when setting up PeerTube.</p>
+ <h2>Installation</h2>
+ <p>This handy one-liner can be used to determine the latest PeerTube version:</p>
+ <pre><code>VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4) && echo "Latest Peertube version is $VERSION"</code></pre>
+ <p>Next, a basic directory structure needs to be setup in the PeerTube user's home directory (/var/www/peertube).</p>
+ <p>To ensure permissions remain the same while managing files as PeerTube, <code>sudo</code> can be used to perform actions:</p>
+ <pre><code>sudo -u peertube mkdir config storage versions
+sudo -u peertube chmod 750 config</code></pre>
+ <p>Finally, a PeerTube release can be downloaded from the GitHub page and installed using yarn:</p>
+ <pre><code>cd versions
+sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latest
+cd ./peertube-latest && sudo -H -u peertube yarn install --production --pure-lockfile</code></pre>
+ <h2>Configuration</h2>
+ <p>PeerTube's default config file can be copied over to <code>/var/www/peertube/config.production.yaml</code> so it can actually be used:</p>
+ <pre><code>cd /var/www/peertube
+ sudo -u peertube cp peertube-latest/production.yaml config/production.yaml</code></pre>
+ <p>Now the <code>production.yaml</code> file must be edited in the following ways:</p>
+ <p>First, add the hostname:</p>
+ <pre><code>webserver:
+ https: true
+ hostname: <strong>'example.org'</strong>
+ port: 443</code></pre>
+ <p>Then, the database:</p>
+ <pre><code>database:
+ hostname: 'localhost'
+ port: 5432
+ ssl: false
+ suffix: '_prod'
+ username: <strong>'peertube'</strong>
+ password: <strong>'your_password'</strong>
+ pool:
+ max: 5</code></pre>
+ <p>An email to generate the admin user:</p>
+ <pre><code>admin:
+ # Used to generate the root user at first startup
+ # And to receive emails from the contact form
+ email: <strong>'chad@example.org'</strong></code></pre>
+ <p>And <strong>optionally,</strong> email server information:</p>
+ <pre><code>smtp:
+ # smtp or sendmail
+ transport: smtp
+ # Path to sendmail command. Required if you use sendmail transport
+ sendmail: null
+ hostname: <strong>mail.example.org</strong>
+ port: 465 # If you use StartTLS: 587
+ username: <strong>your_email_username</strong>
+ password: <strong>your_email_password</strong>
+ tls: true # If you use StartTLS: false
+ disable_starttls: false
+ ca_file: null # Used for self signed certificates
+ from_address: <strong>'admin@example.org'</strong></code></pre>
+ <h2>NGINX</h2>
+ <p>PeerTube includes an NGINX configuration that can be copied over to <code>/etc/nginx/sites-available:</code>
+ <pre><code>cp /var/www/peertube/peertube-latest/support/nginx/peertube /etc/nginx/sites-available/peertube</code></pre>
+ <p>Because the PeerTube config is so long, it's recommended to use <code>sed</code> to modify the contents of the file,
+ replacing <code>${WEBSERVER_HOST}</code> with your hostname,
+ and <code>$(PEERTUBE_HOST)</code> with your localhost and port, which by default should be <code>127.0.0.1:9000</code>:
+ <pre><code>sed -i 's/${WEBSERVER_HOST}/<strong>example.org</strong>/g' /etc/nginx/sites-available/peertube
+sed -i 's/${PEERTUBE_HOST}/127.0.0.1:9000/g' /etc/nginx/sites-available/peertube</code></pre>
+ <p>Once you're happy with the NGINX config file, link it to <code>sites-enabled</code> to activate it:</p>
+ <pre><code>ln -s /etc/nginx/sites-available/peertube /etc/nginx/sites-enabled/peertube</code></pre>
+ <h3>Encryption with Certbot</h3>
+ <p>It's <strong>highly recommended</strong> to generate certificates for use with your PeerTube site, and this can be easily done with Let's Encrypt's <code>certbot</code> command:</p>
+ <pre><code>systemctl stop nginx
+certbot certonly --standalone -d <strong>example.org</strong>
+sudo systemctl restart nginx</code></pre>
+ <p>The certificates are generated <strong>standalone</strong> since the PeerTube NGINX config file already includes configuration for certbot.</p>
+ <h2>Running PeerTube</h2>
+ <p>A config file for a systemd daemon is included in PeerTube and can be setup like so:</p>
+ <pre><code>cp /var/www/peertube/peertube-latest/support/systemd/peertube.service /etc/systemd/system/
+systemctl daemon-reload</code></pre>
+ <p>Now, finally, run the PeerTube daemon to start PeerTube:</p>
+ <pre><code>systemctl start peertube</pre></code>
+ <h2>Using PeerTube</h2>
+ <p>To set a password for your admin user, run:</p>
+ <pre><code>cd /var/www/peertube/peertube-latest &amp;&amp; NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run reset-password -- -u root</code></pre>
+ <p>Login to your PeerTube instance using the admin email specified in your <code>production.yaml</code> file and the admin password you just set.</p>
+ <img src="pix/peertube-login.jpg" height=400px>
+ <p>Once logged in, it's recommended to create a separate user without admin privileges for uploading videos to PeerTube.
+ This can be done easily from the users tab in the administration section:</p>
+ <p>Enjoy your PeerTube instance!</p>
+ <hr>
+ <h2>Updating PeerTube</h2>
+ <p>PeerTube is constantly adding new features, so it's a good idea to <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md">check for new updates</a> and add them if you wish. Just in the past year, they have added livestreaming and more.</p>
+ <p>Updating is fairly easy now since an <code>upgrade.sh</code> script has been added. Just run:</p>
+ <pre><code>cd /var/www/peertube/peertube-latest/scripts &amp;&amp; sudo -H -u peertube ./upgrade.sh</code></pre>
+ <p>
+ Although check the <a href="https://github.com/Chocobozzz/PeerTube/blob/develop/CHANGELOG.md">changelog</a> to see if there are additional manual requirements for particular updates.
+ </p>
+ <hr>
+ <p><em>Written by <a href="https://denshi.live">Denshi.</a> Donate Monero <a href="https://denshi.live/donate.html">here</a> <a href="https://denshi.live/images/monero.png">[QR]</a></em></p>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Server-Side Scripting with CGI</title>
+<guid>https://landchad.net/cgi.html</guid>
+<link>https://landchad.net/cgi.html</link>
+<pubDate>Sun, 25 Jul 2021 14:29:44 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Server-Side Scripting with CGI</h1></header>
+
+ <main>
+ <p>
+ The basic website tutorial here describes how to set up a static
+ website &mdash; one that just serves HTML files saved on your server,
+ and until you change something manually, the same content will be served
+ each time a given page is requested. This is perfectly enough for most
+ personal website needs. This is how blogs should be implemented, instead
+ of relying on bloatware like WordPress!
+ </p>
+ <p>
+ But sometimes you genuinely <i>do</i> need something more. You need your
+ website to serve different contents depending on the time, on who the
+ requester is, on the contents of a database, or maybe process user input
+ from a form.
+ </p>
+ <h2>CGI</h2>
+ <p>
+ CGI, or the Common Gateway Interface, is a specification to allow you,
+ the server owner, to program your web server using pretty much any
+ programming language you might know. The specification is almost as old
+ as the Internet itself and for a long time CGI scripting was the primary
+ method of creating dynamic websites.
+ </p>
+ <p>
+ CGI is a very simple specification indeed. You write a script in your
+ favorite language, the script receives input about the request in
+ environment variables, and whatever you print to the standard output
+ will be the response. Most likely, though, you will want to use a
+ library for your language of choice that makes a lot of this
+ request/response handling simpler (e.g. parsing query parameters for
+ you, setting appropriate headers, etc.).
+ </p>
+ <h3>Limitations of CGI</h3>
+ <p>
+ While in theory you could implement any sort of functionality with CGI
+ scripts, it's going to get difficult managing a lot of separate scripts
+ if they're supposed to be working in tandem to implement a dynamic
+ website. If you want to build a full out web application, you'd probably
+ be better off learning a web framework than gluing together Perl
+ scripts.
+ </p>
+ <p>
+ That said, just as most of the web could be replaced with static
+ websites, much of the remaining non-static web could be replaced with a
+ few simple scripts, rather than bloated Ruby on Rails or Django
+ applications.
+ </p>
+ <h2>Let's write a CGI script!</h2>
+ <p>
+ We'll implement a simple example CGI script. I'll use Ruby for this
+ tutorial, but you'll be able to follow along even if you don't know
+ Ruby, just treat it as pseudocode then find a CGI library for your
+ language.
+ </p>
+ <h3>The working example</h3>
+ <p>
+ Our working example will be the Lazy Calculator. Yeah, you're probably
+ tired of seeing calculator examples in every programming tutorial, but
+ have you ever implemented one that takes the weekends off?
+ </p>
+ <p>
+ Here's how it will work. When in a browser you submit a request to your
+ website like
+ </p>
+ <pre><code>example.com/calculator.html?a=10&amp;b=32</code></pre>
+ <p>
+ you will receive a page with the result of the addition of 10 and 32:
+ 42.
+ </p>
+ <p>
+ <i>Unless</i> you send your request on a weekend. Then the website will
+ respond with
+ </p>
+ <pre><code>I don't get paid to work on weekends! Come back Monday.</code></pre>
+ <p>
+ This example will show a few things that CGI scripts can do that you
+ wouldn't have been able to get using just file hosting in your
+ web server:
+ <ul>
+ <li> getting inputs from the user; </li>
+ <li>
+ getting external information (here just the system time, but you
+ could imagine instead connecting to a database);
+ </li>
+ <li> using the above to create dynamic output. </li>
+ </ul>
+ <h3>The code</h3>
+ <p>
+ Here's an implementation of the lazy calculator as a Ruby CGI script:
+ </p>
+ <pre><code>#!/bin/env ruby
+require 'cgi'
+require 'date'
+cgi = CGI.new
+today = Date::today
+a = cgi["a"].to_i
+b = cgi["b"].to_i
+if today.saturday? || today.sunday?
+ cgi.out do
+ "I don't get paid to work on weekends! Come back Monday."
+ end
+else
+ cgi.out do
+ (a + b).to_s
+ end
+end</code></pre>
+ <p>
+ Let's go through what's happening here.
+ </p>
+ <h3>The shebang line</h3>
+ <p>
+ CGI works by pointing your web server to an executable program. A Ruby
+ or Python script by itself is not immediately executable by a computer.
+ But on Unix-like systems you can specify the program that will be able
+ to execute your file in its first line if it starts with <code>#!</code>
+ (known as the shebang; read more about it on
+ <a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">Wikipedia</a>).
+ </p>
+ <p>
+ So if you're going to be using a scripting language, you'll probably
+ need the appropriate shebang line at the top of your script. If you use
+ a compiled language, you'll just point your web server to the compiled
+ executable binary.
+ </p>
+ <h3>Query parameters</h3>
+ <p>
+ The next interesting lines of code are where we set the variables
+ <code>a</code> and <code>b</code>. Here we are getting user inputs from
+ the request.
+ </p>
+ <p>
+ In the example request we mentioned above
+ (<code>example.com/calculator.html?a=10&amp;b=32</code>), the part
+ starting from the question mark, <code>?a=10&amp;b=32</code>, is the
+ <i>query string</i>. This is how users can submit parameters with their
+ web requests. Usually these parameters are set by e.g. a form on your
+ website, but in our simple example we'll be just manually manipulating
+ the URL.
+ </p>
+ <p>
+ The query string contains key-value pairs. The Ruby CGI library makes
+ them available in the <code>CGI</code> object it provides. We just need
+ to index it with the desired key, and we'll get the corresponding value.
+ </p>
+ <h3>Wrapping it up</h3>
+ <p>
+ The remaining parts of the code should be pretty self-explanatory. We
+ get today's date, check if it's a Saturday or a Sunday, and depending on
+ that, we instruct the CGI library to output either the answer, or a
+ "come back later" message.
+ </p>
+ <p>
+ The Ruby library by default returns an HTML response, so we really
+ should have wrapped our outputs in some <code>html</code>,
+ <code>body</code>, etc. tags. Alternatively, we could have specified
+ that the response is just plain text with
+ </p>
+ <pre><code>cgi.out 'text/plain' do</code></pre>
+ <p>
+ In general, your CGI library will probably have ways of specifying all
+ sorts of HTTP response headers, like status code, content type, etc.
+ </p>
+ <h2>Making it work</h2>
+ <p>
+ We have a CGI script, now let's point our web server to it.
+ </p>
+ <h3>Installing FastCGI</h3>
+ <p>
+ If you're using Nginx, install <code>fcgiwrap</code>:
+ </p>
+ <pre><code>apt install fcgiwrap</code></pre>
+ <p>
+ This installs the necessary packages for Nginx to use FastCGI &mdash; a
+ layer between your web server and CGI script that allows for faster
+ handling of scripts than if the web server had to handle it all by
+ itself.
+ </p>
+ <p>
+ Other web servers will probably have a similarly simple way of enabling
+ FastCGI, or you can look into other methods for launching CGI scripts.
+ </p>
+ <h3>Nginx configuration</h3>
+ <p>
+ In the configuration file for your website, add something like the
+ following:
+ </p>
+<pre><code>location /calculator.html {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME /usr/local/bin/lazy-calculator.rb;
+ fastcgi_param QUERY_STRING $query_string;
+ fastcgi_pass unix:/run/fcgiwrap.socket;
+}</code></pre>
+ <p>
+ <code>fastcgi_param</code> directives specify various parameters for
+ FastCGI. <code>SCRIPT_FILENAME</code> should point to your executable.
+ For <code>QUERY_STRING</code>, we just copy Nginx's
+ <code>$query_string</code> variable. You might want to pass other
+ information to your CGI script as well, see for example
+ <a href="https://wiki.debian.org/nginx/FastCGI">the Debian wiki</a> for
+ a more detailed example, including pointing to an entire directory of
+ CGI scripts, rather than adding each one by hand to your web server
+ config.
+ </p>
+ <h2>Contribution</h2>
+ <ul>
+ <li>Martin Chrzanowski -- <a href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/donate.html">donate</a></li>
+ </ul>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>XMPP Server (Prosody)</title>
+<guid>https://landchad.net/xmpp.html</guid>
+<link>https://landchad.net/xmpp.html</link>
+<pubDate>Wed, 21 Jul 2021 22:58:21 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>XMPP Server (Prosody)</h1></header>
+
+ <main>
+ <img class=titleimg src="pix/xmpp.svg" alt="XMPP Logo and Icon">
+ <p>XMPP is a fantastically simple protocol that's usually used as a messenger.
+ It's highly extensible,
+ better than IRC,
+ lighter and more decentralized and Matrix
+ and Telegram and normie social media can't hold a candle to it.
+ </p>
+ <p>
+ XMPP is so decentralized and extensible that there are many <em>different</em> XMPP servers.
+ Here, let's set up an <a href="https://prosody.im/">Prosody</a> XMPP server.
+ </p>
+ <h2>Installation</h2>
+ <p>
+ Prosody is in the Debian repositories, so we can easily install it on our server with the following command:
+ </p>
+ <pre><code>apt install prosody</code></pre>
+<h2>Configuration</h2>
+<p>
+The Prosody configuration file is in <code>/etc/prosody/prosody.cfg.lua</code>.
+To set it all up, we will be changing several things.
+</p>
+<h3>Setting Admins</h3>
+<p>
+Let's go ahead and set who our admin(s) will be.
+Find the line that says <code>admins = { }</code> and to this we can specify one or more server admins.
+</p>
+<pre><code># To add one admin:
+admins = { "chad@example.org" }
+# We can add more than one by separating them by commas. (This file is written in Lua.)
+admins = { "chad@example.org", "chadmin@example.org" }</code></pre>
+<p>
+Note that we have not created these accounts yet, we will do this <a href=#user>below</a>.
+</p>
+<h3>Set the Server URL</h3>
+<p>
+Find the line <code>VirtualHost "localhost"</code> and replace <code>localhost</code> with your domain.
+In our case, we will have <code>VirtualHost "example.org"</code>
+</p>
+<h3>Multi-User Chats</h3>
+<p>
+Most people will probably want the ability to have chats with more than two users.
+This is easily enough to enable.
+In the config file, add the following:
+</p>
+<pre><code>Component "<strong>chat.example.org</strong>" "muc"
+ modules_enabled = { "muc_mam" }
+ restrict_room_creation = "admin"</code></pre>
+<p>
+On the first line, you must have a separate subdomain for your multi-user chats.
+I use the <code>chat.</code> subdomain, but some use <code>muc.</code>.
+Anything if possible.
+</p>
+<p>
+The second line is important because it prevents non-admins from creating and squatting rooms on your server.
+The only situation where you might not want that is if you indend to open a general public chat system for people you don't know.
+</p>
+<aside>
+<p>
+Read more about the <code>muc</code> plugin on the Prosody documentation page <a href="https://prosody.im/doc/modules/mod_muc">here</a>.
+</p>
+</aside>
+<h3>End-to-end Encryption</h3>
+<p>
+Importantly, we'll want end-to-end encryption enabled for user privacy.
+</p>
+<p>
+Find the array beginning with <code>modules_enabled</code>.
+This includes a list of modules to be used.
+Add
+<code>"omemo_all_access";</code> to that list.
+Additionally, be sure to change the module <code>pep</code> to <code>pep_simple</code> or this will cause a conflict.</p>
+<p>
+This module is not installed by default,
+but you can easily download it by running the following command on the command prompt
+to download and install the module to the correct directory.
+</p>
+<pre class=wide><code>curl -sL https://hg.prosody.im/prosody-modules/raw-file/785389a2d2b3/mod_omemo_all_access/mod_omemo_all_access.lua &gt; /usr/lib/prosody/modules/mod_omemo_all_access.lua</code></pre>
+<h3>Other things to check</h3>
+<p>Check the config file for other settings you might want to change.
+For example, if you want to run a general public XMPP server, you can allow anyone to create an account by changing <code>allow_registration</code> to <code>true</code>.
+</p>
+<h2>Certificates</h2>
+<p>
+Obviously, we want to have client-to-server and server-to-server encryption.
+Nowadays, use can use Certbot to generate certificates and use a convenient command below <code>prosodyctl</code> to import them.
+</p>
+<p>
+<strong>If you have multi-user chat enabled, be sure to get a certificate for that subdomain as well.</strong>
+Include the <code>--nginx</code> option assuming you have an Nginx server running.
+</p>
+<pre><code>certbot -d <strong>chat.example.org</strong> --nginx</code></pre>
+<p>
+Once you have the certificates for encryption, run the following to import them into Prosody.
+</p>
+<pre><code>prosodyctl --root cert import /etc/letsencrypt/live/</code></pre>
+<p>
+Note that you might get an error that a certificate has not been found if your <code>muc</code> subdomain and your main domain share a certificate.
+It should still work, this is just notifying you that no specific
+</p>
+<p>
+For user privacy, we will definitely want to install and enable encryption with OMEMO.
+</p>
+<h2 id=user>Creating users/admins manually</h2>
+<p>
+Let's manually create the admin user we prepared for above.
+Note that you can indeed do this in your XMPP client if you have not disabled registration, but this is how it is done on the command line:
+</p>
+<pre><code>prosodyctl adduser <strong>chad@example.org</strong></code></pre>
+<p>This will prompt you to create a password as well.</p>
+<h2>Make changes active</h2>
+<p>
+With any system service, use <code>systemctl reload</code> or <code>systemctl restart</code> to make the new settings active:
+</p>
+<pre><code>systemctl restart prosody</code></pre>
+<h2>Using your Server!</h2>
+<p>
+Once your server is set up, you just need an XMPP client to use your new and secure chat system.
+</p>
+<ul>
+ <li>GNU/Linux: <a href="https://dino.im/">Dino</a> or <a href="https://gajim.org/">Gajim</a></li>
+ <li>Windows: <a href="https://gajim.org/">Gajim</a> also runs on Windows.</li>
+ <li>Android: <a href="https://conversations.im/">Conversations.im</a></li>
+ <li>Mac/iOS: <a href="https://monal.im/">Monal IM</a> or <a href="https://siskin.im/">Siskin</a> for iOS alone</li>
+ <li>command-line (GNU/Linux, MacOS, Windows): <a href="https://profanity-im.github.io/">Profanity</a></li>
+ <li><a href="https://xmpp.org/software/clients.html">See a more complete list kept by XMPP</a></li>
+</ul>
+<p>
+Install whichever of these clients you want on your computer or phone and you can log into your new XMPP server with the account you made.
+Note that if you enabled public registration, anyone can create an account on your server through one of these clients.
+</p>
+<h3>Account addresses</h3>
+<p>
+XMPP account addressed look just like email addresses: <code><strong>username@example.org</strong></code>.
+You can message any account on any XMPP server on the internet with that format.
+</p>
+<h3>Note on MUCs (multi-user chats)</h3>
+<p>
+Remember that MUCs are kept on a separate subdomain that we created and should've gotten a certificate for above, for example, <code><strong>muc.example.org</strong></code>.
+Chatrooms are created and referred to in the following format: <code><strong>#chatroomname@muc.example.org</strong></code>.
+</p>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Setting up RSS Bridge</title>
+<guid>https://landchad.net/rss-bridge.html</guid>
+<link>https://landchad.net/rss-bridge.html</link>
+<pubDate>Mon, 05 Jul 2021 18:11:15 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Setting up RSS Bridge</h1></header>
+
+ <main>
+ <p>RSS Bridge is a useful utility you can use to help you avoid the big tech sites, like Facebook and Twitter, which instead of the feed you usually would see, will be a based and minimalist RSS feed. </p>
+ <p>You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address <a href="https://landchad.net/dns.html">which is explained in this tutorial.</a>
+ </p>
+<h2>Installation</h2>
+<h3>Setting Up and Configuring</h3>
+<p>First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban.
+There's a great tutorial on how to do this <a href="https://landchad.net/sshkeys.html">which can be read here.</a>
+</p>
+<p>
+Next we'll install the required packages:
+</p>
+<pre><code>apt install -y curl unzip nginx certbot php-fpm php-mysql php-cli php7.3-mbstring php7.3-curl php7.3-xml php7.3-sqlite3 php7.3-json</code></pre>
+<p>We now have to create the website configuration file. Create/open the a file below:</p>
+<pre><code>nano /etc/nginx/sites-available/rss-bridge</code></pre>
+<p>And add the following content:</p>
+<pre><code>server {
+ root /var/www/rss-bridge;
+ index index.php index.html index.htm index.nginx-debian.html;
+ server_name rss-bridge.<strong>example.org</strong>;
+ location / {
+ try_files $uri $uri/ =404;
+ }
+ location ~ \.php$ {
+ include snippets/fastcgi-php.conf;
+ fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
+ }
+ location ~ /\.ht {
+ deny all;
+ }
+}
+</code></pre>
+<p>After you have saved the file, you need to create a symlink so the server actually will read the file.</p>
+<pre><code>ln -s /etc/nginx/sites-available/rss-bridge /etc/nginx/sites-enabled/rss-bridge</code></pre>
+<p>Then we have to create the folder where the service will reside in.</p>
+<pre><code>mkdir -p /var/www/rss-bridge
+cd /var/www/rss-bridge
+</code></pre>
+<p>Lets download the latest version of RSS-Bridge in the directory.</p>
+<p>The newest version can be found <a href="https://github.com/RSS-Bridge/rss-bridge/releases">here</a>, at the time of writing that is "RSS-Bridge 2021-04-25."</p>
+ <pre><code>wget https://github.com/RSS-Bridge/rss-bridge/archive/refs/tags/<strong>2021-04-25.zip</strong></code></pre>
+<p>Unzip the file:</p>
+<pre><code>unzip <strong>2021-04-25.zip</strong></code></pre>
+<p>This will create a directory called rss-bridge-version-number, we now want to move all the file contents of the newly created directory to the one we are in</p>
+<pre><code>mv <strong>rss-bridge-2021-04-25</strong>/* .
+rm -rf <strong>rss-bridge-2021-04-25 2021-04-25.zip</strong>
+</code></pre>
+<p>Now all we need to do is grant read/write permissions and reload the web server.</p>
+<pre><code>chown -R www-data:www-data /var/www/rss-bridge
+systemctl reload nginx
+</code></pre>
+<p>That's it, you should now have a working rss-bridge installed. But you should definately get an SSL certifcate installed <a href="https://landchad.net/certbot.html">which is done briefly here</a>.</p>
+<ul>
+ <li><a href="https://handskemager.xyz">handskemager.xyz</a></li>
+ <li>Bitcoin: <code class=crypto>bc1qhfjgwjzksf2auqjefwpvq20wvyugq3lhqgkxvu</code></li>
+ <li>Monero: <code class=crypto>88cPx6Gzv5RWRRJLstUt6hACF1BRKPp1RMka1ukyu2iuHT7iqzkNfMogYq3YdDAC8AAYRqmqQMkCgBXiwdD5Dvqw3LsPGLU</code></li>
+</ul>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Rsync: Upload and Sync Files and Websites</title>
+<guid>https://landchad.net/rsync.html</guid>
+<link>https://landchad.net/rsync.html</link>
+<pubDate>Sat, 03 Jul 2021 08:58:29 -0400</pubDate>
+<description><![CDATA[
+<header><h1>Rsync: Upload and Sync Files and Websites</h1></header>
+<main>
+ <p>rsync is a simple way to copy files and folders between your local computer and server.</p>
+ <p>It not only makes file-transfer easy, but it allows you to build and maintain your website offline, then easily upload it to the proper directory on your server so you don't need to constantly be logged into your server to modify your site.</p>
+<h2 id="installing-rsync">Installing rsync</h2>
+<p>Run the following on your server <em>and</em> on your local machine.</p>
+<pre><code>apt install rsync</code></pre>
+<h2 id="uploading-files-with-rsync">Uploading files with rsync</h2>
+<p>From your local machine you can upload files to your server like this:</p>
+<pre><code>rsync -ruvzP <strong>/path/to/file</strong> <strong>root@example.org:/path/on/the/server</strong></code></pre>
+<p>You will be prompted for the root password and then uploading will commence.</p>
+<p>If you omit <strong>root@</strong>, rsync will not attempt to log in as root, but whatever your local username is.</p>
+<h3>Options to rsync</h3>
+<p>In this command, we give several options to rsync:</p>
+<ul>
+ <li><code>-r</code> &ndash; run recurssively (include directories)</li>
+ <li><code>-u</code> &ndash; update files (do not reupload files that are not changed since last upload)</li>
+ <li><code>-v</code> &ndash; visual, show files uploaded</li>
+ <li><code>-z</code> &ndash; compress files for upload</li>
+ <li><code>-P</code> &ndash; if uploading a large file and upload breaks, pick up where we left off rather than reuploading the entire file</li>
+</ul>
+<p>Avoid using the commonly used <code>-a</code> option when uploading. It changes can transfer your local machine's user and group permissions to your server, which might cause breakage.</p>
+<h3>Scriptability</h3>
+<p>It's a good idea to build your website offline, then make an rsync script or bash alias like the one above to upload the edited files when you have made updates.</p>
+<h3>Password-less authentication</h3>
+<p>To avoid having to manually input your password each upload, you can set up <a href="sshkeys.html">SSH keys</a> to securely idenitify yourself and computer as a trusted.</p>
+<h3>Picky trailing slashes</h3>
+<p>rsync is very particular about trailing slashes. This is useful, but can be confusing to some new users. Suppose we run the following wanting to mirror our offline copy of our website in the directory we use on our server (<code>/var/www/websitefiles/</code>):</p>
+<pre><code>rsync -ruvzP ~/<strong>websitefiles/</strong> root@example.org:/var/www/<strong>websitefiles/</strong></code></pre>
+<p>This will <em>not actually do quite what we want</em>. It will take our local <code>websitefiles</code> directory and put it <em>inside</em> <code>websitefiles</code> on the remote machine, ending up with: <code>/var/www/websitefiles/websitefiles</code>.</p>
+<p>Instead, remove the trailing slash from the remote server location:</p>
+<pre><code>rsync -ruvzP ~/<strong>websitefiles/</strong> root@example.org:/var/www/<strong>websitefiles</strong></code></pre>
+<p><code>websitefiles/</code> has been replaced with <code>websitefiles</code>, and this will do what we want.</p>
+<h2 id="downloading-file-with-rsync">Downloading files with rsync</h2>
+<p>You may just as easily download files and directories from your server with rsync:</p>
+<pre><code>rsync -urvzP <strong>root@example.org:/path/to/file</strong> <strong>/path/to/file</strong></code></pre>
+<h2 id="contribution">Contribution</h2>
+<ul><li>el3ctr0lyte: <a href="https://github.com/el3ctr0lyte">github</a>, XMR: <code class=crypto>86DBJdiG83ZDea6kJgsbVN5tMae5ScfuhJ3PihEMTHatCrGEw2gctyUB92V2fz4R4YhwRaQeAGL5M4gPRXvVvtkULJi4ayk</code></li><li>Substantial revisions by <a href="https://lukesmith.xyz">Luke</a></li></ul>
+</main>
+]]></description>
+</item>
+
+
+<item>
+<title>Setup a Pleroma Server</title>
+<guid>https://landchad.net/pleroma.html</guid>
+<link>https://landchad.net/pleroma.html</link>
+<pubDate>Fri, 02 Jul 2021 09:14:32 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Setup a Pleroma Server</h1></header>
+
+ <main>
+ <p>Hopefully by now you won't have to be sold on the invasive practices that social media companies conduct. Websites such as Facebook and Twitter aquire so much data on users that they often know more about you than you know about yourself.
+The simple solution to this is to not use social media. However, that just isn't an option for most people. So the next best thing is to setup a self-hosted and federalised social media site so that you have full control over your data.
+I've previously made<a href="https://www.youtube.com/watch?v=l7mVsLSsotU"> a video showing all the steps in depth if you want to check it out.</a> If you run into any issues I suggest you look at the video.
+</p>
+ <p>You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address <a href="https://landchad.net/dns.html">which is explained in this tutorial.</a>
+ </p>
+<h2>Installation</h2>
+<h3>Setting Up and Configuring</h3>
+<p>First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban.
+There's a great tutorial on how to do this <a href="https://landchad.net/sshkeys.html">which can be read here.</a>
+</p>
+<p>
+Next we'll install the required packages:
+</p>
+<pre><code>apt install -y curl unzip libncurses5 postgresql postgresql-contrib nginx certbot libmagic-dev</code></pre>
+<p>
+You can manually configure postgreSQL to suit your system better. <a href="https://docs-develop.pleroma.social/backend/configuration/postgresql/">Check out the documentation here</a> and then run the below command:
+</p>
+<pre><code>systemctl restart postgresql</code></pre>
+<h3>Installing the Pleroma App</h3>
+<h4>First as the root user</h4>
+<p>
+Pleroma is not in the Debian app repositories, so we will install it manually.
+First create the Pleroma user by running the below command:
+</p>
+<pre><code>useradd -m -s /bin/bash -d /opt/pleroma pleroma</code></pre>
+<p>
+Then, still as root, we will create the required directories and give the Pleroma user ownership of them.
+</p>
+<pre><code>mkdir -p /var/lib/pleroma/uploads
+chown -R pleroma /var/lib/pleroma
+mkdir -p /var/lib/pleroma/static
+chown -R pleroma /var/lib/pleroma
+mkdir -p /etc/pleroma
+chown -R pleroma /etc/pleroma</code></pre>
+<h4>Now, as the new Pleroma user</h4>
+<p>
+Now run <code>su -l pleroma</code> to login as the Pleroma user.
+Now use the <code>curl</code> command below to download the Pleroma software and unzip it.
+</p>
+<pre><code>curl 'https://git.pleroma.social/api/v4/projects/2/jobs/artifacts/stable/download?job=<strong>amd64</strong>' -o /tmp/pleroma.zip
+unzip /tmp/pleroma.zip -d /tmp/</code></pre>
+<aside><p>Note that we are downloading the <strong>amd64</strong> version here. If you know you have a different CPU architecture, replace that with whatever your architecture is.</p></aside>
+<pre><code>mv /tmp/release/* /opt/pleroma
+rmdir /tmp/release
+rm /tmp/pleroma.zip
+./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql</code></pre>
+<p>We need to briefly return to the root user so we can run the following command (via the postgres user) to set up the database.
+Type <code>ctrl-d</code> or run <code>exit</code> to return to the root user, then run:
+</p>
+<pre><code>su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"</code></pre>
+<p>Then return to the pleroma user with <code>su -l pleroma</code> and we will test to see that Pleroma can run:</p>
+<pre><code>./bin/pleroma_ctl migrate
+./bin/pleroma daemon</code></pre>
+<p>
+That will initialize Pleroma. It might take as long as a minute to get started, so wait a bit, then run the following:
+</p>
+<pre><code>curl http://localhost:4000/api/v1/instance</code></pre>
+<p>If everything is working, this command will give you a long line of messy output. If it is not, you will get a connection error message.
+Once it is working successfully, stop the Pleroma daemon and we will interface Pleroma with the web server.</p>
+<pre><code>./bin/pleroma stop</code></pre>
+<h3>Setup and Configure Nginx</h3>
+<p>
+Return again to the root user. Let's copy Pleroma's Nginx configuration file from the template given in the installation and enable it:
+</p>
+<pre><code>cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.conf
+ln -s /etc/nginx/sites-available/pleroma.conf /etc/nginx/sites-enabled/pleroma.conf</code></pre>
+<p>Edit the <code>etc/nginx/sites-available/pleroma.conf</code> file and replace <strong>example.tld</strong> with your domain name.</p>
+<p>
+We now have to get a SSL certificate to enable encryption, since we have a model configuration that already includes SSL information,
+just check the brief <a href="standalone.html">the standalone certificate page</a> to get the needed certificate.
+Once you've got your cert setup, copy over the Nginx configuration with the below command:
+</p>
+<p>
+Once everything, including your Cerbot certificate is ready, simply reload Nginx with this command:
+</p>
+<pre><code>systemctl reload nginx</code></pre>
+<h3>Setting up the service</h3>
+<p>
+Pleroma itself runs on a SystemD service similar to other things running on your server like Nginx. To start the service up run the below commands:
+</p>
+<pre><code>cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service
+systemctl start pleroma
+systemctl enable pleroma</code></pre>
+<p>
+If everything worked then when you go to your domain in the web browser you should see a bare-bones Pleroma instance.
+</p>
+<h3>Creating an Admin User</h3>
+<p>You'll be able to create new accounts on the Pleroma instance in the login section on the website but the easiest way to setup an admin account is with the CLI. Simply run the below command replaced with your username:
+</p>
+<pre><code>su -l pleroma
+./bin/pleroma_ctl user new <strong>username</strong> <strong>username</strong>@<strong>example.org</strong> --admin</code></pre>
+<p>
+If you run into any issues then <a href="https://docs-develop.pleroma.social/backend/installation/otp_en/">feel free to checkout the documentation</a> or send me an email or message. My details are below.
+</p>
+<ul>
+ <li><a href="https://biasedriot.co">biasedriot.co</a></li>
+ <li><a href="https://www.youtube.com/channel/UCehh50T6qtDpt_kEUF33GJw">youtube</a></li>
+ <li>Bitcoin: <code class=crypto>1Dmn9jEtWAhdLk1HHWkUVNeDdAaBCwNajm</code></li>
+ <li>Monero: <code>84Y4FZiTbLeR5qc1fBrBhB1yq5agKtEdoixq2w1ysXJv486MiBCz3czGT15bqeXDPpdLoNyF93inxY3BCk6g8mrDMNKoArS</code></li>
+</ul>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Certbot on Standalone Domains and Subdomains</title>
+<guid>https://landchad.net/standalone.html</guid>
+<link>https://landchad.net/standalone.html</link>
+<pubDate>Fri, 02 Jul 2021 09:14:29 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Certbot on Standalone Domains and Subdomains</h1></header>
+
+ <main>
+ <p>The command <code>certbot --nginx</code> will take an unencrypted website on an Nginx configuration file, get a certificate for it and change the configuration to use that certificate and thus HTTPS.</p>
+ <p>Sometimes, however, you are given an Nginx configuration template that already has encryption/HTTPS, so running the automated <code>certbot --nginx</code> is not possible, as it will simply give an error saying that the certicate that Nginx is looking for doesn't already exist and thus the Nginx config is broken.</p>
+ <p>So suppose you want to get a certificate for <strong>pleroma.example.org</strong> because you are installing Pleroma and the configuration file presupposes a certificate.
+ In this case you would want to run this:</p>
+ <pre><code>systemctl stop nginx
+certbot certonly --standalone -d <strong>pleroma.example.org</strong>
+systemctl start nginx</code></pre>
+ <p>What we do here is temporarily turn of Nginx, then run a <code>certonly</code> subcommand that generates a certificate for the domain without changing or caring about the Nginx configuration. Then we reactivate Nginx, thus turning back on our webserver.</p>
+ <p>The reason we deactivate Nginx is that it uses the ports that Certbot will want to bind to, and thus we must temporarily turn Nginx off to let Certbot use those ports. (What it actually does is spin up a dummy webserver that doesn't need to think about the Nginx configuration.)</p>
+ <p>This is just a little note of something that might confuse people, but the three commands above should suffice. If your site is still managed by Nginx, it should still be able to renew with simple <code>certbot renew --nginx</code> without a problem.</p>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Using UFW as a Firewall</title>
+<guid>https://landchad.net/ufw.html</guid>
+<link>https://landchad.net/ufw.html</link>
+<pubDate>Thu, 01 Jul 2021 16:58:11 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Using UFW as a Firewall</h1></header>
+
+ <main>
+ <p>
+ <strong>Uncomplicated Firewall</strong> (UFW) is a front-facing program for the more involved <code>iptables</code> firewall program installed in most GNU/Linux distributions.
+ We can use <code>ufw</code> to restrict machines on the internet to only access the services (SSH, websites etc) you want them to, but it can also be used to prevent programs on the computer itself from accesing parts of the internet it shouldn't.
+ </p>
+ <h2 id="how-to-get-it">How to Get It</h2>
+ <p>Log into your server by pulling up a terminal and typing:</p>
+ <pre><code>ssh root@<strong>example.org</strong></code></pre>
+ <p>
+ This command will attempt to log into your server and run a remote shell.
+ If you leave the settings default, it should prompt you for your password, and you can just copy or type in the password from Vultr's site.
+ </p>
+ <p>
+ Some VPS providers automatically install <code>ufw</code>, but if you do not have it installed already, install it in the typical way:
+ </p>
+ <pre><code>apt install ufw</code></pre>
+ <h2 id="first-time-setup">First-Time Setup</h2>
+ <p>You can check the status of <code>ufw</code> right now by running:</p>
+ <pre><code>ufw status</code></pre>
+ <p>Without any changes, it should report back <code>Status: inactive</code>. Let's set it up so that only connections to SSH (standardized at port 22) are allowed in, and then enable the firewall:</p>
+ <aside>
+ <strong>Careful!</strong> Enabling <code>ufw</code> without allowing SSH will block you from remoting to your server.
+ Double-check that you have allowed SSH, and if you have changed the default SSH port, put in <em>that</em> number instead.
+ </aside>
+ <pre><code>ufw default deny incoming # block all incoming connections by default
+ufw allow in ssh # or: ufw allow in 22
+ufw enable</code></pre>
+ <aside>
+ <code>ufw</code> has an internal list of protocols applications, and the ports used by them.
+ In this case, it knwos SSH is on port 22.
+ We'll go more in detail how to view all protocols <code>ufw</code> knows about.
+ By default, when you allow an incoming port, it allows that port both on IPv4 and IPv6.
+ </aside>
+ <p>
+ With the firewall enabled and allowing only SSH in, all other ports are prortected from incoming requests.
+ To view all your rules, run:
+ </p>
+ <pre><code>ufw status verbose</code></pre>
+ <p>A firewall that allows to connect to SSH and their website may look like:</p>
+ <pre><code>Status: active
+Logging: on (low)
+Default: deny (incoming), allow (outgoing), deny (routed)
+New profiles: skip
+To Action From
+-- ------ ----
+22 (SSH) ALLOW IN Anywhere
+80,443/tcp (WWW Full) ALLOW IN Anywhere
+22 (SSH (v6)) ALLOW IN Anywhere (v6)
+80,443/tcp (WWW Full (v6)) ALLOW IN Anywhere (v6)</code></pre>
+ <p>If you want to delete e.g. the 'WWW Full' rule, run:</p>
+ <pre><code>ufw delete allow in 'WWW Full'
+ufw reload</pre></code>
+ <h2 id="enabling-common-services">Enabling Common Services</h2>
+ <p>
+ You have blocked all incoming ports but SSH, which means no outsiders would be able to access other services, like an email server or your website.
+ You should look at the ports your services are open on and enable them individually.
+ Here is a list of a few common services:
+ </p>
+ <h3>Opening Port Numbers</h3>
+ <p>Suppose you install <a href="gemini.html">a Gemini server</a>, which must broadcast on port 1965. By default <code>ufw</code> blocks all incoming connections on all ports, so whenever you install a new service like this you will have to tell <code>ufw</code> to enable the desired port:</p>
+ <pre><code>ufw allow 1985</code></pre>
+ <h3>Websites: HTTP and HTTPS</h3>
+ <p>HTTP uses port 80 and HTTPS uses port 443. We can enable them like this:</p>
+ <pre><code>ufw allow 80
+ufw allow 443</code></pre>
+ <p>But <code>ufw</code> additionally knows the typical ports of common serives, so you can also run this:</p>
+ <pre><code>ufw allow http
+ufw allow https</code></pre>
+ <p>And that will do the same thing. There are also other abbreviations for common port lists:</p>
+ <pre><code>ufw allow in 'WWW Full'</code></pre>
+ <p>To see these other "apps" that <code>ufw</code> knows by default, run <code>ufw app list</code></p>
+ <h3>Email: IMAP, POP3, and SMTP</h3>
+ <pre><code>ufw allow in IMAPS
+ufw allow in POP3
+ufw allow in SMTP
+ufw allow in 'Postfix SMTPS'
+ufw allow in 'Mail Submission'</pre></code>
+ <h2 id="fine-tuning-rules">Fine-Tuning Rules</h2>
+ <p>Instead of denying all ports by default, you may want to deny (ignores incoming requests) or reject (explicitly tells requests they're not allowed):</p>
+ <pre><code>ufw default allow in
+ufw deny in <strong>PORT</strong>
+ufw reject in <strong>PORT</strong>
+ufw reload</code></pre>
+ <p>You can add rules to comments to remember what they are there for:</p>
+ <pre><code>ufw allow in <strong>PORT</strong> comment 'Secret SSH'
+ufw reload
+ufw status verbose</code></pre>
+ <p>Output:</p>
+ <pre><code>To Action From
+-- ------ ----
+<strong>PORT</strong> ALLOW IN Anywhere # Secret SSH
+<strong>PORT</strong> (v6) ALLOW IN Anywhere (v6) # Secret SSH</pre></code>
+ <p>To deny outgoing ports:</p>
+ <pre><code>ufw deny out <strong>PORT</strong></code></pre>
+ <p>Ratelimiting is useful to protect against brute-force login attacks, like in SSH. Only IPv4 is supported for now. Enable it by running:</p>
+ <pre><code>ufw limit <strong>PORT</strong>/tcp</code></pre>
+ <p>To blocklist IP addresses:</p>
+ <pre><code>ufw deny from <strong>IP_ADDRESS</strong></code></pre>
+ <p>To read more what you can do with <code>ufw</code>, run:</p>
+ <pre><code>man ufw</code></pre>
+ <h2 id="recovering-from-losing-ssh">Recovering SSH</h2>
+ <p>
+ If you have accidentally firewalled yourself from logging on your computer, you can recover access by using your VPS's virtual console.
+ On Vultr, this is on your VPS's menu. To the right of the server name, It is the leftmost icon that looks like a monitor.
+ </p>
+ <a href="pix/ssh-01.png"><img src="pix/ssh-01.png" alt="View Console"></a>
+ <p>Log in through there, and disable ufw by typing:</p>
+ <pre><code>ufw disable</code></pre>
+ <h2 id="further-reading">Further Reading</h2>
+ <ul>
+ <li><a href="https://wiki.ubuntu.com/UncomplicatedFirewall">Ubuntu Wiki: UncomplicatedFirewall</a></li>
+ <li><a href="https://help.ubuntu.com/community/Gufw">Gufw (Graphical UFW)</a></li>
+ <li><code>man ufw</code></li>
+ </ul>
+ <strong>Contributor</strong> - <a href="https://shunter.xyz">shunter.xyz</a>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Creating Your Own Chat Server With IRC</title>
+<guid>https://landchad.net/irc.html</guid>
+<link>https://landchad.net/irc.html</link>
+<pubDate>Thu, 01 Jul 2021 16:28:32 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Creating Your Own Chat Server With IRC</h1></header>
+
+ <main>
+ <img class=titleimg src="pix/irc.svg">
+ <p>
+ Creating your own chat server for you and your friends is easy, and you don't have to rely on a complicated system to get started.
+ IRC is an old but gold protocol, and has clients for basically every operating system made since the 80s, with many powerful modern ones on Linux, Mac, and Windows.
+ </p>
+ <p>
+ Having a chat server for you and your friends makes it impossible for a group of arbitrarily appointed moderators to deplatform you for wrong-think, and gives you greater freedom of communication.
+ </p>
+ <h2 id="installing">Installing an IRCd</h2>
+ <p>
+ An IRCd is short for "IRC daemon", which just means an IRC server.
+ The most easy IRCd to setup is <a href="https://ergo.chat/">Ergo</a>.
+ </p>
+ <p>
+ The first thing you need to do is create a new user for the server to be run by.
+ This is good practice for installing software/servers manually, as it give you more fine-grained control over which permissions the application has.
+ </p>
+<pre><code>useradd -m ergo -s /bin/bash</code></pre>
+ <p>
+ Next, we want to switch to our newly created <code>ergo</code> user and create the server directory.
+ </p>
+<pre><code>sudo -i -u ergo
+mkdir server</code></pre>
+ <p>
+ You can find the latest release of Ergo on its GitHub <a href="https://github.com/ergochat/ergo/releases/latest">latest release</a> page.<br>
+ There are several platforms available, but you want to choose Linux, most likely <code>linux-x86_64</code>.<br>
+ Once you have selected the correct package, copy its URL and replace <code><i>&lt;release url&gt;</i></code> with the package URL (still as the <code>ergo</code> user):
+ </p>
+<pre><code>wget https://github.com/ergochat/ergo/releases/download/v2.7.0/ergo-2.7.0-linux-x86_64.tar.gz
+tar -xf ergo-2.7.0-linux-x86_64.tar.gz
+mv ergo-2.7.0-linux-x86_64/*
+rm -r ergo-2.7.0-linux-x86_64*</code></pre>
+ <p>Executing <code>ls -l</code> should now yield something like this:</p>
+<pre><code>-rw-r--r-- 1 ergo ergo 118825 Jun 8 00:51 CHANGELOG.md
+-rw-r--r-- 1 ergo ergo 1983 May 31 01:48 README
+-rw-r--r-- 1 ergo ergo 41440 Jun 8 00:42 default.yaml
+drwxr-xr-x 2 ergo ergo 4096 Jul 1 09:01 docs
+-rwxr-xr-x 1 ergo ergo 9654272 Jun 8 00:53 ergo
+-rw-r--r-- 1 ergo ergo 1753 May 31 01:48 ergo.motd
+drwxr-xr-x 2 ergo ergo 12288 Jul 1 09:01 languages
+-rw-r--r-- 1 ergo ergo 39722 Jun 8 00:42 traditional.yaml</code></pre>
+ <p>If you see something similar to the above, that means Ergo is installed, although not quite ready to run yet.</p>
+ <h2 id="configuring">Configuring Ergo</h2>
+ <p>
+ Now that Ergo is installed, you want to configure it to fit the needs of your group.<br>
+ The configuration in this section is tailored towards a small group of people, and less for a possibly large network,
+ but it should work for any size of group.
+ </p>
+ <p>
+ First thing, make sure you're still using the <code>ergo</code> user, and are in the <code>~/server</code> directory.<br>
+ If you aren't, you can run the following to get back there:
+ </p>
+<pre><code>sudo -i -u ergo
+cd ~/server</code></pre>
+ <p>
+ Next, generate certificate files for TLS:
+ </p>
+ <pre><code>./ergo mkcerts</code></pre>
+ <p>
+ Ergo comes with a default configuration file with detailed documentation that can be used to guide you through the configuration process.
+ This guide will help you setup the server for a typical use-case, but if you see any settings that you would like to change along the way,
+ go ahead and change them, as long as you know what you're doing.
+ </p>
+ <p>To start configuring, we need to copy some files:</p>
+<pre><code>cp default.yaml ircd.yaml
+cp ergo.motd ircd.motd</code></pre>
+ <p>
+ The next steps involve editing the newly copied <code>ircd.yaml</code> file. If you do not know how to edit text files from the comment line,
+ you can use <code>nano</code>, which is very simple, using arrow keys to navigate, <code>CTRL+O</code> to save, and <code>CTRL+X</code> to exit.<br>
+ Another option is <code>vim</code>, which is a much more powerful text editor, but has a learning curve. It is only recommended for this guide if you already know it.<br>
+ Lastly, you can copy the <code>ircd.yaml</code> file to a text editor on your computer and edit it with a GUI text editor of your choice.
+ If that is what you choose to do, you may want to just download the file from <a href="https://raw.githubusercontent.com/ergochat/ergo/master/default.yaml">Ergo's GitHub</a>,
+ edit it on your computer, clear the <code>ircd.yaml</code> file on the server, and then paste the contents from your computer into the blank file.<br>
+ No matter how you do it, the next steps assume you can edit the configuration file.
+ </p>
+ <p>
+ <b>Note</b>:<br>
+ The options highlighted in this section are not a complete overview of all options.
+ Instead, the options shown are the ones which are most relevant to a small network.<br>
+ You should read over the configuration file yourself if you are curious about everything you can change.
+ </p>
+ <h3 id="configuring-names">Network and server names</h3>
+ <p>
+ One of the first properties in the config file is network name.
+ You can change this to whatever you like, as it will show up as the name when you connect to the server.
+ </p>
+<pre><code># network configuration
+network:
+ # name of the network
+ name: "Land-Chat"</code></pre>
+ <p>Change the server name to your server's domain name.</p>
+<pre><code># server configuration
+server:
+ # server name
+ name: "example.org"</code></pre>
+ <h3 id="configuring-password">Network password</h3>
+ <p>
+ The next step is optional, depending on if you want your network password protected or not.
+ The benefit of password protection is fairly obvious; nobody can connect to your network unless you gave them the password.
+ If you're wanting to run a public network which anyone can join and create a channel, you want to skip this, but for personal setups,
+ it is highly recommended.
+ </p>
+ <p>Generate a password to use by executing the following:</p>
+ <pre><code>./ergo genpasswd</code></pre>
+ <p>
+ It will ask you to enter a password and confirm it, then you will be given a hashed password.<br>
+ Copy this password, and paste it into the following field (also removing the <code>#</code> before the <code>password:</code> line):
+ </p>
+<pre><code># password to login to the server, generated using `ergo genpasswd`:
+password: "<i>&lt;your hashed password&gt;</i>"</code></pre>
+ <h3 id="configuring-motd">Message of the day (MotD)</h3>
+ <p>Change the MotD (<b>M</b>essage <b>o</b>f <b>t</b>he <b>D</b>ay) file to the one you copied earlier:</p>
+<pre><code># motd filename
+# if you change the motd, you should move it to ircd.motd
+motd: ircd.motd</code></pre>
+ <p>Feel free to edit <code>ircd.motd</code> to your heart's content. Its contents will be sent to clients when they connect to the network.</p>
+ <h3 id="configuring-ip-limits">IP limits</h3>
+ <p>
+ For security purposes, you might want to limit the amount of client connections per IP.
+ For a private network, 4 is likely the maximum amount of connections you will have per IP, so that is a safe value.<br>
+ If your network is password protected, this is less of an issue, since the only people connecting will be people who have the password.
+ The following is the default, but you can change it to be whichever value you like:
+ </p>
+<pre><code># IP-based DoS protection
+ip-limits:
+ # whether to limit the total number of concurrent connections per IP/CIDR
+ count: true
+ # maximum concurrent connections per IP/CIDR
+ max-concurrent-connections: 16</code></pre>
+ <h3 id="configuring-ip-cloaking">IP cloaking</h3>
+ <p>
+ Traditionally, IRC networks expose users' IP addresses to everyone. This is not a good practice for privacy, however.
+ With Ergo, IP cloaking is enable by default. You can enable or disable it if you like, and change how it looks to users.<br>
+ In this case, <code>netname</code> was changed to <code>"chad"</code>.
+ </p>
+<pre><code># IP cloaking hides users' IP addresses from other users and from channel admins
+# (but not from server admins), while still allowing channel admins to ban
+# offending IP addresses or networks. In place of hostnames derived from reverse
+# DNS, users see fake domain names like pwbs2ui4377257x8.irc. These names are
+# generated deterministically from the underlying IP address, but if the underlying
+# IP is not already known, it is infeasible to recover it from the cloaked name.
+# If you disable this, you should probably enable lookup-hostnames in its place.
+ip-cloaking:
+ # whether to enable IP cloaking
+ enabled: true
+ # whether to use these cloak settings (specifically, `netname` and `num-bits`)
+ # to produce unique hostnames for always-on clients. you can enable this even if
+ # you disabled IP cloaking for normal clients above. if this is disabled,
+ # always-on clients will all have an identical hostname (the server name).
+ enabled-for-always-on: true
+ # fake TLD at the end of the hostname, e.g., pwbs2ui4377257x8.irc
+ # you may want to use your network name here
+ netname: "chad"</code></pre>
+ <h3 id="configuring-hexchat-password">Password enforcement adjustments for HexChat (and possibly other clients)</h3>
+ <p>
+ Ergo offers account registration to allow users to do things like use history and bouncer features, register channels, etc.<br>
+ In clients such as HexChat, server password may conflict with account passwords, so the following setting should be enable if you wish to use accounts with clients such as HexChat.<br>
+ Note that this could under some circumstances be considered a security hazard, as a user with an account does not need to know the server password to connect,
+ although that user would have needed to register an account before the server had a password, and then a password would need to have been set after the fact, so this can be considered a very small concern if your setup always has had a password.<br>
+ Also keep in mind that this setting has no effect if your network does not even have a password at all.
+ </p>
+<pre><code># some clients (notably Pidgin and Hexchat) offer only a single password field,
+# which makes it impossible to specify a separate server password (for the PASS
+# command) and SASL password. if this option is set to true, a client that
+# successfully authenticates with SASL will not be required to send
+# PASS as well, so it can be configured to authenticate with SASL only.
+skip-server-password: true</code></pre>
+ <h3 id="configuring-multiclient">Multiclient, always-on clients, history, etc</h3>
+ <p>
+ Traditionally, IRC servers have no message history, and once you close your client, you cannot receive messages, and are not shown to be online at all.
+ Ergo includes functionality to allow users to both receive history, and keep their clients "online" even after they have left.
+ It also allows multiple clients to connect to the same account.<br>
+ If you are running a private network for friends, you should set <code>always-on</code> and <code>auto-away</code> to <code>opt-out</code>,
+ to have all users with accounts to appear as if they are online at all times, and be able to receive messages when they are offline.<br>
+ For a public network, keep everything as their default values, since you probably do not want randoms having this by default.<br>
+ If for some reason you do not want any of these features at all, you can set <code>enabled</code> to <code>false</code>, but this is not recommended.
+ Below are the recommended values for a private network (e.g. for friends) where users with accounts will be able to receive messages and history while they are offline.
+ </p>
+<pre><code># multiclient controls whether Ergo allows multiple connections to
+# attach to the same client/nickname identity; this is part of the
+# functionality traditionally provided by a bouncer like ZNC
+multiclient:
+ # when disabled, each connection must use a separate nickname (as is the
+ # typical behavior of IRC servers). when enabled, a new connection that
+ # has authenticated with SASL can associate itself with an existing
+ # client
+ enabled: true
+ # if this is disabled, clients have to opt in to bouncer functionality
+ # using nickserv or the cap system. if it's enabled, they can opt out
+ # via nickserv
+ allowed-by-default: true
+ # whether to allow clients that remain on the server even
+ # when they have no active connections. The possible values are:
+ # "disabled", "opt-in", "opt-out", or "mandatory".
+ always-on: "opt-out"
+ # whether to mark always-on clients away when they have no active connections:
+ auto-away: "opt-out"
+ # QUIT always-on clients from the server if they go this long without connecting
+ # (use 0 or omit for no expiration):
+ #always-on-expiration: 90d</code></pre>
+ <h3 id="configuring-vhosts">VHosts</h3>
+ <p>
+ IP cloaking was mentioned previously, and somewhat related to that, Ergo includes "vhost" functionality, which allows users to set a custom IP/host string.
+ This is mostly for cosmetic value, and does not interfere with operators being able to see actual IP addresses for banning, but if you do not want it enable for some reason, you can disable it.
+ </p>
+<pre><code># vhosts controls the assignment of vhosts (strings displayed in place of the user's
+# hostname/IP) by the HostServ service
+vhosts:
+ # are vhosts enabled at all?
+ enabled: true</code></pre>
+ <h3 id="configuring-channels">Channels</h3>
+ <p>
+ Channels are where everyone on an IRC network talk. By default, anyone can create a channel, and anyone with an account can register one.
+ The difference between a normal channel and a registered one is that the registered one will preserve the operator status of the person who created,
+ whereas a normal channel's owner will lose operator status if they leave the channel or disconnect from the network.<br>
+ There are various settings for channels available, but the defaults are suitable for a private network with trust among users, or where you just want anyone to have the ability to create a channel.
+ Below are the default values:
+ </p>
+<pre><code># channel options
+channels:
+ # modes that are set when new channels are created
+ # +n is no-external-messages and +t is op-only-topic
+ # see /QUOTE HELP cmodes for more channel modes
+ default-modes: +nt
+ # how many channels can a client be in at once?
+ max-channels-per-client: 100
+ # if this is true, new channels can only be created by operators with the
+ # `chanreg` operator capability
+ operator-only-creation: false
+ # channel registration - requires an account
+ registration:
+ # can users register new channels?
+ enabled: true
+ # restrict new channel registrations to operators only?
+ # (operators can then transfer channels to regular users using /CS TRANSFER)
+ operator-only: false
+ # how many channels can each account register?
+ max-channels-per-account: 15</code></pre>
+ <h3 id="configuring-operators">Operators (administrators, etc)</h3>
+ <p>
+ The IRC term for an administrator or another privileged user is "operator", or "oper" for short.<br>
+ Ergo's opers have different permissions that can be granted to them, and are defined in "classes", basically groups of permissions under a name.
+ For example, "chat-moderator" and "server-admin" are defined in the default configuration:
+ </p>
+<pre><code># operator classes
+oper-classes:
+ # chat moderator: can ban/unban users from the server, join channels,
+ # fix mode issues and sort out vhosts.
+ "chat-moderator":
+ # title shown in WHOIS
+ title: Chat Moderator
+ # capability names
+ capabilities:
+ - "kill"
+ - "ban"
+ - "nofakelag"
+ - "roleplay"
+ - "relaymsg"
+ - "vhosts"
+ - "sajoin"
+ - "samode"
+ - "snomasks"
+ # server admin: has full control of the ircd, including nickname and
+ # channel registrations
+ "server-admin":
+ # title shown in WHOIS
+ title: Server Admin
+ # oper class this extends from
+ extends: "chat-moderator"
+ # capability names
+ capabilities:
+ - "rehash"
+ - "accreg"
+ - "chanreg"
+ - "history"
+ - "defcon"
+ - "massmessage"</code></pre>
+ <p>
+ The above can be kept with their default values, but you are free to modify them or create any new classes that are appropriate for your setup.<br>
+ Next, let's actually create an operator account:
+ </p>
+<pre><code># ircd operators
+opers:
+ # default operator named 'gigachad'; log in with /OPER gigachad &lt;password&gt;
+ "gigachad":
+ # which capabilities this oper has access to
+ class: "server-admin"
+ # custom whois line
+ whois-line: is the server administrator
+ # custom hostname
+ vhost: "gigachad"
+ # normally, operator status is visible to unprivileged users in WHO and WHOIS
+ # responses. this can be disabled with 'hidden'. ('hidden' also causes the
+ # 'vhost' line above to be ignored.)
+ hidden: false
+ # modes are modes to auto-set upon opering-up. uncomment this to automatically
+ # enable snomasks ("server notification masks" that alert you to server events;
+ # see `/quote help snomasks` while opered-up for more information):
+ #modes: +is acjknoqtuxv
+ # operators can be authenticated either by password (with the /OPER command),
+ # or by certificate fingerprint, or both. if a password hash is set, then a
+ # password is required to oper up (e.g., /OPER dan mypassword). to generate
+ # the hash, use `ergo genpasswd`.
+ password: "<i>&lt;your oper password&gt;</i>"</code></pre>
+ <p>
+ This is a modified version of the default oper entry. The account name is "gigachad", but you can change it to anything.<br>
+ Replace <code><i>&lt;your oper password&gt;</i></code> with a password generated by <code>./ergo genpasswd</code>, and you will have a new oper account to use.<br>
+ Note that to log into an oper account, clients have to enter <code>/OPER <i>&lt;oper name&gt;</i> <i>&lt;oper password&gt;</i></code> each time they log in.
+ This can be automated by most clients by setting the command to be executed when the client logs in.
+ In the case of HexChat, you can edit your network and add the command to the <code>Connect commands</code> tab of the menu.<br>
+ You can copy everything from <code>"gigachad"</code> to the end of the line, paste it again, and change the name to create another oper account.
+ Another, less privileged example of an oper is shown as a comment below the above configuration snippet.
+ </p>
+ <h3 id="configuring-history">Chat history</h3>
+ <p>
+ Traditionally, IRC networks do not store, relay, or handle chat history in any way.<br>
+ On a privacy standpoint, this is a good thing, since chats are entirely ephemeral and handled by clients.<br>
+ On a practicality standpoint, this is a bad thing, since people have to keep a client connected 24/7 to see message history.<br>
+ For normalfriends, this can be a big problem, not only because having to stay online 24/7 is just annoying or infeasible,
+ but also because they are likely used to chat platforms that handle history for them.<br>
+ With this in mind, enabling history is a good idea if you want to move friends over to IRC, and will make things a lot more pleasant for private networks.
+ </p>
+ <p>
+ Ergo's <code>history</code> configuration group is very long, so it is encouraged to read over it yourself.
+ This section will go over the most important pieces of that configuration group.
+ </p>
+ <p>
+ History is not endless (unless you want it to be), and the amount that can be stored for channels is configurable:
+ </p>
+<pre><code># how many channel-specific events (messages, joins, parts) should be tracked per channel?
+channel-length: 2048</code></pre>
+ <p>
+ History is already enabled by default, but that just means it is being collected, not relayed by default.
+ To relay history to clients when they connect, change the following to the amount of messages that you think is appropriate:
+ </p>
+<pre><code># number of messages to automatically play back on channel join (0 to disable):
+autoreplay-on-join: 250</code></pre>
+ <p>
+ History older than a certain time can be configured to be deleted or be inaccessible.
+ The default cutoff time is 1 week, but this is configurable as well.
+ </p>
+<pre><code>
+# options to delete old messages, or prevent them from being retrieved
+restrictions:
+ # if this is set, messages older than this cannot be retrieved by anyone
+ # (and will eventually be deleted from persistent storage, if that's enabled)
+ expire-time: 1w
+</code></pre>
+ <p>
+ By default, Ergo only stores chat history in memory, so when the server restarts, all history is lost.
+ If you wish to have chat history persist beyond restarts, you must store it in a MySQL database:
+ </p>
+<pre><code># options to store history messages in a persistent database (currently only MySQL).
+# in order to enable any of this functionality, you must configure a MySQL server
+# in the `datastore.mysql` section.
+persistent:
+ enabled: true
+ # store unregistered channel messages in the persistent database?
+ unregistered-channels: true</code></pre>
+<br>
+<pre><code># connection information for MySQL (currently only used for persistent history):
+mysql:
+ enabled: false
+ host: "localhost"
+ port: 3306
+ # if socket-path is set, it will be used instead of host:port
+ #socket-path: "/var/run/mysqld/mysqld.sock"
+ user: "ergo"
+ password: "hunter2"
+ history-database: "ergo_history"
+ timeout: 3s
+ max-conns: 4
+ # this may be necessary to prevent middleware from closing your connections:
+ #conn-max-lifetime: 180s</code></pre>
+ <p>
+ For privacy reasons, you may want to allow users to delete their own messages in history, or export their messages to JSON:
+ </p>
+<pre><code># options to control how messages are stored and deleted:
+retention:
+ # allow users to delete their own messages from history?
+ allow-individual-delete: true
+ # if persistent history is enabled, create additional index tables,
+ # allowing deletion of JSON export of an account's messages. this
+ # may be needed for compliance with data privacy regulations.
+ enable-account-indexing: true</code></pre>
+ <h3 id="configuring-spam">Spam reduction</h3>
+ <p>
+ Most IRC networks have measures in place to reduce chat spam. By default, "fakelag" is enabled in Ergo, and that can deal with most aggregious chat spam.<br>
+ If you are running a private network where user trust is high, you can disable it so that there are no limits on the speed that messages can be sent.
+ </p>
+<pre><code># fakelag: prevents clients from spamming commands too rapidly
+fakelag:
+ # whether to enforce fakelag
+ enabled: true
+ # time unit for counting command rates
+ window: 1s
+ # clients can send this many commands without fakelag being imposed
+ burst-limit: 5
+ # once clients have exceeded their burst allowance, they can send only
+ # this many commands per `window`:
+ messages-per-window: 2
+ # client status resets to the default state if they go this long without
+ # sending any commands:
+ cooldown: 2s</code></pre>
+ <h2 id="using">Starting and using your server</h3>
+ <p>
+ Now that Ergo is both installed and configured, you can actually start using it!
+ </p>
+ <h3 id="using-starting">Starting the server</h3>
+ <p>
+ First thing, make sure you're still using the <code>ergo</code> user, and are in the <code>~/server</code> directory.<br>
+ If you aren't, you can run the following to get back there:
+ </p>
+<pre><code>sudo -i -u ergo
+cd server</code></pre>
+ <p>
+ Starting the server is done in one command:
+ </p>
+ <pre><code>./ergo run</code></pre>
+ <p>
+ It will stay online until you close the terminal, or press CTRL+C. Don't worry, the next section goes over how to make it run like a normal server with a SystemD service.<br>
+ If you have not already, make sure the port <code>6697</code> is not blocked on your server. If you are using UFW as your firewall,
+ you need to run <code>ufw enable 6697</code> (not as the <code>ergo</code> user, of course).<br>
+ If you make and configuration changes while the server is running, you can apply them without restarting by typing <code>/rehash</code> as an operator.
+ </p>
+ <h3 id="using-connecting">Connecting to the server</h3>
+ <p>
+ To use IRC, you of course need an IRC client. There are many choices available, but the most widely used for Windows and Linux is <a href="https://hexchat.github.io/">HexChat</a>.
+ On Mac, you have a slightly nicer option with <a href="https://www.codeux.com/textual/">Textual</a>, although you have to <a href="https://github.com/Codeux-Software/Textual/#building-textual">compile it from source</a> if you want to use it for free.<br>
+ A more user-friendly and modern client choice is TheLounge, which is explained in the last section of this guide, if you want to look into it.
+ </p>
+ <p>
+ Connecting with HexChat is very easy. When you start it, you will see something like this:
+ </p>
+ <img src="pix/irc/hexchat-network-select.png" alt="HexChat network select">
+ <p>
+ From there, you should click <code>+ Add</code> and name the server whatever you like (so you can find it on the server list).<br>
+ Once you have created a new server and named it, select it and click <code>Edit...</code>.
+ A menu will show up like the one below. Change the domain to whatever domain your server is running on,
+ and make sure to put in your server password if you set one.
+ </p>
+ <img src="pix/irc/hexchat-network-edit.png" alt="HexChat network edit menu">
+ <p>
+ Once you're done editing the network, click <code>(X) Close</code>, select your network from the network list, and click <code>Connect</code>.<br>
+ If all is well, you should be connected!
+ </p>
+ <img src="pix/irc/hexchat-connection-complete.png" alt="HexChat connection complete">
+ <p>
+ The process is very similar on Textual.<br>
+ Create a new network and connect to it. Note that it will ask if you want to connect even though the certificate is unsigned.
+ This is due to the self-signed certificates generated for the server, and is not a problem or security vulnerability, it is just a little annoying.
+ </p>
+ <img src="pix/irc/textual-network-edit.png" alt="Textual network edit menu">
+ <h2 id="service">Surviving restarts with a SystemD service</h3>
+ <p>
+ In the beginning of the last section, Ergo was started by simply running <code>./ergo run</code>, but this is only suitable for testing.
+ To have a proper server setup, you need to run it as a service. This can be achieved via a SystemD service.
+ </p>
+ <p>
+ Before creating your service file, make sure you are in <code>~/server</code> as the <code>ergo</code> user.<br>
+ Once you have done that, create a file called <code>start.sh</code> with the following content:
+ </p>
+<pre><code>#!/bin/bash
+./ergo run</code></pre>
+ <p>Save the file, then mark it as executable:</p>
+ <pre><code>chmod +x start.sh</code></pre>
+ <p>Now, create a file called <code>ergo.service</code> with the following content:</p>
+<pre><code>[Unit]
+Description=Ergo IRC server
+After=network.target
+# If you are using MySQL for history storage, comment out the above line
+# and uncomment these two instead (you must independently install and configure
+# MySQL for your system):
+# Wants=mysql.service
+# After=network.target mysql.service
+[Service]
+Type=simple
+User=ergo
+WorkingDirectory=/home/ergo/server
+ExecStart=/home/ergo/server/start.sh
+ExecReload=/bin/kill -HUP $MAINPID
+Restart=on-failure
+LimitNOFILE=1048576
+# Uncomment this for a hidden service:
+# PrivateNetwork=true
+[Install]
+WantedBy=multi-user.target</code></pre>
+ <p>
+ You now have your service file, but it is not installed yet.
+ To install it, switch to your normal user, and execute the following lines to install, enable, and start the SystemD service:
+ </p>
+<pre><code>ln -s /home/ergo/server/ergo.service /etc/systemd/system/ergo.service
+systemctl enable ergo
+systemctl start ergo</code></pre>
+ <p>Ergo is now installed and running as a service, and will automatically start when the system boots.</p>
+ <h2 id="registering">Registering accounts and channels</h2>
+ <p>
+ Account and channel registration were mentioned multiple times in this guide, and are indeed very important parts of the modern IRC ecosystem.
+ You can connect to most IRC networks and talk without creating an account, but you will not be able to reserve your nickname or register channels, so it is important to register an account.
+ </p>
+ <h3 id="registering-accounts">Registering an account with NickServ</h3>
+ <p>
+ First, make sure you are connected to your IRC network.
+ Once you are, type <code>/nickserv help</code> to make sure NickServ (the registration system) is working propertly.<br>
+ If all is well, type the following, replacing <code><i>&lt;your password&gt;</i></code> with the password you want to use:
+ </p>
+ <pre><code>/nickserv register <i>&lt;your password&gt;</i></code></pre>
+ <p>
+ At this point, you are now registered!<br>
+ The final step is to configure authentication with your client.
+ </p>
+ <p>In HexChat, all that needs to be done is changing <code>Login method</code> to <code>SASL (username + password)</code>, and entering your NickServ password that you used earlier into the password field:</p>
+ <img src="pix/irc/hexchat-sasl.png" alt="HexChat SASL in network edit menu">
+ <p>
+ In Textual, open up your network in the menu, and click <code>Identity</code> under <code>Server Properties</code>.
+ Enter your password in <code>Personal Password</code>, and check <code>Wait for identification before joining channels</code>.
+ </p>
+ <img src="pix/irc/textual-identity.png" alt="Textual identity menu">
+ <p>You will now be logged into your account when you connect to your network.</p>
+ <h3 id="registering-channels">Registering channels with ChanServ</h3>
+ <p>
+ Once you have an account registered, you can register channels with ChanServ.<br>
+ To do so, join the channel you want to register, then type the following, replacing <code><i>&lt;your channel&gt;</i></code> with the name of the channel you want to register:
+ </p>
+ <pre><code>/chanserv register #<i>&lt;your channel&gt;</i></code></pre>
+ <p>
+ You are now the channel owner, and are free to appoint operators, administrators, etc for it.
+ When you go offline, you won't lose ownership, and you cannot be removed as the owner unless you unregister the channel later.
+ </p>
+ <h2 id="moderation">Moderation</h2>
+ <p>
+ Like any chat, there will come a point where you need to use moderation tools to keep things under control.
+ Many IRC setup guides do not go over moderation, so it can be stressful when operators need to actually use moderation tools.<br>
+ The main difference between IRC and other chat systems in terms of moderation is the difference between channel bans and network bans.
+ Channel ban keeps a person out of channel a channel, whereas a network ban keeps a person out of the entire network.
+ </p>
+ <h3 id="moderation-masks">Understanding masks</h3>
+ <p>
+ Bans are applied "masks", which are formatted pieces of text that contain a user's nick (username), their realname value, and their IP address or host.<br>
+ This is what a mask looks like: <code>nick!~nick-dude@127.0.0.1</code>.<br>
+ In bans, asterisks can be used as wildcards, which is useful for banning IP address ranges, patterns of nicknames, or whatever else you can think of.<br>
+ A ban on the nick <code>person</code>, for example, would look like this: <code>person!*@*</code>.<br>
+ A ban on anyone with the IP address <code>127.0.0.1</code> would look like this: <code>*!*@127.0.0.1</code>
+ </p>
+ <h3 id="moderation-real-ips">Discovering real IPs</h3>
+ <p>
+ Even if IP cloaking is enabled on your network, you can still obtain real IP addresses/hosts if you are an operator.
+ See the <b>Operators</b> part of the configuration section of this guide on how to become an operator.<br>
+ To find out a user's real IP, simply type <code>/whois</code> along with the user's nick, and you will see information about the user, along with their real IP address/host.<br>
+ <code>/whois</code> is not a command that is exclusive to operators, but it does not reveal as much information to non-operators.
+ </p>
+ <h3 id="moderation-network-ban">Banning someone from the network</h3>
+ <p>
+ Any netword-wide moderation action requires being an operator. See the <b>Operators</b> part of the configuration section of this guide on how to become an operator.<br>
+ Banning someone from the network is achieved with the <code>/kline</code> command. To see more info on the command, type <code>/helpop kline</code>.<br>
+ </p>
+ <p>To ban a nick from the network:</p>
+ <pre><code>/kline andkill <i>&lt;nick&gt;</i>!*@*</code></pre>
+ <p>To ban an IP address or host from the network:</p>
+ <pre><code>/kline andkill *!*@<i>&lt;IP or mask&gt;</i></code></pre>
+ <p>To unban a mask, you can use the <code>/unkline</code> command with the mask you want to unban.</p>
+ <h3 id="moderation-channel-ban">Banning someone from a channel</h3>
+ <p>
+ Channel owners, administrators, and operators can ban people from channels.
+ This is not the same as banning someone from the network, since it only has an effect on one channel.
+ Additionally, a channel operator is not the same as a network operator.
+ </p>
+ <p>To ban someone in a channel, type the following in that channel, replacing <code><i>&lt;mask&gt;</i></code> with the user's mask:</p>
+ <pre><code>/mode +b <i>&lt;mask&gt;</i></code></pre>
+ <p>
+ Note that this will only ban the user, not kick them immediately.
+ You will want to run <code>/kick</code> along with the user's nick to also kick them.<br>
+ To unban a user, run the command above, but replace the <code>+</code> with a <code>-</code>.<br>
+ You can see who is banned in a channel by typing <code>/banlist</code>.
+ </p>
+ <h3 id="moderation-muting">Muting people in a channel</h3>
+ <p>
+ By default, anyone can speak in an IRC channel. To change this, you must be a channel owner, administrator, or operator.<br>
+ Channels, along with users, have modes, which modify their behavior. There is a special mode for channels called <code>m</code> (moderated) which requires users to be privileged in some way to talk.<br>
+ To set a channel as moderated, type the following in the channel:
+ </p>
+ <pre><code>/mode +m</code></pre>
+ <p>
+ Now, users must be an owner, administrator, operator, or be voiced to talk in the channel
+ This be reversed by typing the command above, but changing the <code>+</code> to a <code>-</code>.<br>
+ To voice a user, run the following, replacing <i>&lt;nick&gt;</i> with the user's nick:
+ </p>
+ <pre><code>/mode +v <i>&lt;nick&gt;</i></code></pre>
+ <p>Unvoice the user by typing the above command, but replacing the <code>+</code> with a <code>-</code>.</p>
+ <h3 id="moderation-appointing">Appointing channel administrators and operators</h3>
+ <p>
+ Assuming you a channel owner, you can appoint both administrators and operators.
+ If you are only an operator, you may only appoint operators.<br>
+ The difference between administrator and operator is mainly that administrators cannot have their privileges taken away by operators, only owners.
+ To appoint an administrator, type the following, replacing <i>&lt;nick&gt;</i> with the user's nick:
+ </p>
+ <pre><code>/mode +a <i>&lt;nick&gt;</i></code></pre>
+ <p>To appoint an operator, type the following, replacing <i>&lt;nick&gt;</i> with the user's nick:</p>
+ <pre><code>/mode +o <i>&lt;nick&gt;</i></code></pre>
+ <p>
+ You can also use <code>/op</code> and <code>/deop</code> on most clients to appoint and remove an operator.<br>
+ To remove administrator or operator status, run either of the above commands, but replace the <code>+</code> with a <code>-</code>.
+ </p>
+ <h2 id="thelounge">Bringing modern-day features to IRC with TheLounge</h3>
+ <p>
+ A large downside to IRC as a protocol is just how old it is, and the limitations that exist because of it.
+ Other old protocols such as HTTP were built to be content-agnostic and versitile, but IRC was built with a very specific set of features, so it has not held up so well to contemporary chat systems.<br>
+ A notable thing that IRC as a protocol is missing is file uploads, and other fancy features that many other chats have.<br>
+ With that said, these problems can be fixed by clients, although many clients are still very primitive.
+ </p>
+ <p>
+ <a href="https://thelounge.chat/">TheLounge</a> is a modern self-hosted IRC web client that tries to make IRC as user-friendly as possible.
+ It can be the answer to many of the complaints that normalfriends may have about IRC. It runs on anything with a web browser, can be "installed" since it is a PWA (Progressive Web App),
+ and is optimized for both desktops and mobile devices. It keeps you logged in even when you are gone, and even supports file uploads and embeds.<br>
+ Effectively, it brings IRC up to the standard of most other chat systems.
+ </p>
+ <p>
+ If you would like to setup an instance of TheLounge for you and your friends, you can take a look at their <a href="https://thelounge.chat/docs/install-and-upgrade">installation guide</a>.<br>
+ It is a self-hosted web app, so you can run it for multiple people, not just yourself.
+ </p>
+ <hr>
+ <p><i>Written by <a href="https://termer.net/">Termer</a></i></p>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Setting up Gitea</title>
+<guid>https://landchad.net/gitea.html</guid>
+<link>https://landchad.net/gitea.html</link>
+<pubDate>Thu, 01 Jul 2021 16:14:22 -0400</pubDate>
+<description><![CDATA[
+ <header><h1>Setting up Gitea</h1></header>
+
+ <main>
+ <img class=titleimg src="pix/gitea.svg">
+ <p>Gitea allows you to self-host your git repositories similar to <a href="git.html">bare repositories</a>, but comes with additional features that you might know from GitHub, such as issues, pull requests or multiple users. Its advantage over GitLab&mdash;another Free Software GitHub clone&mdash;is that it is much more lightweight and easier to setup.</p>
+ <p>Head over to <a href="https://gitea.com">gitea.com</a> to see what it looks like in practice.</p>
+ <p>Although Gitea is lighter than Gitlab, if you have a VPS with only 512MB of RAM, you will probably have to upgrade. Gitea is more memory-intensive than having just a bare git repository.</p>
+ <h2>Installing Gitea</h2>
+ <p>First install a few dependencies:</p>
+ <pre><code>apt install curl sqlite3</code></pre>
+ <p>Unfortunately, Gitea itself is not in the official Debian repos, so we will add a third-party repository for it.</p>
+ <p>Add the repo's gpg key to apt's trusted keys:</p>
+ <pre><code>curl -sL -o /etc/apt/trusted.gpg.d/morph027-gitea.asc https://packaging.gitlab.io/gitea/gpg.key</code></pre>
+ <p>Then add the actual repository to apt:</p>
+ <pre><code>echo "deb [arch=amd64] https://packaging.gitlab.io/gitea gitea main" > /etc/apt/sources.list.d/morph027-gitea.list</code></pre>
+ <p>Now we can install Gitea:<p>
+ <pre><code>apt update
+apt install gitea</code></pre>
+ <p>Since apt automatically enables and starts the Gitea service, it should already be running on port <code>3000</code> on your server!</p>
+ <h2>Setting up a Nginx reverse proxy</h2>
+ <p>You should know how to generate SSL certificates and use Nginx by now. Add this to your Nginx config to proxy requests made to your git subdomain to Gitea running on port 3000:</p>
+ <pre><code>
+server {
+ listen 443 ssl;
+ listen [::]:443 ssl;
+ ssl_certificate /etc/ssl/nginx/<strong>git.example.org</strong>.crt;
+ ssl_certificate_key /etc/ssl/nginx/<strong>git.example.org</strong>.key;
+ server_name <strong>git.example.org</strong>;
+ location / {
+ proxy_pass http://localhost:3000/; # The / is important!
+ proxy_redirect off;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+}
+ </pre></code>
+ <p>And reload Nginx:</p>
+ <pre><code>systemctl reload nginx</code></pre>
+ <h2>Setting up Gitea</h2>
+ <p>If everything worked fine you should now see a setup screen when you go to your configured domain in the browser. The options should be pretty self-explanatory, it is only important to select SQLite3 and to replace the base url and SSH server domain with your own.</p>
+ <dl>
+ <dt>Database Type:</dt>
+ <dd>SQLite3</dd>
+ <dt>SSH Server Domain:</dt>
+ <dd><strong>git.example.org</strong></dd>
+ <dt>Gitea Base URL:</dt>
+ <dd><strong>git.example.org</strong></dd>
+ </dl>
+ <p>These and other settings can be changed in a configuration file later so don't worry about making wrong decisions right now.</p>
+ <p>After clicking the install button you should now be able to log into your Gitea instance with the account you just created! Explore the settings for more things to do, such as setting up your SSH keys.</p>
+ <p>If Gitea does not load fully and has random errors, it is possible that you need to increase your available memory on your VPS. This can usually be done on your VPS-provider's website without too much trouble.</p>
+ <h2>A few extras</h2>
+ <h3>Automatically create a new repo on push</h3>
+ <p>This is an incredicly useful feature for me. Open up <code>/etc/gitea/app.ini</code> and add <code>DEFAULT_PUSH_CREATE_PRIVATE = true</code> to the <code>repository</code> section like so:</p>
+ <img src=pix/gitea-push-create.png>
+ <br>
+ <p>If you now add a remote to a repository like this</p>
+ <pre><code>git remote add origin 'ssh://gitea@git.<strong>example.org</strong>/<strong>username</strong>/<strong>coolproject</strong>.git'</code></pre>
+ <p>and push, Gitea will automatically create a private <code>coolproject</code> repository in your account!</p>
+ <h3>Change tab-width</h3>
+ <p>By default Gitea displays tabs 8 spaces wide, however I prefer 4 spaces. We can change this!</p>
+ <pre><code>mkdir -p /var/lib/gitea/custom/templates/custom/</code></pre>
+ <p>And write this into <code>/var/lib/gitea/custom/templates/custom/header.tmpl</code>:</p>
+ <pre><code>&ltstyle&gt
+.tab-size-8 {
+ tab-size: 4 !important;
+ -moz-tab-size: 4 !important;
+}
+&lt/style&gt</code></pre>
+ <h2>Contribution</h2>
+ <ul>
+ <li><a href="https://phire.cc">phire</a></li>
+ </ul>
+ </main>
+
+]]></description>
+</item>
+
+
+<item>
+<title>Hosting Your Own Git Repositories</title>
<guid>https://landchad.net/git.html</guid>
<link>https://landchad.net/git.html</link>
<pubDate>Thu, 01 Jul 2021 07:19:51 -0400</pubDate>
@@ -154,8 +1974,7 @@ mkdir git</code></pre>
</p>
<h2>Contribution</h2>
<ul>
- <li>Martin Chrzanowski -- <a
- href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/crypto.html">donate</a></li>
+ <li>Martin Chrzanowski -- <a href="https://m-chrzan.xyz">website</a>, <a href="https://m-chrzan.xyz/donate.html">donate</a></li>
</ul>
</main>
@@ -164,7 +1983,7 @@ mkdir git</code></pre>
<item>
-<title>Requiring Passwords for Webpages (HTTP Authentication) &ndash; LandChad.net</title>
+<title>Requiring Passwords for Webpages (HTTP Authentication)</title>
<guid>https://landchad.net/auth.html</guid>
<link>https://landchad.net/auth.html</link>
<pubDate>Thu, 01 Jul 2021 07:19:27 -0400</pubDate>
@@ -268,7 +2087,7 @@ mkdir git</code></pre>
<item>
-<title>Cronjobs &ndash; LandChad.net</title>
+<title>Cronjobs</title>
<guid>https://landchad.net/cron.html</guid>
<link>https://landchad.net/cron.html</link>
<pubDate>Thu, 01 Jul 2021 07:19:04 -0400</pubDate>
diff --git a/rsync.html b/rsync.html
new file mode 100644
index 0000000..a02d17f
--- /dev/null
+++ b/rsync.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Rsync: Upload and Sync Files and Websites &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+
+<header><h1>Rsync: Upload and Sync Files and Websites</h1></header>
+<nav></nav>
+<main>
+ <p>rsync is a simple way to copy files and folders between your local computer and server.</p>
+ <p>It not only makes file-transfer easy, but it allows you to build and maintain your website offline, then easily upload it to the proper directory on your server so you don't need to constantly be logged into your server to modify your site.</p>
+<h2 id="installing-rsync">Installing rsync</h2>
+<p>Run the following on your server <em>and</em> on your local machine.</p>
+<pre><code>apt install rsync</code></pre>
+<h2 id="uploading-files-with-rsync">Uploading files with rsync</h2>
+<p>From your local machine you can upload files to your server like this:</p>
+<pre><code>rsync -rtvzP <strong>/path/to/file</strong> <strong>root@example.org:/path/on/the/server</strong></code></pre>
+<p>You will be prompted for the root password and then uploading will commence.</p>
+<p>If you omit <strong>root@</strong>, rsync will not attempt to log in as root, but whatever your local username is.</p>
+<h3>Options to rsync</h3>
+<p>In this command, we give several options to rsync:</p>
+<ul>
+ <li><code>-r</code> &ndash; run recurssively (include directories)</li>
+ <li><code>-t</code> &ndash; transfer modification times, which allows skipping files that have not been modified on future uploads</li>
+ <li><code>-v</code> &ndash; visual, show files uploaded</li>
+ <li><code>-z</code> &ndash; compress files for upload</li>
+ <li><code>-P</code> &ndash; if uploading a large file and upload breaks, pick up where we left off rather than reuploading the entire file</li>
+</ul>
+<p>Avoid using the commonly used <code>-a</code> option when uploading. It can transfers your local machine's user and group permissions to your server, which might cause breakage.</p>
+<h3>Scriptability</h3>
+<p>It's a good idea to build your website offline, then make an rsync script or bash alias like the one above to upload the edited files when you have made updates.</p>
+<h3>Password-less authentication</h3>
+<p>To avoid having to manually input your password each upload, you can set up <a href="sshkeys.html">SSH keys</a> to securely idenitify yourself and computer as a trusted.</p>
+<h3>Picky trailing slashes</h3>
+<p>rsync is very particular about trailing slashes. This is useful, but can be confusing to some new users. Suppose we run the following wanting to mirror our offline copy of our website in the directory we use on our server (<code>/var/www/websitefiles/</code>):</p>
+<pre><code>rsync -rtvzP ~/<strong>websitefiles/</strong> root@example.org:/var/www/<strong>websitefiles/</strong></code></pre>
+<p>This will <em>not actually do quite what we want</em>. It will take our local <code>websitefiles</code> directory and put it <em>inside</em> <code>websitefiles</code> on the remote machine, ending up with: <code>/var/www/websitefiles/websitefiles</code>.</p>
+<p>Instead, remove the trailing slash from the remote server location:</p>
+<pre><code>rsync -rtvzP ~/<strong>websitefiles/</strong> root@example.org:/var/www/<strong>websitefiles</strong></code></pre>
+<p><code>websitefiles/</code> has been replaced with <code>websitefiles</code>, and this will do what we want.</p>
+<h2 id="downloading-file-with-rsync">Downloading files with rsync</h2>
+<p>You may just as easily download files and directories from your server with rsync:</p>
+<pre><code>rsync -rtvzP <strong>root@example.org:/path/to/file</strong> <strong>/path/to/file</strong></code></pre>
+<h2 id="contribution">Contribution</h2>
+<ul><li>el3ctr0lyte: <a href="https://github.com/el3ctr0lyte">github</a>, XMR: <code class=crypto>86DBJdiG83ZDea6kJgsbVN5tMae5ScfuhJ3PihEMTHatCrGEw2gctyUB92V2fz4R4YhwRaQeAGL5M4gPRXvVvtkULJi4ayk</code></li><li>Substantial revisions by <a href="https://lukesmith.xyz">Luke</a></li></ul>
+</main>
+<footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/server.html b/server.html
index 08ddcc2..aaf007f 100644
--- a/server.html
+++ b/server.html
@@ -38,7 +38,7 @@
<p>
The VPS provider that I'll be using for this guide is Vultr, since that is what I use.
Vultr provides a free one-month $100 credit to anyone who starts an account through <a href="https://www.vultr.com/?ref=8384069-6G">this referral link of mine</a>
- so you can play around with their servies with impunity.
+ so you can play around with their services with impunity.
</p>
<h2>Starting your server in two minutes or less</h2>
@@ -73,7 +73,7 @@
<p>
I especially recommend <strong>Debian 10</strong> for an operating system for your server.
Debian is the "classic" server OS and as such, <strong>I make my guides on this site for Debian 10</strong>.
- If you use another OS, just know that your milage may vary in terms of you might need to change some instructions here minorly.
+ If you use another OS, just know that your millage may vary in terms of you might need to change some instructions here minorly.
</p>
<h4>Server size</h4>
@@ -113,7 +113,8 @@
Momentarily, you will be able to see your server's IP addresses which will be used for the next brief step:
</p>
- <span class=next><a href="dns.html">Next: Connect Your Domain and Server</a></span>
+ <span class=prev><a href="domain.html">Previous: Get a domain name.</a></span>
+ <span class=next><a href="dns.html">Next: Connect Your Domain and Server.</a></span>
<hr>
@@ -140,6 +141,6 @@
There's a low chance of their whole system collapsing or something, but I say it's a good idea to be hyper-precautious.
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/sshkeys.html b/sshkeys.html
index 24154ba..33aabe0 100644
--- a/sshkeys.html
+++ b/sshkeys.html
@@ -167,6 +167,6 @@ UsePAM <strong>no</strong></code></pre>
</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/standalone.html b/standalone.html
new file mode 100644
index 0000000..2336b2f
--- /dev/null
+++ b/standalone.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Certbot on Standalone Domains and Subdomains &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Certbot on Standalone Domains and Subdomains</h1></header>
+ <nav></nav>
+ <main>
+ <p>The command <code>certbot --nginx</code> will take an unencrypted website on an Nginx configuration file, get a certificate for it and change the configuration to use that certificate and thus HTTPS.</p>
+
+ <p>Sometimes, however, you are given an Nginx configuration template that already has encryption/HTTPS, so running the automated <code>certbot --nginx</code> is not possible, as it will simply give an error saying that the certicate that Nginx is looking for doesn't already exist and thus the Nginx config is broken.</p>
+
+ <p>So suppose you want to get a certificate for <strong>pleroma.example.org</strong> because you are installing Pleroma and the configuration file presupposes a certificate.
+ In this case you would want to run this:</p>
+
+ <pre><code>systemctl stop nginx
+certbot certonly --standalone -d <strong>pleroma.example.org</strong>
+systemctl start nginx</code></pre>
+
+ <p>What we do here is temporarily turn of Nginx, then run a <code>certonly</code> subcommand that generates a certificate for the domain without changing or caring about the Nginx configuration. Then we reactivate Nginx, thus turning back on our webserver.</p>
+ <p>The reason we deactivate Nginx is that it uses the ports that Certbot will want to bind to, and thus we must temporarily turn Nginx off to let Certbot use those ports. (What it actually does is spin up a dummy webserver that doesn't need to think about the Nginx configuration.)</p>
+ <p>This is just a little note of something that might confuse people, but the three commands above should suffice. If your site is still managed by Nginx, it should still be able to renew with simple <code>certbot renew --nginx</code> without a problem.</p>
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/style.css b/style.css
index 40eee45..5167903 100644
--- a/style.css
+++ b/style.css
@@ -5,6 +5,7 @@ body {
color: beige ;
background: #111 ;
margin-bottom: 200px ;
+ font-family: sans-serif ;
}
h1 {
@@ -66,7 +67,7 @@ pre {
.wide { max-width: inherit ; }
-p img, li img, h1 img, h2 img, h3 img, h4 img {
+p img, li img, h1 img, h2 img, h3 img, h4 img, dt img {
vertical-align: middle ;
max-width: 1em;
max-height: 1em;
@@ -168,7 +169,27 @@ aside.callout {
main { max-width: 850px ; }
}
-.ll { font-size: large ; line-height: 1.3em ; max-width: 600px; margin: auto ; }
+.ll {
+ font-size: large ;
+ line-height: 1.3em ;
+ max-width: 600px;
+ margin: auto ;
+}
+
+.ll dd {
+ display: inline ;
+}
+
+.ll dt {
+ display: inline-block ;
+ width: 6em ;
+}
+
+.ll dd:after {
+ display:block;
+ content: '' ;
+}
+
/* These settings are for the cryptocurrency donation QR codes and info on the
* main page. */
@@ -184,7 +205,7 @@ aside.callout {
padding-left: 10px ;
padding-right: 10px ;
}
-.cryptoinfo code {
+.cryptoinfo code,.crypto {
font-size: small ;
overflow-wrap: break-word ;
}
@@ -197,19 +218,30 @@ aside.callout {
100% {color: lightblue}
}
+.prev {
+ font-size: large ;
+ text-align: center ;
+ margin: auto ;
+ display: block ;
+ font-weight: bold ;
+}
+
+.prev:before {
+ content: "👈" ;
+}
+
.next a {
color: inherit ;
}
.next {
- color: red ;
-webkit-animation:next 1s infinite alternate ;
font-size: xx-large ;
text-align: center ;
margin: auto ;
display: block ;
font-weight: bold ;
- padding: 1em ;
+ padding: 0 1em 1em 1em ;
}
.next:before {
diff --git a/template.html b/template.html
index 7384113..576995d 100644
--- a/template.html
+++ b/template.html
@@ -15,6 +15,6 @@
<++>
<span class=next><a href="<++>">Next:<++></a></span>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/tor.html b/tor.html
index bbe8147..87c34ac 100644
--- a/tor.html
+++ b/tor.html
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang=en>
<head>
- <title>Mirror your site over tor</title>
+ <title>Mirror your site over Tor</title>
<meta charset="utf-8"/>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<link rel='stylesheet' type='text/css' href='style.css'>
@@ -22,24 +22,24 @@
<h3>Installing Tor</h3>
- <p>Firstly we need to add the tor repo's to have the latest up to date version or tor.</p>
+ <p>Firstly we need to add the Tor repos to our system to get the latest version of Tor:</p>
<pre><code>apt install -y apt-transport-https gpg
echo "deb https://deb.torproject.org/torproject.org buster main
deb-src https://deb.torproject.org/torproject.org buster main" > /etc/apt/sources.list.d/tor.list</code></pre>
- <p>Then we need to add the gpg keys to our keyring</p>
+ <p>Then we need to add the gpg keys to our keyring:</p>
<pre><code>curl -s https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | apt-key add -</code></pre>
- <p>Now update and install tor</p>
+ <p>Now update and install Tor:</p>
<pre><code>apt update
apt install tor deb.torproject.org-keyring</code></pre>
<h3>Enabling Tor</h3>
- <p>Then edit the file <code>/etc/tor/torrc</code>, uncommenting the following lines:</p>
+ <p>Next edit the file <code>/etc/tor/torrc</code>, uncommenting the following lines:</p>
<pre><code>HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:80</code></pre>
<aside>
@@ -51,19 +51,19 @@ HiddenServicePort 80 127.0.0.1:80</code></pre>
HiddenServiceDir line.</p>
</aside>
- <p>Now start and enable tor at boot</p>
+ <p>Now start and enable Tor at boot:</p>
<pre><code> systemctl enable --now tor </code></pre>
<p>If the next command outputs <q>active</q> in green you're golden!</p>
<pre><code> systemctl status tor</code></pre>
- <p>Now you're server is on the dark web. The following command will give you your onion address:</p>
+ <p>Now your server is on the dark web. The following command will give you your onion address:</p>
<pre><code> cat /var/lib/tor/hidden_service/hostname</code></pre>
<h2>Adding the Nginx Config</h2>
<p>
From here, the steps are almost identical to setting up a normal website configuration file.
- Follow the steps as if you were making a new website on the webserver
+ Follow the steps as if you were making a new website in the webserver
<a href="nginx.html">tutorial</a> up until the server block of code. Instead, paste this:
</p>
@@ -80,18 +80,30 @@ HiddenServicePort 80 127.0.0.1:80</code></pre>
<p>The <code>root</code> line is the path to whichever website of yours you'd like to mirror.</p>
</aside>
<p>
- From here we are almost done, all we have to do is enable the site and reload nginx which is also covered in <a href="nginx.html#enable">the webserver tutorial</a>.
+ Now we are almost done, all we have to do is enable the site and reload nginx which, is also covered in <a href="nginx.html#enable">the webserver tutorial</a>.
</p>
+ <h3>Advertise your onion service</h3>
+
+ <p>You can add the Onion-Location header to your normal website to advertise your onion service to Tor users. On your regular site's nginx config, add the following line:</p>
+ <pre><code>server {
+ ...
+ add_header Onion-Location http://<strong>your-onion-address</strong>.onion$request_uri;
+}</code></pre>
+ <p>After doing this and reloading nginx, when visiting your regular site via Tor, you should see a ".onion available" button on the address bar, which should take you to the onion service.</p>
+
<h3>Update regularly!</h3>
<p>Make sure to update Tor on a regular basis by running:</p>
<pre><code>apt update
apt install tor</code></pre>
- <p><strong>Contributor</strong> - <a href="https://tomfasano.xyz" target="_blank">tomfasano.xyz</a></p>
+ <h4>Note:</h4>
+ <p>You do <u>not</u> need to run certbot for an ssl certificate. HTTP over tor is plenty secure!</p>
+
+ <p><strong>Contributor</strong> - <a href="https://tomfasano.co" target="_blank">tomfasano.co</a></p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>
diff --git a/ufw.html b/ufw.html
new file mode 100644
index 0000000..61c77a1
--- /dev/null
+++ b/ufw.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html lang=en>
+ <head>
+ <title>Using UFW as a Firewall &ndash; LandChad.net</title>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
+ <link rel='stylesheet' type='text/css' href='style.css'>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel='alternate' type='application/rss+xml' title='Land Chad RSS' href='/rss.xml'>
+ </head>
+<body>
+ <header><h1>Using UFW as a Firewall</h1></header>
+ <nav></nav>
+ <main>
+ <p>
+ <strong>Uncomplicated Firewall</strong> (UFW) is a front-facing program for the more involved <code>iptables</code> firewall program installed in most GNU/Linux distributions.
+ We can use <code>ufw</code> to restrict machines on the internet to only access the services (SSH, websites etc) you want them to, but it can also be used to prevent programs on the computer itself from accesing parts of the internet it shouldn't.
+ </p>
+
+ <h2 id="how-to-get-it">How to Get It</h2>
+
+ <p>Log into your server by pulling up a terminal and typing:</p>
+
+ <pre><code>ssh root@<strong>example.org</strong></code></pre>
+
+ <p>
+ This command will attempt to log into your server and run a remote shell.
+ If you leave the settings default, it should prompt you for your password, and you can just copy or type in the password from Vultr's site.
+ </p>
+
+ <p>
+ Some VPS providers automatically install <code>ufw</code>, but if you do not have it installed already, install it in the typical way:
+ </p>
+
+ <pre><code>apt install ufw</code></pre>
+
+ <h2 id="first-time-setup">First-Time Setup</h2>
+
+ <p>You can check the status of <code>ufw</code> right now by running:</p>
+
+ <pre><code>ufw status</code></pre>
+
+ <p>Without any changes, it should report back <code>Status: inactive</code>. Let's set it up so that only connections to SSH (standardized at port 22) are allowed in, and then enable the firewall:</p>
+
+ <aside>
+ <strong>Careful!</strong> Enabling <code>ufw</code> without allowing SSH will block you from remoting to your server.
+ Double-check that you have allowed SSH, and if you have changed the default SSH port, put in <em>that</em> number instead.
+ </aside>
+
+ <pre><code>ufw default deny incoming # block all incoming connections by default
+ufw allow in ssh # or: ufw allow in 22
+ufw enable</code></pre>
+
+ <aside>
+ <code>ufw</code> has an internal list of protocols applications, and the ports used by them.
+ In this case, it knows SSH is on port 22.
+ We'll go more in detail how to view all protocols <code>ufw</code> knows about.
+ By default, when you allow an incoming port, it allows that port both on IPv4 and IPv6.
+ </aside>
+
+ <p>
+ With the firewall enabled and allowing only SSH in, all other ports are prortected from incoming requests.
+ To view all your rules, run:
+ </p>
+
+ <pre><code>ufw status verbose</code></pre>
+
+ <p>A firewall that allows to connect to SSH and their website may look like:</p>
+
+ <pre><code>Status: active
+Logging: on (low)
+Default: deny (incoming), allow (outgoing), deny (routed)
+New profiles: skip
+
+To Action From
+-- ------ ----
+22 (SSH) ALLOW IN Anywhere
+80,443/tcp (WWW Full) ALLOW IN Anywhere
+22 (SSH (v6)) ALLOW IN Anywhere (v6)
+80,443/tcp (WWW Full (v6)) ALLOW IN Anywhere (v6)</code></pre>
+
+ <p>If you want to delete e.g. the 'WWW Full' rule, run:</p>
+
+ <pre><code>ufw delete allow in 'WWW Full'
+ufw reload</pre></code>
+
+ <h2 id="enabling-common-services">Enabling Common Services</h2>
+
+ <p>
+ You have blocked all incoming ports but SSH, which means no outsiders would be able to access other services, like an email server or your website.
+ You should look at the ports your services are open on and enable them individually.
+ Here is a list of a few common services:
+ </p>
+
+ <h3>Opening Port Numbers</h3>
+
+ <p>Suppose you install <a href="gemini.html">a Gemini server</a>, which must broadcast on port 1965. By default <code>ufw</code> blocks all incoming connections on all ports, so whenever you install a new service like this you will have to tell <code>ufw</code> to enable the desired port:</p>
+
+ <pre><code>ufw allow 1985</code></pre>
+
+ <h3>Websites: HTTP and HTTPS</h3>
+
+ <p>HTTP uses port 80 and HTTPS uses port 443. We can enable them like this:</p>
+
+ <pre><code>ufw allow 80
+ufw allow 443</code></pre>
+
+ <p>But <code>ufw</code> additionally knows the typical ports of common serives, so you can also run this:</p>
+
+ <pre><code>ufw allow http
+ufw allow https</code></pre>
+
+ <p>And that will do the same thing. There are also other abbreviations for common port lists:</p>
+
+ <pre><code>ufw allow in 'WWW Full'</code></pre>
+
+
+ <p>To see these other "apps" that <code>ufw</code> knows by default, run <code>ufw app list</code></p>
+
+
+ <h3>Email: IMAP, POP3, and SMTP</h3>
+
+ <pre><code>ufw allow in IMAPS
+ufw allow in POP3
+ufw allow in SMTP
+ufw allow in 'Postfix SMTPS'
+ufw allow in 'Mail Submission'</pre></code>
+
+ <h2 id="fine-tuning-rules">Fine-Tuning Rules</h2>
+
+ <p>Instead of denying all ports by default, you may want to deny (ignores incoming requests) or reject (explicitly tells requests they're not allowed):</p>
+
+ <pre><code>ufw default allow in
+ufw deny in <strong>PORT</strong>
+ufw reject in <strong>PORT</strong>
+ufw reload</code></pre>
+
+ <p>You can add rules to comments to remember what they are there for:</p>
+
+ <pre><code>ufw allow in <strong>PORT</strong> comment 'Secret SSH'
+ufw reload
+ufw status verbose</code></pre>
+
+ <p>Output:</p>
+
+ <pre><code>To Action From
+-- ------ ----
+<strong>PORT</strong> ALLOW IN Anywhere # Secret SSH
+<strong>PORT</strong> (v6) ALLOW IN Anywhere (v6) # Secret SSH</pre></code>
+
+ <p>To deny outgoing ports:</p>
+
+ <pre><code>ufw deny out <strong>PORT</strong></code></pre>
+
+ <p>Ratelimiting is useful to protect against brute-force login attacks, like in SSH. Only IPv4 is supported for now. Enable it by running:</p>
+
+ <pre><code>ufw limit <strong>PORT</strong>/tcp</code></pre>
+
+ <p>To blocklist IP addresses:</p>
+
+ <pre><code>ufw deny from <strong>IP_ADDRESS</strong></code></pre>
+
+ <p>To read more what you can do with <code>ufw</code>, run:</p>
+
+ <pre><code>man ufw</code></pre>
+
+ <h2 id="recovering-from-losing-ssh">Recovering SSH</h2>
+
+ <p>
+ If you have accidentally firewalled yourself from logging on your computer, you can recover access by using your VPS's virtual console.
+ On Vultr, this is on your VPS's menu. To the right of the server name, It is the leftmost icon that looks like a monitor.
+ </p>
+
+ <a href="pix/ssh-01.png"><img src="pix/ssh-01.png" alt="View Console"></a>
+
+ <p>Log in through there, and disable ufw by typing:</p>
+
+ <pre><code>ufw disable</code></pre>
+
+
+ <h2 id="further-reading">Further Reading</h2>
+
+ <ul>
+ <li><a href="https://wiki.ubuntu.com/UncomplicatedFirewall">Ubuntu Wiki: UncomplicatedFirewall</a></li>
+ <li><a href="https://help.ubuntu.com/community/Gufw">Gufw (Graphical UFW)</a></li>
+ <li><code>man ufw</code></li>
+ </ul>
+
+ <strong>Contributor</strong> - <a href="https://shunter.xyz">shunter.xyz</a>
+ </main>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
+</body>
+</html>
diff --git a/xmpp.html b/xmpp.html
index d20cfd5..21841df 100644
--- a/xmpp.html
+++ b/xmpp.html
@@ -13,6 +13,8 @@
<nav></nav>
<main>
+ <img class=titleimg src="pix/xmpp.svg" alt="XMPP Logo and Icon">
+
<p>XMPP is a fantastically simple protocol that's usually used as a messenger.
It's highly extensible,
better than IRC,
@@ -49,10 +51,10 @@ Find the line that says <code>admins = { }</code> and to this we can specify one
</p>
<pre><code># To add one admin:
-admins = { "chad@landchad.net" }
+admins = { "chad@example.org" }
# We can add more than one by separating them by commas. (This file is written in Lua.)
-admins = { "chad@landchad.net", "chadmin@landchad.net" }</code></pre>
+admins = { "chad@example.org", "chadmin@example.org" }</code></pre>
<p>
Note that we have not created these accounts yet, we will do this <a href=#user>below</a>.
@@ -62,7 +64,7 @@ Note that we have not created these accounts yet, we will do this <a href=#user>
<p>
Find the line <code>VirtualHost "localhost"</code> and replace <code>localhost</code> with your domain.
-In our case, we will have <code>VirtualHost "landchad.net"</code>
+In our case, we will have <code>VirtualHost "example.org"</code>
</p>
<h3>Multi-User Chats</h3>
@@ -73,7 +75,8 @@ This is easily enough to enable.
In the config file, add the following:
</p>
-<pre><code>Component "<strong>chat.landchad.xyz</strong>" "muc"
+<pre><code>Component "<strong>chat.example.org</strong>" "muc"
+ modules_enabled = { "muc_mam" }
restrict_room_creation = "admin"</code></pre>
<p>
@@ -93,28 +96,6 @@ Read more about the <code>muc</code> plugin on the Prosody documentation page <a
</p>
</aside>
-
-<h3>End-to-end Encryption</h3>
-
-<p>
-Importantly, we'll want end-to-end encryption enabled for user privacy.
-</p>
-
-<p>
-Find the array beginning with <code>modules_enabled</code>.
-This includes a list of modules to be used.
-Add
-<code>"omemo_all_access";</code> to that list.
-</p>
-
-<p>
-This module is not installed by default,
-but you can easily download it by running the following command on the command prompt
-to download and install the module to the correcy directory.
-</p>
-
-<pre><code style=font-size:x-small>curl -sL https://hg.prosody.im/prosody-modules/raw-file/785389a2d2b3/mod_omemo_all_access/mod_omemo_all_access.lua &gt; /usr/lib/prosody/modules/mod_omemo_all_access.lua</code></pre>
-
<h3>Other things to check</h3>
<p>Check the config file for other settings you might want to change.
@@ -130,22 +111,10 @@ Nowadays, use can use Certbot to generate certificates and use a convenient comm
<p>
<strong>If you have multi-user chat enabled, be sure to get a certificate for that subdomain as well.</strong>
-I usually just create a dummy nginx site for each and run it with the <code>--nginx</code> option.
-This makes auto-renewal a little easier.
+Include the <code>--nginx</code> option assuming you have an Nginx server running.
</p>
-<!-- <pre><code>server { -->
-<!-- listen 80 ; -->
-<!-- listen [::]:80 ; -->
-<!-- root /var/www/html; -->
-<!-- index index.html index.htm index.nginx-debian.html; -->
-<!-- server_name <strong>muc.landchad.net</strong> ; -->
-<!-- location / { -->
-<!-- try_files $uri $uri/ =404; -->
-<!-- } -->
-<!-- }</code></pre> -->
-
-<pre><code>certbot --nginx</code></pre>
+<pre><code>certbot -d <strong>chat.example.org</strong> --nginx</code></pre>
<p>
Once you have the certificates for encryption, run the following to import them into Prosody.
@@ -170,7 +139,7 @@ Let's manually create the admin user we prepared for above.
Note that you can indeed do this in your XMPP client if you have not disabled registration, but this is how it is done on the command line:
</p>
-<pre><code>prosodyctl adduser chad@landchad.net</code></pre>
+<pre><code>prosodyctl adduser <strong>chad@example.org</strong></code></pre>
<p>This will prompt you to create a password as well.</p>
@@ -181,9 +150,43 @@ Note that you can indeed do this in your XMPP client if you have not disabled re
With any system service, use <code>systemctl reload</code> or <code>systemctl restart</code> to make the new settings active:
</p>
-<pre><code>systemctl reload prosody</code></pre>
+<pre><code>systemctl restart prosody</code></pre>
+
+<h2>Using your Server!</h2>
+
+<p>
+Once your server is set up, you just need an XMPP client to use your new and secure chat system.
+</p>
+
+<ul>
+ <li>GNU/Linux: <a href="https://dino.im/">Dino</a> or <a href="https://gajim.org/">Gajim</a></li>
+ <li>Windows: <a href="https://gajim.org/">Gajim</a> also runs on Windows.</li>
+ <li>Android: <a href="https://conversations.im/">Conversations.im</a></li>
+ <li>Mac/iOS: <a href="https://monal.im/">Monal IM</a> or <a href="https://siskin.im/">Siskin</a> for iOS alone</li>
+ <li>command-line (GNU/Linux, MacOS, Windows): <a href="https://profanity-im.github.io/">Profanity</a></li>
+ <li><a href="https://xmpp.org/software/clients.html">See a more complete list kept by XMPP</a></li>
+</ul>
+
+<p>
+Install whichever of these clients you want on your computer or phone and you can log into your new XMPP server with the account you made.
+Note that if you enabled public registration, anyone can create an account on your server through one of these clients.
+</p>
+
+<h3>Account addresses</h3>
+
+<p>
+XMPP account addressed look just like email addresses: <code><strong>username@example.org</strong></code>.
+You can message any account on any XMPP server on the internet with that format.
+</p>
+
+<h3>Note on MUCs (multi-user chats)</h3>
+
+<p>
+Remember that MUCs are kept on a separate subdomain that we created and should've gotten a certificate for above, for example, <code><strong>chat.example.org</strong></code>.
+Chatrooms are created and referred to in the following format: <code><strong>#chatroomname@chat.example.org</strong></code>.
+</p>
</main>
- <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><li><a href="index.html"><img src="pix/chad.gif" alt="chad"></a></li><li><a href="rss.xml"><img src="pix/rss.svg" alt="RSS"></a></li><li><a href="pix/btc.png"><img src="pix/btc.svg" alt="BTC"></a></li><li><a href="pix/xmr.png"><img src="pix/xmr.svg" alt="XMR"></a></li><li><a href="https://github.com/lukesmithxyz/landchad"><img src="pix/git.svg" alt="Github"></a></footer>
+ <footer><a href="https://landchad.net">LandChad.net</a></br>Because Everyone should be an Internet LandChad.</br><a href="index.html"><li><img src="pix/chad.gif" alt="chad"></li></a><a href="rss.xml"><li><img src="pix/rss.svg" alt="RSS"></li></a><a href="pix/btc.png"><li><img src="pix/btc.svg" alt="BTC"></li></a><a href="pix/xmr.png"><li><img src="pix/xmr.svg" alt="XMR"></li></a><a href="https://github.com/lukesmithxyz/landchad"><li><img src="pix/git.svg" alt="Github"></li></a></footer>
</body>
</html>