summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--content/auth.md2
-rw-r--r--content/basic/dns.md36
-rw-r--r--content/basic/domain.md31
-rw-r--r--content/basic/nginx.md18
-rw-r--r--content/calibre.md2
-rw-r--r--content/cgit.md8
-rw-r--r--content/coturn.md5
-rw-r--r--content/dendrite.md292
-rw-r--r--content/dokuwiki.md4
-rw-r--r--content/ejabberd.md83
-rw-r--r--content/git.md2
-rw-r--r--content/i2p.md116
-rw-r--r--content/irc.md2
-rw-r--r--content/jitsi.md2
-rw-r--r--content/mail/inbox.md6
-rw-r--r--content/mail/rdns.md3
-rw-r--r--content/mail/smtp.md2
-rw-r--r--content/mail/validate.md29
-rw-r--r--content/matrix.md37
-rw-r--r--content/monerod.md233
-rw-r--r--content/mumble.md144
-rw-r--r--content/nextcloud.md32
-rw-r--r--content/prosody.md89
-rw-r--r--content/radicale.md6
-rw-r--r--content/rainloop.md4
-rw-r--r--content/rss-bridge.md4
-rw-r--r--content/sshkeys.md16
-rw-r--r--content/tor.md4
-rw-r--r--content/transmission.md844
-rw-r--r--content/wireguard.md17
-rw-r--r--static/pix/dns-epik.pngbin82393 -> 76446 bytes
-rw-r--r--static/pix/monerod/monerod-step-1.webpbin0 -> 31984 bytes
-rw-r--r--static/pix/monerod/monerod-step-2.webpbin0 -> 33428 bytes
-rw-r--r--static/pix/monerod/monerod-step-3.webpbin0 -> 16130 bytes
-rw-r--r--static/pix/monerod/monerod-step-4.webpbin0 -> 10362 bytes
-rw-r--r--static/pix/monerod/monerod-step-5.webpbin0 -> 40168 bytes
-rw-r--r--static/pix/mumble.svg127
-rw-r--r--static/pix/mumble/mumble-1.pngbin0 -> 33792 bytes
-rw-r--r--static/pix/mumble/mumble-2.pngbin0 -> 33810 bytes
-rw-r--r--static/pix/transmission-web-interface.pngbin0 -> 10792 bytes
-rw-r--r--static/pix/transmission.pngbin0 -> 16039 bytes
-rw-r--r--static/pix/xmr.svg8
43 files changed, 2003 insertions, 207 deletions
diff --git a/README.md b/README.md
index 37acf86..b1bd959 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ This site is compiled and organized with Hugo, using [this very simple theme](ht
## Submission guidelines
-- Guides should be made for the most recent stable version of Debian. (Now Debian 11.)
+- Guides should be made for the most recent stable version of Debian. (Now Debian 12.)
- Follow the general style of pre-existing articles.
- use the root user (i.e. no `sudo`) unless there is a specific need.
- do not preface commands with `$` or `#` or anything.
diff --git a/content/auth.md b/content/auth.md
index 88a5fee..b38cb88 100644
--- a/content/auth.md
+++ b/content/auth.md
@@ -132,5 +132,3 @@ http {
Now check your configuration with `nginx -t`
Reload nginx and you\'re good to go!
-
-**Contributor** - [tomfasano.net](https://tomfasano.net)
diff --git a/content/basic/dns.md b/content/basic/dns.md
index c6d3d42..5225f96 100644
--- a/content/basic/dns.md
+++ b/content/basic/dns.md
@@ -10,30 +10,28 @@ can connect the two using DNS records. DNS (domain name system) records
are usually put into your registrar and direct people looking up your
website to the server where your website and other things will be.
-Get your IPv4/IPv6 addresses from Vultr and put them into A/AAAA records
-on Epik. Simple process, takes a minute, but here\'s a guide with a
-million images just so you know.
+Get your IPv4/IPv6 addresses from your VPS provider and put them into A/AAAA
+records on your registrar. Simple process, takes a minute, but here\'s a guide
+with a million images just so you know.
## Open up your Registrar
-As before, we will be using
-[Epik](https://www.epik.com/?affid=we2ro7sa6) as a registrar and
-[Vultr](https://www.vultr.com/?ref=8384069-6G) as a server host. Go
-ahead and log into your accounts on both. Open up Epik, or your
-registrar, and click on your domain and then a choice for \"DNS
-records.\" This is the screen you\'ll want to see on Epik.
+As before, we will be using any registrar of your choice and
+[Vultr](https://www.vultr.com/?ref=8384069-6G) as a server host. Go ahead and
+log into your accounts on both. Open up your registrar, or your registrar, and
+click on your domain and then a choice for \"DNS records.\" You'll want to see
+something like this on your registrar's site.
-{{< img alt="Blank Epik DNS records" src="/pix/dns-epik.png" link="/pix/dns-epik.png" >}}
+{{< img alt="Blank records" src="/pix/dns-epik.png" link="/pix/dns-epik.png" >}}
-Note that we are on the \"External Hosts (A, AAAA)\" tab by default.
-Epik sometimes adds records to this page once you buy a domain. If they
-did, you can go ahead and delete them so they look clean like the
-picture above.
+Note that we are on the \"External Hosts (A, AAAA)\" tab by default. There may
+be default settings set by your registrar. If there are, you can go ahead and
+delete them so they look clean like the picture above.
**All we have to do now is get our IP addresses from Vultr and add new
DNS records that will send connections to our server.**
-Keep the Epik tab open and open Vultr and we will copy-and-paste our IP
+Keep the registrar tab open and open Vultr and we will copy-and-paste our IP
addresses in.
## Find your server\'s IP addresses
@@ -45,8 +43,8 @@ attach to it). That is my **IPv4** address.
{{< img src="/pix/dns-ipv4.png" alt="See the IPv4 address?" link="/pix/dns-ipv4.png" >}}
-Copy your IPv4 address and on Epik, click the \"Add Record\" record
-button and add two A entries pasting in your IPv4 address like I\'ve
+Copy your IPv4 address and on your registrar's site, click the \"Add Record\"
+record button and add two A entries pasting in your IPv4 address like I\'ve
done for mine here.
{{< img src="/pix/dns-ipv4-done.png" alt="IPv4 complete" link="/pix/dns-ipv4-done.png" >}}
@@ -74,8 +72,8 @@ Now just click on the **IPv6** submenu to reveal your IPv6 address.
{{< img alt="The IPv6 address" src="/pix/dns-ipv6.png" link="/pix/dns-ipv6.png" >}}
That ugly looking sequence of numbers and letters with colons in between
-(`2001:19f0:5:ccc:5400:03ff:fe58:324a`) is my **IPv6** address. Yours
-will look something like it. Now let\'s put it into Epik. This time, be
+(`2001:19f0:5:ccc:5400:03ff:fe58:324a`) is my **IPv6** address. Yours will look
+something like it. Now let\'s put it into your registrar's site. This time, be
sure to select to put in AAAA records as below:
{{< img src="/pix/dns-ipv6-done.png" alt="IPv6 complete" link="/pix/dns-ipv6-done.png" >}}
diff --git a/content/basic/domain.md b/content/basic/domain.md
index 67cdd79..a6b762b 100644
--- a/content/basic/domain.md
+++ b/content/basic/domain.md
@@ -25,32 +25,39 @@ So let\'s register your domain name!
## How
-Domains can be registered at any accredited <dfn>registrar</dfn>. In this
-guide, I will use the registrar
-[Epik](https://www.epik.com/?affid=we2ro7sa6) because it is one of the
-more high quality and easy to use. The guides on this site will use
-Epik, but if you choose to register your domain with one of the [many,
-many other registrars](https://www.icann.org/en/accredited-registrars),
-you can still do most of what Epik does, albeit options and settings
-might appear in different menus.
+Domains can be registered at any accredited <dfn>registrar</dfn> and there are
+[a lot to choose from](https://www.icann.org/en/accredited-registrars). Some major names are
+[Host Gator](https://www.hostgator.com/domains),
+[Blue Host](https://www.bluehost.com/domains),
+[Name Cheap](https://www.namecheap.com/domains/) or
+[Dream Host](https://www.dreamhost.com/domains/).
+
+There are also sites that are more private, like [Njalla](https://njal.la/) and
+[Cheap Privacy](https://cheapprivacy.ru/), which register a domain for you
+under their name, but still allow you access to it. (Normally all websites must
+be registered with the ICANN with a real name and address, but these sites
+allow you to bypass that.)
+
+Choosing a registrar is not permanent, and you can transfer domains to a
+different registrar if you get a better deal later, so in most cases, you can just
+choose one and let's head on...
### Basic info about domain names
-- Domain names usually require a *very* small year fee to keep
+- Domain names usually require a *very* small yearly fee to keep
registered, usually around \$12 for most generic TLDs. There are
some \"specialty\" TLDs that are more expensive, but `.com`, `.xyz`
and other basic TLDs are that cheap.
- Once you own a domain, it is yours as long as you pay the yearly
fee, but you can also sell it to someone for however much you want.
-- Domain names do not hold your data or your website, instead, you add
+- Domain names do not hold your data or your website; instead, you add
\"DNS settings\" that direct people connecting to your domain to
your IP address. The purpose of a domain name is so that people
don\'t have to remember your IP address to find your website!
### Looking for domain names
-Let\'s go to [Epik\'s site](https://www.epik.com/?affid=we2ro7sa6) and
-you can search for domain names.
+Let\'s go to our registrar's site and you can search for domain names.
You can look for whatever domain name you want. Domains that are already
bought and owned by someone else might have the option to \"Backorder,\"
diff --git a/content/basic/nginx.md b/content/basic/nginx.md
index 3ec3af7..d76fb54 100644
--- a/content/basic/nginx.md
+++ b/content/basic/nginx.md
@@ -33,7 +33,7 @@ for your password, and you can just copy or type in the password from
Vultr\'s site.
If you get an error here, you might not have done your [DNS
-settings](dns.html) right. Double check those. Note you can also replace
+settings](/basic/dns) right. Double check those. Note you can also replace
the `example.org` with your IP address, but you\'ll want to fix your DNS
settings soon.
@@ -51,7 +51,7 @@ apt install nginx
The first command checks for packages that can be updated and the second
command installs any updates.
-The third command installs `nginx` (pronounced Engine-X) which is the
+The third command installs `nginx` (pronounced Engine-X), which is the
web server we\'ll be using, along with some other programs.
### Our nginx configuration file
@@ -115,7 +115,7 @@ in `/var/www/`. Name the directory in that whatever you want.
a website, say `landchad.net`, you are actually going to a file at
`landchad.net/index.html`. That\'s all that is. Note that that this in
concert with the line above mean that `/var/www/landchad/index.html`, a
-file on our computer that we\'ll create will be the main page of our
+file on our computer that we\'ll create, will be the main page of our
website.
Lastly, the `location` block is really just telling the server how to
@@ -125,14 +125,14 @@ powerful, but this is all we need them for now.
### Create the directory and index for the site
We\'ll actually start making a \"real\" website later, but let\'s go
-ahead and create a little page that will appear on when someone looks up
+ahead and create a little page that will appear when someone looks up
the domain.
```sh
mkdir /var/www/{{<hl>}}mysite{{</hl>}}
```
-Now let\'s create and index file inside of that directory which will
+Now let\'s create an index file inside of that directory, which will
appear when the website is accessed:
```sh
@@ -167,7 +167,7 @@ systemctl reload nginx
## The Firewall {#firewall}
-Vultr and some other VPS automatically install and enable `ufw`, a
+Vultr and some other VPSes automatically install and enable `ufw`, a
firewall program. This will block basically everything by default, so we
have to change that. If you don\'t have `ufw` installed, you can skip
this section.
@@ -185,7 +185,7 @@ encrypted connections. We will certainly need that for the next page.
<aside>
As you add more services to your website, they might need you to open more ports, but that will be mentioned on individual articles.
-(It should be noted that some local services only running for other services on your machine, so you *don't* need to open ports for every process running locally, *only* those that directly interact with the internet, although it's common to run those through NginX for simplicity and security.)
+(It should be noted that some local services run only for other services on your machine, so you *don't* need to open ports for every process running locally, *only* those that directly interact with the internet, although it's common to run those through Nginx for simplicity and security.)
</aside>
@@ -199,9 +199,9 @@ someone could exploit it. Open the main Nginx config file
Uncomment it, and reload Nginx.
Remember to [keep your server software up to
-date](maintenance.html#update) to get the latest security fixes!
+date](/../maintenance#update) to get the latest security fixes!
-## We now have running website!
+## We now have a running website!
At this point you can now type in your website in your browser and this
webpage will appear!
diff --git a/content/calibre.md b/content/calibre.md
index 9768acf..e1e9faa 100644
--- a/content/calibre.md
+++ b/content/calibre.md
@@ -94,7 +94,7 @@ server {
}
```
-Issue a Let\'s Encrypt certificate. [Detailed instructions and additional information](/certbot).
+Issue a Let\'s Encrypt certificate. [Detailed instructions and additional information](/basic/certbot).
```sh
certbot --nginx
diff --git a/content/cgit.md b/content/cgit.md
index ce6214c..13d4b2b 100644
--- a/content/cgit.md
+++ b/content/cgit.md
@@ -53,8 +53,8 @@ server {
fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
fastcgi_param PATH_INFO $uri;
fastcgi_param GIT_HTTP_EXPORT_ALL 1;
- fastcgi_param GIT_PROJECT_ROOT /srv/git;
- fastcgi_param HOME /srv/git;
+ fastcgi_param GIT_PROJECT_ROOT /var/git;
+ fastcgi_param HOME /var/git;
fastcgi_pass unix:/run/fcgiwrap.socket;
}
@@ -90,11 +90,11 @@ root-title={{<hl>}}Chad's git server{{</hl>}}
root-desc={{<hl>}}A web interface to LandChad's git repositories, powered by Cgit{{</hl>}}
# The location where git repos are stored on the server
-scan-path=/srv/git/
+scan-path=/var/git/
```
This configuration assumes you followed the [git hosting guide](/git)
-and store your repositories on the `/srv/git/` directory.
+and store your repositories on the `/var/git/` directory.
Cgit\'s configuration allows changing many settings, as documented on
the cgitrc(5) manpage installed with Cgit.
diff --git a/content/coturn.md b/content/coturn.md
index 614b87c..b49c47c 100644
--- a/content/coturn.md
+++ b/content/coturn.md
@@ -102,6 +102,11 @@ systemctl restart coturn
At this stage, you should look in your application's own guide on how to set the TURN and STUN server settings. Configure it to point at **turn.example.org** and use either your **username and password pair** or your super-secure **authentication secret.**
+- [How to configure TURN on ejabberd](/ejabberd#voice-and-video-calls)
+- [How to configure TURN on Prosody](/prosody#voice-and-video-calls)
+- [How to configure TURN on Matrix Synapse](/matrix#voice-and-video-calls)
+- [How to configure TURN on Matrix Dendrite](/dendrite#voice-and-video-calls)
+
Congratulations! You've successfully setup a Coturn server!
---
diff --git a/content/dendrite.md b/content/dendrite.md
new file mode 100644
index 0000000..c949a9d
--- /dev/null
+++ b/content/dendrite.md
@@ -0,0 +1,292 @@
+---
+title: "Matrix Dendrite"
+date: 2023-03-21
+icon: 'element.svg'
+tags: ['service']
+short_desc: "A faster server implementation of Matrix."
+---
+
+The Matrix protocol's default implementation, [Synapse,](/matrix) is very memory and processor hungry, mostly due to it being written in the *interpreted Python programming language.* This means that running Synapse on less powerful servers may **take a lot of resources away** from other services. If you need a more efficient and less memory-intensive but still fully functional Matrix server, then [Dendrite](https://github.com/matrix-org/dendrite) is for you.
+
+## Prerequisities
+
+### DNS Records and Delegation
+
+You are **not required** to run a Matrix server under a subdomain (like **matrix.example.org**), regardless of server software. You can run your server under **example.org** to ensure usernames and rooms look like `@user:example.org` and `#room:example.org` respectively.
+
+Because Matrix uses **HTTP** for transport over the SSL ports (443 and 8448), you'll have to configure NGINX for it to work. This can cause confusion, especially if you're running both a [static website](/basic/nginx/) and Matrix server under the same domain (like **example.org**).
+
+Depending on your setup, there are 2 different configurations to achieve this:
+
+1. Your *desired* domain (**example.org**) has an [A DNS record](/basic/dns/) that already poinst to your desired Matrix server, so you can configure this or add to your existing NGINX static site configuration to setup Matrix.
+
+2. You wish to use Matrix with your *desired* domain (**example.org**) but this domain's A record points to a different server, accessible through another domain (like **matrix.example.org**). In this case, look into [delegation.](https://matrix-org.github.io/synapse/latest/delegate.html)
+
+
+### NGINX Configuration
+
+Here's an example configuration for a Matrix server running under **example.org:**
+
+```nginx
+server {
+ server_name {{<hl>}}example.org{{</hl>}};
+
+ listen 80;
+ listen [::]:80;
+
+ listen 443 ssl http2 default_server;
+ listen [::]:443 ssl http2 default_server;
+
+ listen 8448 ssl http2 default_server;
+ listen [::]:8448 ssl http2 default_server;
+
+ location ~* ^(\/_matrix|\/_synapse|\/_client) {
+ proxy_pass http://localhost:8008;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ client_max_body_size {{<hl>}}50M{{</hl>}};
+ }
+
+ # These sections are required for client and federation discovery
+ # (AKA: Client Well-Known URI)
+ location /.well-known/matrix/client {
+ return 200 '{"m.homeserver": {"base_url": "https://{{<hl>}}example.org{{</hl>}}"}}';
+ default_type application/json;
+ add_header Access-Control-Allow-Origin *;
+ }
+
+ location /.well-known/matrix/server {
+ return 200 '{"m.server": "{{<hl>}}example.org{{</hl>}}:443"}';
+ default_type application/json;
+ add_header Access-Control-Allow-Origin *;
+ }
+}
+```
+
+Let's say you also want to run a **static website** under **example.org.** This can be achieved by adding these usual lines under the `server` section:
+
+```nginx
+ # Basic static site configuration, like any other site
+ root /var/www/{{<hl>}}example.org{{</hl>}};
+ index index.html;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+```
+
+#### Certbot Certificates
+
+Finally, make sure to download and enable TLS certificates for this setup by using the `certbot` command:
+
+```sh
+certbot --nginx -d {{<hl>}}example.org{{</hl>}}
+```
+
+## Installation
+
+Dendrite has no official distribution packages at the time of writing. To install and run it, you must first install *the Go programming language* and then compile the Dendrite software from source.
+
+### Installing Go
+
+First, download the latest Go tarball:
+```sh
+curl -fLO "https://dl.google.com/go/$(curl https://go.dev/VERSION?m=text).linux-amd64.tar.gz"
+```
+
+Then, extract the contents to `/usr/local`, which will create the directory `/usr/local/go`:
+```sh
+tar -C /usr/local -xzfv go*.tar.gz
+```
+
+Then finally, make sure the `/usr/local/go/bin/` path is accessible in the `$PATH` variable for every user by editing `/etc/profile` and adding the following line:
+
+```sh
+export PATH=$PATH:/usr/local/go/bin
+```
+
+### Compiling and Installing Dendrite
+
+Besides Go, we also need the `build-essential` package to compile software:
+
+```sh
+apt install build-essential
+```
+
+Now download the Dendrite repository using `git` and change directory to it:
+
+```sh
+git clone https://github.com/matrix-org/dendrite
+cd dendrite
+```
+Finally, compile Dendrite using `go build`:
+
+```sh
+go build -o bin/ ./cmd/...
+```
+
+*This might take a few minutes,* but once the process is finished you should find the final Dendrite programs populating the `bin/` directory.
+
+## Configuration
+
+To configure Dendrite, begin by coping the `dendrite-sample.yaml` configuration file to `dendrite.yaml`:
+
+```sh
+cp dendrite-sample.yaml dendrite.yaml
+```
+
+To configure your domain, edit the following under the `global:` section:
+
+```yaml
+server_name: {{<hl>}}example.org{{</hl>}}
+```
+
+### Server Signing Keys
+
+Generate the signing keys used by your homeserver with the following command, ran from the Dendrite repository:
+
+```sh
+./bin/generate-keys --private-key matrix_key.pem
+```
+
+You can also import old keys from Synapse, by specifying their file path in the `old_private_keys:` variable in `dendrite.yaml`.
+
+### Database Configuration
+
+By default, Dendrite will create SQLite databases for all its various components. On most server deployments however, it is beneficial to run Dendrite with a more efficient database backend, like PostgreSQL.
+
+Begin by installing PostgreSQL:
+
+```sh
+apt install postgresql
+```
+
+Then start the daemon:
+
+```sh
+systemctl restart postgresql
+```
+
+Now create a user named `dendrite` to manage your database:
+
+```sh
+su -c "createuser --pwprompt dendrite" postgres
+```
+
+And finally, create the actual database:
+
+```sh
+su -c "psql -c 'CREATE DATABASE dendrite ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER dendrite;'" postgres
+```
+
+Now we can configure this in `dendrite.yaml` using the `connection_string:` option under the `database:` section:
+
+```yaml
+ database:
+ connection_string: postgres://dendrite:{{<hl>}}password{{</hl>}}@localhost/dendrite?sslmode=disable
+ max_open_conns: 90
+ max_idle_conns: 5
+ conn_max_lifetime: -1
+```
+
+**Important:** If you find `database:` sub-sections under the individual Dendrite modules in `dendrite.yaml` (`app_service_api`, `federation_api`, `key_server`, `media_api`, `mscs`, `room_server`, `sync_api` and `user_api`), make sure to **comment these out** as these would override the global `database` configuration.
+
+### Voice and Video Calls
+
+Dendrite supports native voice and video calling by connecting to a compatible TURN and STUN server.
+
+Begin by setting up the [coturn](/coturn) TURN server using the guide provided, setting either a shared secret or a username-password pair for authentication.
+
+Then edit the `turn:` section in `dendrite.yaml`:
+
+```yaml
+ turn:
+ turn_user_lifetime: "5m"
+ turn_uris:
+ - turn:{{<hl>}}turn.example.org{{</hl>}}?transport=udp
+ - turn:{{<hl>}}turn.example.org{{</hl>}}?transport=tcp
+
+ turn_shared_secret: "{{<hl>}}your_shared_secret{{</hl>}}"
+
+ # If your TURN server requires static credentials, then you will need to enter
+ # them here instead of supplying a shared secret. Note that these credentials
+ # will be visible to clients!
+ # turn_username: ""
+ # turn_password: ""
+```
+
+### File Directory and Ownership
+
+Like [Synapse,](/matrix) it's recommended you place the Dendrite program files in `/opt` to keep your server organized:
+
+```sh
+mv dendrite/ /opt/
+```
+
+It's also recommended you create a `dendrite` user, who will own the `/opt/dendrite` directory, so it can be used to run Dendrite as a service:
+
+```sh
+useradd dendrite -d /opt/dendrite
+chown -R dendrite:dendrite /opt/dendrite
+```
+
+### Setting up a systemd Service
+
+Now setup a **systemd service** in `/etc/systemd/system/dendrite.service` to run Dendrite automatically for you. Make sure to set the `WorkingDirectory` to the directory where your Dendrite repository is located!
+
+```systemd
+[Unit]
+Description=Dendrite (Matrix Homeserver)
+After=syslog.target
+After=network.target
+After=postgresql.service ## Remove this if you're not using PostgreSQL
+
+[Service]
+Environment=GODEBUG=madvdontneed=1
+RestartSec=2s
+Type=simple
+User={{<hl>}}dendrite{{</hl>}}
+Group={{<hl>}}dendrite{{</hl>}}
+WorkingDirectory={{<hl>}}/opt/dendrite/{{</hl>}}
+ExecStart={{<hl>}}/opt/dendrite/bin/dendrite{{</hl>}}
+Restart=always
+LimitNOFILE=65535
+
+[Install]
+WantedBy=multi-user.target
+```
+
+Refresh the systemd daemon configuration by running:
+
+```sh
+systemctl daemon-reload
+```
+
+And finally, **run Dendrite** by running:
+
+```sh
+systemctl restart dendrite
+```
+
+## Using Dendrite
+
+### Creating Users
+
+To create users on the Dendrite server, first ensure it is running. Then, enter a secret value into the `registration_shared_secret:` field under the `client_api` section:
+
+```yaml
+registration_shared_secret: "your_secret_string"
+```
+
+ Then, use the `./bin/create-account` tool located in its repository:
+
+```sh
+./bin/create-account -config dendrite.yaml -username {{<hl>}}user{{</hl>}} -admin
+```
+This will automatically prompt you for a password.
+
+Congratulations! You've installed the Matrix Dendrite homeserver. Now you can login with any [Matrix client](https://matrix.org/clients/) you wish, and chat securely.
+
+---
+Written by [Denshi.](https://denshi.org)
+Donate Monero at:
+`48dnPpGgo8WernVJp5VhvhaX3u9e46NujdYA44u8zuMdETNC5jXiA9S7JoYMM6qRt1ZcKpt1J3RZ3JPuMyXetmbHH7Mnc9C`
diff --git a/content/dokuwiki.md b/content/dokuwiki.md
index 1dfb96b..6f224d0 100644
--- a/content/dokuwiki.md
+++ b/content/dokuwiki.md
@@ -69,7 +69,7 @@ server {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REDIRECT_STATUS 200;
- fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ fastcgi_pass unix:/var/run/php/php-fpm.sock;
# fastcgi_pass unix:/var/run/php5-fpm.sock; #old php version
}
}
@@ -90,7 +90,7 @@ certbot --nginx
Restart nginx and php in order for the changes to take effect.
```sh
-systemctl restart nginx && systemctl restart php7.4-fpm
+systemctl restart nginx && systemctl restart php8.2-fpm
```
Finally, go to `wiki.yourwebsite.com/install.php` to finish the installation process. Read up [the documentation](https://www.dokuwiki.org/installer) in order to understand what each of those itens mean.
diff --git a/content/ejabberd.md b/content/ejabberd.md
index b8579cd..eff3b36 100644
--- a/content/ejabberd.md
+++ b/content/ejabberd.md
@@ -17,10 +17,26 @@ Ejabberd presumes that you have already created all the **required and optional
Depending on the usecase, you may need any or all of the following domains for XMPP functionality:
- **example.org** - Your XMPP hostname
-- **conference.example.org** - For Multi User Chats (MUCs)
-- **upload.example.org** - For file upload support
-- **proxy.example.org** - For SOCKS5 proxy support
-- **pubsub.example.org** - For publish-subscribe support (A fancier RSS)
+- **conference.example.org** - For `mod_muc`, Multi User Chats (MUCs)
+- **upload.example.org** - For `mod_http_upload`, file upload support
+- **proxy.example.org** - For `mod_proxy65`, SOCKS5 proxy support
+- **pubsub.example.org** - For `mod_pubsub`, publish-subscribe support (A fancier RSS)
+
+Only the **example.org** domain is required for basic, private chat usage.
+If you do **not** wish to use a certain domain, just disable it's associated module and ejabberd won't complain when it can't find it's associated certificate.
+For example, if you don't want [Publish-Subscribe](https://xmpp.org/extensions/xep-0060.html) support, just comment out the `mod_pubsub` config in `/etc/ejabberd.yml`:
+
+```yml
+## mod_pubsub:
+## access_createnode: pubsub_createnode
+## plugins:
+## - flat
+## - pep
+## force_node_config:
+## ## Avoid buggy clients to make their bookmarks public
+## storage:bookmarks:
+## access_model: whitelist
+```
This guide will assume **all these subdomains** have been created.
@@ -175,6 +191,11 @@ PostgreSQL is available in the Debian repositories:
apt install postgresql
```
+In addition, you will have to install the **appropriate headers for Erlang,** the language ejabberd is written in, so it can actually interact with the PostgreSQL server:
+```sh
+apt install erlang-p1-pgsql
+```
+
Start the PostgreSQL daemon to begin using it:
```sh
@@ -213,16 +234,37 @@ sql_server: "localhost"
sql_database: "{{<hl>}}ejabberd{{</hl>}}"
sql_username: "{{<hl>}}ejabberd{{</hl>}}"
sql_password: "{{<hl>}}psql_password{{</hl>}}"
+
+default_db: sql
```
+That line at the end sets **every module's database** to default to the `sql` backend. This includes the `mod_mam` module, so all our data is being stored with PostgreSQL.
+
+### Voice and Video Calls
+
+Ejabberd supports the **TURN** and **STUN** protocols to allow internet users behind NATs to perform voice and video calls with other XMPP users. **This is enabled by default using [ejabberd_stun](https://docs.ejabberd.im/admin/configuration/listen#ejabberd-stun-1).**
+
+**However,** if you plan on running ejabberd alongside **other applications** that require TURN and STUN, such as Matrix, then you'll have to setup your own external TURN server using Coturn.
-Once you've ensured your database name, username and password are all correct, enable SQL storage for `mod_mam`:
+#### Setup with Coturn and `mod_stun_disco`
+
+Firstly, setup a TURN and STUN server with [Coturn,](/coturn) using an **authentication secret.**
+
+Then, edit `mod_stun_disco` to contain the appropriate information for
+your turnserver:
```yml
-mod_mam:
- ## (Other parameters above)
- db_type: sql
+ mod_stun_disco:
+ secret: "{{<hl>}}your_auth_secret{{</hl>}}"
+ services:
+ -
+ host: {{<hl>}}turn.example.org{{</hl>}}
+ type: stun
+ -
+ host: {{<hl>}}turn.example.org{{</hl>}}
+ type: turn
```
+
## Using ejabberd
### Registering the Admin User
@@ -252,31 +294,6 @@ your ejabberd server from this web interface:
{{< img src="/pix/ejabberd-admin.webp" >}}
-## TURN & STUN for Calls
-
-Ejabberd supports the **TURN** and **STUN** protocols to allow internet users behind NATs to perform voice and video calls with other XMPP users. **This is enabled by default using [ejabberd_stun](https://docs.ejabberd.im/admin/configuration/listen#ejabberd-stun-1).**
-
-**However,** if you plan on running ejabberd alongside **other applications** that require TURN and STUN, such as Matrix, then you'll have to setup your own external TURN server using Coturn.
-
-### Setup with Coturn and `mod_stun_disco`
-
-Firstly, setup a TURN and STUN server with [Coturn,](/coturn) using an **authentication secret.**
-
-Then, edit `mod_stun_disco` to contain the appropriate information for
-your turnserver:
-
-```yml
- mod_stun_disco:
- secret: "{{<hl>}}your_auth_secret{{</hl>}}"
- services:
- -
- host: {{<hl>}}turn.example.org{{</hl>}}
- type: stun
- -
- host: {{<hl>}}turn.example.org{{</hl>}}
- type: turn
-```
-
## Further Configuration
For a deeper look into all the modules and options, have a look at the following ejabberd documentation:
diff --git a/content/git.md b/content/git.md
index f11d79d..7cb0121 100644
--- a/content/git.md
+++ b/content/git.md
@@ -100,7 +100,7 @@ chown git:git -R /var/git/.ssh # Make the created directory and contents to be o
### Syncing a new repository with your server
-How that we've set that up, we can push a repository we have on our computer to
+Now that we've set that up, we can push a repository we have on our computer to
that newly created bare repo. First, on our local computer, we run a command like this:
```sh
diff --git a/content/i2p.md b/content/i2p.md
index d0b2edb..8dcb7cb 100644
--- a/content/i2p.md
+++ b/content/i2p.md
@@ -7,38 +7,40 @@ tags: ['service']
short_desc: "A private and uncensorable web-layer similar to Tor."
---
-Now you have a website, why not offer it in a private alternative such
-as the Invisible Internet?
+Now you have a website, why not offer it in a private alternative such as the Invisible Internet?
## Setting up I2P
-There are 2 main I2P implementations, I2P and i2pd, we are using i2pd in
-this guide because it\'s easier to use in servers.
+There are 2 main I2P implementations, I2P and i2pd, we are using i2pd in this guide because it's easier to use on servers.
### Installing I2P
-i2pd is in most repos, in debian/ubuntu you can install it simply with
+We need to [add the i2pd repos to our system](https://repo.i2pd.xyz/) to get the latest version of i2pd:
+
+Install apt-transport-https and gpg package:
```sh
-apt install i2pd
+apt install apt-transport-https gpg
```
-### Enabling I2P
+Automatically add the repository with a script:
+
+```sh
+wget -q -O - https://repo.i2pd.xyz/.help/add_repo | bash -s -
+```
-We are going to create a user for i2pd, because i2pd finds the
-configuration files in its home directory. And it\'s easier (and more
-tidy) to have it in a separate user:
+After that you can install i2pd as any other software package:
```sh
-useradd -m i2p -s /bin/bash
-su -l i2p
-mkdir ~/.i2pd
-cd ~/.i2pd
+apt update
+apt install i2pd
```
-Now that you\'re in \~/.i2pd, you have to create a file named
-\"tunnels.conf\". Which is the config file for every hidden service
-you\'re offering over I2P, the content should be like this:
+### Enabling I2P
+
+Next we have to configure the i2pd daemon, the configuration is located at `/etc/i2pd/`.
+
+Edit the `tunnels.conf` file and add the following configuration to the file:
```systemd
[example]
@@ -48,27 +50,73 @@ port = 8080
keys = example.dat
```
+You can comment or remove the tunnels that are added by default in the configuration file.
+
+#### Optional: Generating a Vanity Address
+
+If you run `i2pd` with the configuration above, it will generate a random private key (`example.dat`) for your website at `/var/lib/i2pd/` with a matching address made up of 52 random characters, derived from this same key.
+
+If you instead pre-generate a private key for your website, you can use brute-force computation to make a "vanity" address, such as the following:
+```
+{{<hl>}}chad{{</hl>}}aor3jc08ht340c30mg5cf340j395gj095kuazj5tokipr34f.32.i2p
+```
+
+To accomplish this, a set of tools named `i2pd-tools` can be installed.
+
+Begin by cloning their repository:
+```sh
+git clone --recursive https://github.com/purplei2p/i2pd-tools
+```
+
+The repository comes with a dependency installation script included. Run this to list the compilation dependencies you'll need, and install them:
+```sh
+cd i2pd-tools
+sh dependencies.sh
+```
+
+Then compile using the `make` command:
+```sh
+make
+```
+
+This will build a variety of useful tools for i2p, with `vain` being the command of interest to generate an address:
+```sh
+./vain {{<hl>}}chad{{</hl>}}
+```
+This command will begin running and output a new set of private keys named `private.dat` to the same directory it's ran from. Copy this file to your i2p configuration and you'll have your vanity address:
+
+```sh
+cp private.dat /var/lib/i2pd/example.dat
+```
+
+#### Optional: Authentication Strings for Registrars
+
+I2P has various **registrars** that let users link their long I2P addresses to shorter, more memorable ones, like `example.i2p`. To actually register your site on one of these registrars, you will need an **authentication string.** Luckily, `i2pd-tools` includes such a tool in their repository:
+
+```sh
+./regaddr private.dat {{<hl>}}example.2ip{{</hl>}} > {{<hl>}}auth_string.txt{{</hl>}}
+```
+
+The command above will save the string to a file named `auth_string.txt`. You will have to place the text contained in that file on a registration page like [http://reg.i2p/add](http://reg.i2p/add) or [http://stats.i2p/i2p/addkey.html](http://stats.i2p/i2p/addkey.html).
+
### Getting your I2P Hostname
-Then, run `/usr/sbin/i2pd --daemon` to start i2pd and we can retreive
-our I2P hostname.
+Then, run the command `systemctl start i2pd` to start i2pd and `systemctl enable i2pd` to enable i2pd at startup, this will automatically generate our I2P hostname which we will now see.
-This can be done in lynx or a command-line browser by going to
-`http://127.0.0.1:7070/?page=i2p_tunnels` to get your I2P hostname.
+This can be done in lynx or a command-line browser by going to `http://127.0.0.1:7070/?page=i2p_tunnels` to get your I2P hostname.
You can also run these commands to find your hostname:
```sh
printf "%s.b32.i2p
-" $(head -c 391 /home/i2p/.i2pd/example.dat |sha256sum|xxd -r -p | base32 |sed s/=//g | tr A-Z a-z)
+" $(head -c 391 /var/lib/i2pd/example.dat | sha256sum | xxd -r -p | base32 | sed s/=//g | tr A-Z a-z)
```
+*(If you've generated your own keys to obtain a vanity address, now's a good time to make sure i2pd is properly reading those keys by verifying the address is the same as the one generated with the `vain` command.)*
+
## Adding the Nginx Config
-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 [tutorial](/basic/nginx) up until the server block of
-code. Instead, paste this:
+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 [tutorial](/basic/nginx) up until the server block of code. Instead, paste this:
```nginx
server {
@@ -80,22 +128,18 @@ server {
#### Clarifications
-####
-
-Nginx will listen in port 8080, but i2pd will forward your port 8080 to
-the i2p site port 80. This way you don\'t have to deal with server names
-or anything like that
+Nginx will listen on port 8080, but i2pd will forward your port 8080 to the i2p site port 80. This way you don't have to deal with server names or anything like that.
-From here we are almost done, all we have to do is enable the site and
-reload nginx which is also covered in [the webserver
-tutorial](nginx.html#enable).
+From here we are almost done, all we have to do is enable the site and reload nginx which is also covered in [the webserver tutorial](/basic/nginx#enable).
### Update regularly!
Make sure to update I2P on a regular basis by running:
```sh
-apt update && apt install i2pd
+apt update && apt upgrade
```
-**Contributor** - [qorg11](https://qorg11.net)
+**Contributors**
+- [qorg11](https://qorg11.net)
+- [David Uhden](https://github.com/daviduhden)
diff --git a/content/irc.md b/content/irc.md
index ccf16e8..71abd09 100644
--- a/content/irc.md
+++ b/content/irc.md
@@ -534,7 +534,7 @@ persistent:
# connection information for MySQL (currently only used for persistent history):
mysql:
- enabled: false
+ enabled: true
host: "localhost"
port: 3306
# if socket-path is set, it will be used instead of host:port
diff --git a/content/jitsi.md b/content/jitsi.md
index 82246dd..0df893b 100644
--- a/content/jitsi.md
+++ b/content/jitsi.md
@@ -175,7 +175,7 @@ You now need to register some users in [Prosody](/prosody), you
can do so manually using `prosodyctl`:
```sh
-prosodyctl register &ltusername> meet.example.org &ltpassword>
+prosodyctl register <username> meet.example.org <password>
```
Finally, restart `prosody`, `jicofo`, and `jitsi-videobridge2`:
diff --git a/content/mail/inbox.md b/content/mail/inbox.md
index 9b45a77..3f70b9c 100644
--- a/content/mail/inbox.md
+++ b/content/mail/inbox.md
@@ -39,7 +39,7 @@ We also need two little DNS records set on your domain registrar's site/DNS serv
## Configuring Dovecot
-Dovecot\'s configuration file is in `/etc/dovecot/docevot.conf`. If you
+Dovecot\'s configuration file is in `/etc/dovecot/dovecot.conf`. If you
open that file, you will see this line: `!include conf.d/*.conf` which adds
all the `.conf` files in `/etc/dovecot/conf.d/` to the Dovecot
configuration.
@@ -114,10 +114,10 @@ service auth {
}
protocol lda {
- mail_plugins = \$mail_plugins sieve
+ mail_plugins = $mail_plugins sieve
}
protocol lmtp {
- mail_plugins = \$mail_plugins sieve
+ mail_plugins = $mail_plugins sieve
}
plugin {
sieve = ~/.dovecot.sieve
diff --git a/content/mail/rdns.md b/content/mail/rdns.md
index 6a6ddf2..85cce0f 100644
--- a/content/mail/rdns.md
+++ b/content/mail/rdns.md
@@ -3,7 +3,8 @@ title: "Setup rDNS"
tags: ['mail']
date: 2022-12-02
---
-While [DNS records](dns.html) refer a domain name to the IP address
+
+While [DNS records](/basic/dns) refer a domain name to the IP address
where the the website is hosted, there is also rDNS (reverse DNS) and
specifically PTR (pointer) records which do the reverse: link a
server\'s IP to a domain name.
diff --git a/content/mail/smtp.md b/content/mail/smtp.md
index dee5640..3def765 100644
--- a/content/mail/smtp.md
+++ b/content/mail/smtp.md
@@ -25,7 +25,7 @@ If you want to start an email server, therefore, go to your VPS\'s site
and open a ticket or make a request to open up email ports, notably port `25`. This is a
simple process that requires nothing too special. One of the wagies at
your VPS will kindly do the needful and open your ports for you. Note
-that this is not the same as unblocking a port with [ufw](ufw.html),
+that this is not the same as unblocking a port with [ufw](/../ufw),
which still needs to be done for SMTP to work.
ufw allow 25,587 proto tcp
diff --git a/content/mail/validate.md b/content/mail/validate.md
index 2e371b2..8447409 100644
--- a/content/mail/validate.md
+++ b/content/mail/validate.md
@@ -119,10 +119,9 @@ systemctl reload postfix
## Adding the DNS record!
-We are only one step away from having functioning OpenDKIM. We must add
-the DKIM public key to our server\'s DNS settings, so go ahead and open
-up [your registrar\'s site](https://www.epik.com/?affid=we2ro7sa6) or
-wherever your site\'s DNS settings are.
+We are only one step away from having functioning OpenDKIM. We must add the
+DKIM public key to our server\'s DNS settings, so go ahead and open up your
+registrar\'s site or wherever your site\'s DNS settings are.
The public key is found in the file `/etc/postfix/dkim/mail.txt`, but it
will display as multiple lines and multiple quoted strings, which is
@@ -145,9 +144,8 @@ host we put it for is `mail._domainkey`.
{{< img alt="Adding the OpenDKIM TXT entry in DNS settings" src="/pix/dkim-01.png" link="/pix/dkim-01.png" >}}
-On my registrar, Epik, this is how it is input, but on some registrars,
-it may be required to include your domain name as well as
-`mail._domainkey.example.org`.
+On my registrar, this is how it is input, but on some registrars, it may be
+required to include your domain name as well as `mail._domainkey.example.org`.
If you have your own DNS server, add a TXT entry as follows:
@@ -172,7 +170,7 @@ You can permanently change your hostname by changing it in
`/etc/hostname` and rebooting, or you can just run
`hostname example.org` to change it temporarily for testing. Either way,
this will allow us to run the `mail` command as in [the SMTP
-article](smtp.html).
+article](../smtp).
```sh
echo "Hi there.
@@ -211,9 +209,22 @@ an email-authentication standard used to prevent spammers from sending messages
that appear to come from a spoofed domain.
cat /etc/mailname
- echo "v=spf1 mx a:mail.$(cat /etc/mailname) -all"
+ IP4=<your VPS's IPv4 address>
+ IP6=<your VPS's IPv6 address>
+ echo "v=spf1 mx a:mail.$(cat /etc/mailname) ip4:$IP4 ip6:$IP6 -all"
+
+**Note**: previous versions of this guide didn't ask you to specify the `ip4`
+and `ip6` mechanisms. If you don't include them, some email hosts (most
+notoriously gmail) will not accept mail from your server.
+
+The `IP4` and `IP6` values should be the same as what you set your [PTR
+records](../rdns) to.
The output of `cat /etc/mailname` is the Host field. The output of the second command is the TXT value.
Again, you can check [that site](https://appmaildev.com/en/spf)
to make sure your DKIM, DMARC, and SPF entries are valid. That's it!
+
+## Contribution
+
+- SPF mechanisms updated by Martin Chrzanowski \-- [website](https://m-chrzan.xyz), [donate](https://m-chrzan.xyz/donate.html)
diff --git a/content/matrix.md b/content/matrix.md
index 0b71d7b..76bb816 100644
--- a/content/matrix.md
+++ b/content/matrix.md
@@ -151,13 +151,42 @@ registration_shared_secret: {{<hl>}}???{{</hl>}}
Then, run the following command to register a user:
```sh
-cd /etc/matrix-synapse
-
-register_new_matrix_user -c homeserver.yaml http://localhost:8008
+register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml
```
This command will prompt you for a username, password and whether to make the user an admin or not.
+### Voice and Video Calls
+
+For native voice and video call support, the Synapse homserver needs to interface with a working **TURN and STUN Server.**
+
+First, follow the guide on installing and setting up [coturn](/coturn), setting either a shared secret or username-password pair for authentication.
+
+Then, in `/etc/matrix-synapse/homeserver.yaml`, edit the configuration as follows:
+
+```yaml
+turn_uris: [ "turn:{{<hl>}}turn.example.org{{</hl>}}?transport=udp", "turn:{{<hl>}}turn.example.org{{</hl>}}?transport=tcp" ]
+
+## This is how long call credentials are valid. Lessen to prevent abuse.
+turn_user_lifetime: 86400000
+
+## Keep this enabled unless for security reasons.
+turn_allow_guests: True
+```
+
+If you're using a shared secret, add the following config:
+
+```yaml
+turn_shared_secret: "{{<hl>}}your secret here{{</hl>}}"
+```
+
+Otherwise, add this config if you're using username-password pairs:
+
+```yaml
+turn_username: "{{<hl>}}turnserver_username{{</hl>}}"
+turn_password: "{{<hl>}}turnserver_password{{</hl>}}"
+```
+
### URL Previews
To enable server-generated previews of webpages, change this line to true in `/etc/matrix-synapse/homeserver.yaml`:
@@ -166,7 +195,7 @@ To enable server-generated previews of webpages, change this line to true in `/e
url_preview_enabled: true
```
-And make sure to uncomment the `url_preview_ip_range_blacklist:` section; Otherwise, Synapse will refuse to start up again!
+And **make sure to uncomment** the `url_preview_ip_range_blacklist:` section; Otherwise, Synapse will refuse to start up again!
### Federation
diff --git a/content/monerod.md b/content/monerod.md
new file mode 100644
index 0000000..19afba0
--- /dev/null
+++ b/content/monerod.md
@@ -0,0 +1,233 @@
+---
+title: "Monero Node"
+icon: 'xmr.svg'
+date: '2021-06-29'
+tags: ['service']
+short_desc: "Contribute to the Monero network."
+---
+
+The Monero cryptocurrency relies on a network of [decentralized nodes](https://www.getmonero.org/resources/moneropedia/node.html) to store the private transaction information and maintain consensus.
+
+Running your own node will let you relay transactions and contribute to the Monero network by dedicating storage and processing power to the task. You can then connect to your node from a wallet (if you enable rps).
+
+Some other benefits of a full node are:
+
+- More reliable and trusted as opposed to using a public node
+- More secure for RPC calls for payment processors
+- The ability to mine using [p2pool](https://p2pool.io/#help)
+- The ability to run a mining pool or solo mine\*
+
+**Note: Solo mining can be very unreliable and it is not recommended unless you have a very powerful computer.*
+
+**Warning:** Running a Monero node requires *a lot of storage* (at least 100GB) and a reasonable amount of memory and processing power. If you are hosting at home, make sure to use an **SSD** and not a hard disk drive, as advised by `monerod`.
+
+## Installation
+
+Because of the nature of Monero as an ever-evolving decentralized project, it is advised to download and keep an up-to-date version of it for your node. This can be accomplished by downloading the software manually:
+
+```sh
+wget https://downloads.getmonero.org/linux64
+tar -xvjf linux64
+mv linux64/monero* /usr/bin/
+```
+
+If the hardware you are using is not based on the amd64 architecture (like a Raspberry Pi), the monero project also [offers binaries](https://www.getmonero.org/downloads/) for other architectures on Linux, to download and install them simply change the last part of the link (linux64) and the archive name, e.g. for arm64 (linuxarm8). The fastest way to find out which one to use in Debian is with the `dpkg --print-architecture` command.
+
+## Configuration
+
+By default, Monero comes with no sample configuration files. Create one in `/etc/monerod.conf` using a text editor, and enter the following details:
+
+```sh
+# Configuration for monerod
+# Syntax: any command line option may be specified as 'clioptionname=value'.
+# Boolean options such as 'no-igd' are specified as 'no-igd=1'.
+# See 'monerod --help' for all available options.
+
+data-dir={{<hl>}}/var/lib/monero{{</hl>}}
+log-file={{<hl>}}/var/log/monero/monero.log{{</hl>}}
+log-level=0
+
+# Slow but reliable db writes
+db-sync-mode=safe
+
+# 1048576 kB/s == 1GB/s; a raise from default 2048 kB/s; contribute more to p2p network
+limit-rate-up=1048576
+limit-rate-down=1048576
+
+# Be more generous to wallets connecting
+disable-rpc-ban=1
+```
+
+### Log files
+
+The logfile at `/var/log/monero/monerod.log` will get **very large, very soon** if you do not limit it's size. Add these options to `/etc/monerod.conf` to limit it's size, and limit the creation of additional log
+ backups:
+
+```sh
+# Limit log size to 10 MiB
+max-log-file-size=10485760
+max-log-files=5
+```
+
+### Making a Public Node
+
+To advertise and let other users connect to your node, enable the following options:
+
+```sh
+restricted-rpc=true
+# Bind to all addresses (useful if under NAT)
+p2p-bind-ip=0.0.0.0
+rpc-bind-ip=0.0.0.0
+confirm-external-bind=1
+
+public-node=true
+```
+
+### User creation
+
+Create a dedicated user to run `monerod` named `monero`:
+```sh
+useradd -m -d /var/lib/monero monero
+```
+
+Create the directories, and ensure the user has the relevant permissions on them:
+```sh
+mkdir /var/lib/monero && chown -R monero:monero /var/lib/monero
+mkdir /var/log/monero && chown -R monero:monero /var/log/monero
+```
+
+### Pruning the blockchain
+
+When running a node, [pruning](https://www.getmonero.org/resources/moneropedia/pruning.html) allows the user to save data by only storing 1/8th of the ring signature information. Every "pruned" node contains a random 1/8th of the data, so the information is never lost. While this isn't as helpful to the network as running a full node, it is a very reasonable option when storage space and bandwidth are limited. **A pruned node will only use 1/3rd of storage compared to a full node.**
+
+To enable pruning, add the following options to `/etc/monerod.conf`:
+```sh
+prune-blockchain=true
+# This option should speed up the syncing process
+sync-pruned-blocks=true
+```
+
+## Tor/I2P Setup
+
+from the Monero documentation:
+
+> Only handshakes, peer timed syncs and transaction broadcast messages are supported over anonymity networks.
+
+Monero nodes **cannot sync the blockchain over Tor or I2P,** but the node can broadcast transactions and *let users connect* over these anonymizing networks.
+
+To set this up, first install [Tor](/tor) and/or [I2P](/i2p).
+
+When creating a hidden service, create the following configuration:
+
+### Tor
+
+Edit `/etc/tor/torrc` and add the following:
+
+```sh
+HiddenServiceDir /var/lib/tor/monerod
+
+# For wallets connecting over RPC:
+HiddenServicePort 18081 127.0.0.1:18181
+# For other nodes:
+HiddenServicePort 18083 127.0.0.1:18183
+```
+
+Now restart Tor:
+```sh
+systemctl restart tor
+```
+
+You can acquire the Tor address by running:
+```sh
+cat /var/lib/tor/monerod/hostname
+```
+
+### I2P
+
+Edit `tunnels.conf` (Which may be located in `/etc/i2pd/` if you followed [this](/i2p) guide) and add the following tunnels:
+
+```systemd
+[monerod]
+type = http
+host = 127.0.0.1
+port = 18283
+keys = monerod.dat
+
+[monerod-rpc]
+type = http
+host = 127.0.0.1
+port = 18281
+keys = monerod-rpc.dat
+```
+
+Now restart `i2pd`:
+```sh
+systemctl restart i2pd
+```
+
+You can acquire the I2P address by running:
+```sh
+printf "%s.b32.i2p
+" $(head -c 391 /home/i2p/.i2pd/monerod.dat | sha256sum |xxd -r -p | base32 | sed s/=//g | tr A-Z a-z)
+```
+
+### Configuring monerod
+
+Then, in `/etc/monerod.conf`, add the following:
+
+```sh
+# Tor config
+tx-proxy=tor,127.0.0.1:9050,10
+anonymous-inbound={{<hl>}}your-tor-address-here.onion{{</hl>}}:18083,127.0.0.1:18183,16
+
+# I2P config
+tx-proxy=i2p,127.0.0.1:4447
+anonymous-inbound={{<hl>}}your-i2p-address-here.b32.i2p{{</hl>}}:80,127.0.0.1:18283,16 # Maximum 16 simultaneous connections
+```
+
+## Running the Node
+
+Then, run this command to download the systemd daemon configuration for `monerod`. This will allow your node to run in the background and start automatically on boot as a service.
+
+```sh
+curl https://raw.githubusercontent.com/monero-project/monero/master/utils/systemd/monerod.service > {{<hl>}}/etc/systemd/system/monerod.service{{</hl>}}
+```
+
+*Note: This configuration assumes that you've created a user named `monero` which runs the program `monerod` in it's home directory, and which points to the configuration in `/etc/monerod.conf`. Edit any of these details in `/etc/systemd/system/monerod.service` if they don't apply to your configuration.*
+
+Now reload the systemd service file:
+```sh
+systemctl daemon-reload
+```
+
+To run the node, restart the systemd service:
+```sh
+systemctl restart monerod
+```
+
+To monitor the node's status at any time (for example, to check sync progress) check the log file using `tail`:
+```sh
+tail -f /var/log/monero/monerod.log
+```
+
+## Connecting to your Node
+
+To connect to your node using the GUI wallet, first open it:
+
+{{< img src=/pix/monerod/monerod-step-1.webp >}}
+
+On the mode selection screen, make sure to pick **Advanced mode:**
+
+{{< img src=/pix/monerod/monerod-step-2.webp >}}
+
+When you reach daemon settings, select the **Connect to a remote node** option, and then click **add remote node.**
+
+{{< img src=/pix/monerod/monerod-step-3.webp >}}
+
+A prompt will appear, asking for your node's details. Add your **address,** set the port to **18081,** and make to click **Mark as trusted daemon.**
+
+{{< img src=/pix/monerod/monerod-step-4.webp >}}
+
+When you reach the main wallet screen, you'll see **"Remote Node"** in the bottom-left corner. Now you can enjoy using your Monero node straight from your wallet!
+
+{{< img src=/pix/monerod/monerod-step-5.webp >}}
diff --git a/content/mumble.md b/content/mumble.md
new file mode 100644
index 0000000..0fddadc
--- /dev/null
+++ b/content/mumble.md
@@ -0,0 +1,144 @@
+---
+title: "Mumble"
+icon: 'mumble.svg'
+tags: ['service']
+date: 2023-07-2
+short_desc: 'Open Source, Low Latency, High Quality Voice Chat.'
+---
+
+[Mumble](https://mumble.info) is an open source, low latency and high quality voice chat software, being the best open source alternative to TeamSpeak.
+VoIP communications are mandatory encrypted by default using OCB-AES128, it has integrations for gamers (like overlays), it's stable and it's resource friendly.
+
+The server can also be run [behind Tor](https://gitlab.torproject.org/legacy/trac/-/wikis/doc/TorifyHOWTO/Mumble) without any issue.
+
+## Installation
+
+Mumble has a Debian repository for client and server, however it's very outdated so we are going to build the server instead.
+
+**I suggest to build both binaries on your local machine and [transfer the `mumble-server` to your remote server using `scp`](#extra).**
+
+
+Install dependencies:
+```sh
+apt install build-essential cmake pkg-config qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qttools5-dev qttools5-dev-tools libqt5svg5-dev libboost-dev libssl-dev libprotobuf-dev protobuf-compiler libprotoc-dev libcap-dev libxi-dev libasound2-dev libogg-dev libsndfile1-dev libspeechd-dev libavahi-compat-libdnssd-dev libxcb-xinerama0 libzeroc-ice-dev libpoco-dev g++-multilib
+```
+
+Git clone the repo.
+
+```sh
+git clone https://github.com/mumble-voip/mumble.git && cd mumble
+```
+
+Initialize all the submodules.
+
+```
+git submodule update --init
+```
+
+Create a build directory and run `cmake`.
+Cmake will create all the necessary files to build the mumble-server and client.
+
+```sh
+mkdir build && cd build && cmake ..
+```
+
+Build using `cmake`.
+
+```sh
+cmake
+```
+
+After the build you will now find a file named `mumble-server`, one `mumble` (which is the client) and a file named `mumble-server.ini` (aka the config file).
+
+## Running your Mumble server
+
+If you built it on local machine you can check out [how to move it to your remote server](#extra) first.
+
+After that, start with making your `mumble-server` executable and move it in `/usr/bin`.
+
+```sh
+chmod +x mumble-server && mv mumble-server /usr/bin
+```
+
+Create a folder in `/etc/` move your config files there.
+
+```sh
+mkdir /etc/mumble && mv mumble-server.ini /etc/mumble
+```
+
+By default, mumble-server uses port 64738, so make sure to open that port on your firewall (if you're using one), or whatever other port you selected on your configuration file. If you're using `ufw` as your firewall, the command is:
+
+```sh
+ufw allow 64738
+```
+
+Now we can run the server passing the config and a superuser password that can be used to connect and authenticate as an administrator from any client
+
+```sh
+mumble-server -ini mumble-server.ini -supw <your_password>
+```
+
+Check if it's running in the backgroud with `ps aux`.
+
+```sh
+ps aux | grep mumble-server
+```
+
+You will have an output like this.
+
+```sh
+root 127181 0.1 0.1 261064 21640 ? Sl 19:18 0:01 ./mumble-server
+root 127689 0.0 0.1 112956 22572 ? Sl 19:19 0:00 ./mumble-server
+```
+
+## Connecting to your mumble-server as a SuperUser
+
+You will probably will be left with your `mumble` binary in the build folder on your local machine.
+
+Now you should make it executable and move it in the `/usr/bin` folder.
+
+```sh
+chmod +x mumble && mv mumble /usr/bin
+```
+
+Run it the GUI with one command.
+
+```sh
+mumble
+```
+
+You will have something like this opening up.
+
+{{< img src="/pix/mumble/mumble-1.png" alt="connect window" >}}
+
+Click on the button `Add New...` and fill out the information need to connect to your server.
+
+{{< img src="/pix/mumble/mumble-2.png" alt="add server window" >}}
+
+If you haven't edited the port, `64738` will be default one.
+
+Click on `Ok`, select your server from the list and click `Connect`.
+
+**Now you are connected to your very own Mumble server as a SuperUser!**
+
+Now, you will want to setup a regular user to be an administrator of the server. Follow the [official documentation](https://wiki.mumble.info/wiki/Murmurguide#Becoming_Administrator_and_Registering_a_User) in order to do that, it is well-explained, so I won't repeat it here.
+
+Also, you might want to take a look at the [options for your config file](https://wiki.mumble.info/wiki/Murmurguide#Set_Up_Server), since mumble let's you set up a good amount of things, including a server password, a welcome message, and how to make your server public for the whole internet to see.
+
+---
+
+## Extra
+
+### Move binary with scp
+
+Move your binary to the folder `~` of your remote server.
+
+```sh
+scp <your_binary> root@<your_server_ip>:~
+```
+
+---
+
+Written by [NotMtth](https://notmtth.xyz) (Tor access warning)
+
+Donate Monero at: `donate.notmtth.xyz` ([OpenAlias](https://openalias.org/))
diff --git a/content/nextcloud.md b/content/nextcloud.md
index 0109e5e..9ec7627 100644
--- a/content/nextcloud.md
+++ b/content/nextcloud.md
@@ -22,10 +22,10 @@ cloud experience (in the likes of Google Services, anyways).
First, we install the dependencies:
```sh
-apt install -y nginx python3-certbot-nginx mariadb-server php7.4 php7.4-{fpm,bcmath,bz2,intl,gd,mbstring,mysql,zip,xml,curl}
+apt install -y nginx python3-certbot-nginx mariadb-server php php-{fpm,bcmath,bz2,intl,gd,mbstring,mysql,zip,xml,curl}
```
-*Optionally*, you can improve the performance of your Nextcloud server by adjusting the child processes that are used to execute PHP scripts. That way, more PHP scripts can be executed at once. Make the following adjustments to `/etc/php/7.4/fpm/pool.d/www.conf`:
+*Optionally*, you can improve the performance of your Nextcloud server by adjusting the child processes that are used to execute PHP scripts. That way, more PHP scripts can be executed at once. Make the following adjustments to `/etc/php/8.2/fpm/pool.d/www.conf`:
```systemd
pm = dynamic
@@ -74,7 +74,7 @@ below and change some of the placeholders as you wish:
```mysql
CREATE DATABASE nextcloud;
-GRANT ALL ON nextcloud.* TO 'username'@'localhost' IDENTIFIED BY 'password';
+GRANT ALL ON nextcloud.* TO '<your_username>'@'localhost' IDENTIFIED BY '<your_password>';
FLUSH PRIVILEGES;
EXIT;
```
@@ -94,11 +94,11 @@ In `/etc/nginx/sites-available/` we need to make a new configuration for
Nextcloud (example: `/etc/nginx/sites-available/nextcloud`).
-Add the following content [based of Nextcloud's recommendations](https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html) to the file, **remembering to replace `nextcloud.example.org` with your Nextcloud domain**.
+Add the following content [based of Nextcloud's recommendations](https://docs.nextcloud.com/server/25/admin_manual/installation/nginx.html) to the file, **remembering to replace `nextcloud.example.org` with your Nextcloud domain**.
```nginx
upstream php-handler {
- server unix:/var/run/php/php7.4-fpm.sock;
+ server unix:/var/run/php/php-fpm.sock;
server 127.0.0.1:9000;
}
map $arg_v $asset_immutable {
@@ -128,13 +128,13 @@ 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/wasm 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;
client_body_buffer_size 512k;
- add_header Referrer-Policy "no-referrer" always;
- add_header X-Content-Type-Options "nosniff" always;
- add_header X-Download-Options "noopen" always;
- add_header X-Frame-Options "SAMEORIGIN" always;
- add_header X-Permitted-Cross-Domain-Policies "none" always;
- add_header X-Robots-Tag "none" always;
- add_header X-XSS-Protection "1; mode=block" always;
+ add_header Referrer-Policy "no-referrer" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Download-Options "noopen" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "noindex, nofollow" always;
+ add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
index index.php index.html /index.php$request_uri;
location = / {
@@ -204,11 +204,11 @@ ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/
## Installing Nextcloud Itself
We should have all the moving pieces in place now, so we can download and
-install Nextcloud itself. First, download the latest Nextcloud version and we will extract into `/var/www/` and ensure Nginx has the authority to use it.
+install Nextcloud itself. First, download the latest Nextcloud 25 version and we will extract into `/var/www/` and ensure Nginx has the authority to use it.
```sh
-wget https://download.nextcloud.com/server/releases/latest.tar.bz2
-tar -xjf latest.tar.bz2 -C /var/www
+wget https://download.nextcloud.com/server/releases/latest-25.tar.bz2
+tar -xjf latest-25.tar.bz2 -C /var/www
chown -R www-data:www-data /var/www/nextcloud
chmod -R 755 /var/www/nextcloud
```
@@ -216,7 +216,7 @@ chmod -R 755 /var/www/nextcloud
Start and enable php-fpm and reload nginx:
```sh
-systemctl enable php7.4-fpm --now
+systemctl enable php8.2-fpm --now
systemctl reload nginx
```
diff --git a/content/prosody.md b/content/prosody.md
index 5c6bbc1..df18ad3 100644
--- a/content/prosody.md
+++ b/content/prosody.md
@@ -64,7 +64,7 @@ The second line is important because it prevents non-admins from creating and sq
Read more about the `muc` plugin on the Prosody documentation page [here](https://prosody.im/doc/modules/mod_muc).
-### Enabling chat histories
+### Enabling Chat Histories
By default, Prosody will send out messages received only to the first available clients.
That means that if you have your desktop client turned off and your cell phone receives a message,
@@ -87,29 +87,21 @@ With this we can bring XMPP to the level of other popular instant messaging appl
It is extremely easy to setup.
This part is optional, but it can make XMPP more normie-friendly if you plan on moving family members and friends over to XMPP.
-First we need to install extra prosody modules. Run the following command:
-
-```sh
-apt install prosody-modules
-```
-
-Then we can add the following line to you prosody config file to enable file uploads:
+Add the following line to your prosody config file to enable file uploads:
```cfg
-Component "uploads.example.org" "http_upload"
+Component "{{<hl>}}uploads.example.org{{</hl>}}" "http_file_share"
```
As you will notice, you need another subdomain for this. We will add an ssl certficate for this later.
-You will also need to go back to `modules_enabled` and uncomment the `http_files` module.
-This is used to actually serve the files to users.
+### Proxy Support
-And the last part of the setup is to enable the built in proxy server.
-This helps with file transfers for devices behind a NAT, and unless you are using XMPP in a LAN, you probably need this.
+This helps with file transfers for devices behind a NAT, and unless you are using XMPP in a LAN, you **probably need this.**
Enable the proxy by adding the following line to the config:
```cfg
-Component "proxy.example.org" "proxy65"
+Component "{{<hl>}}proxy.example.org{{</hl>}}" "proxy65"
```
As you can see, another subdomain is needed. We will add ssl certificates for this later.
@@ -119,26 +111,45 @@ At this point, file sharing is now setup and ready to be used. Although there ar
A big concern with file sharing is large files, seeing as all files shared over XMPP will be stored on your server. This can become a problem when many (and large) files are being shared. We can put a cap on large files by adding the following line to our config:
```cfg
-http_upload_file_size_limit = 20971520
+http_file_share_size_limit = 20971520
```
This puts a 20MB cap on all files being shared. The value is specified in bytes. You can also specify after how long files should be deleted by adding the following line:
```cfg
-http_upload_expire_after = 60 * 60 * 24 * 7
+http_file_share_expire_after = 60 * 60 * 24 * 7
```
The value is specified in seconds. The above line will make prosody delete files after a week.
-If it is for some reason neccessary, you can also manually invoke expiry with the following command:
+### Database Setup
-```cfg
-prosodyctl mod_http_upload expire
+Prosody includes the `internal` and `sql` storage backends by default.
+If you wish to run Prosody with PostgreSQL, begin by installing the PostgreSQL:
+
+```sh
+apt install postgresql lua-dbi-postgresql
```
-### Database Setup
+Then start the daemon:
+
+```sh
+systemctl restart postgresql
+```
+
+Now create a user named `prosody` to manage your database:
+
+```sh
+su -c "createuser --pwprompt prosody" postgres
+```
-Prosody includes the `internal` and `sql` storage backends by default. If you wish to run Prosody with PostgreSQL, edit the following lines:
+And finally, create the actual database:
+
+```sh
+su -c "psql -c 'CREATE DATABASE prosody OWNER prosody;'" postgres
+```
+
+Finally, in `/etc/prosody/prosody.cfg.lua`, edit the following lines:
```cfg
storage = "sql"
@@ -152,7 +163,27 @@ sql = {
}
```
-(This is assuming you've installed the `postgresql` package, and setup a database named `prosody` with a user named `prosody` as the owner.)
+### Voice and Video Calling
+
+Prosody supports XMPP voice and video calls through an external TURN and STUN server.
+
+First, follow the guide on installing and setting up [coturn,](/coturn) setting **only a shared secret** for authentication.
+
+Then, uncomment the `turn_external` module in the modules section in `prosody.cfg.lua`.
+
+```cfg
+"turn_external";
+```
+
+Finally, specify the host and credentials lower in the config:
+
+```cfg
+-- Specify the address of the TURN service (you may use the same domain as XMPP)
+turn_external_host = "{{<hl>}}turn.example.org{{</hl>}}"
+
+-- This secret must be set to the same value in both Prosody and the TURN server
+turn_external_secret = "{{<hl>}}your shared secret{{</hl>}}"
+```
### Other things to check
@@ -171,14 +202,14 @@ Obviously, we want to have client-to-server and server-to-server encryption. Now
**If you have multi-user chat enabled, be sure to get a certificate for that subdomain as well.** Include the `--nginx` option assuming you have an Nginx server running.
```sh
-certbot -d chat.example.org --nginx
+certbot -d {{<hl>}}chat.example.org{{</hl>}} --nginx
```
**If you have file sharing enabled, be sure to get a certificate for those subdomains as well.**
```sh
-certbot -d uploads.example.org --nginx
-certbot -d proxy.example.org --nginx
+certbot -d {{<hl>}}uploads.example.org{{</hl>}} --nginx
+certbot -d {{<hl>}}proxy.example.org{{</hl>}} --nginx
```
Once you have the certificates for encryption, run the following to import them into Prosody.
@@ -196,7 +227,7 @@ Note that you might get an error that a certificate has not been found if your `
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:
```sh
-prosodyctl adduser chad@example.org
+prosodyctl adduser {{<hl>}}chad@example.org{{</hl>}}
```
This will prompt you to create a password as well.
@@ -217,7 +248,7 @@ Once your server is set up, you just need an XMPP client to use your new and sec
- Windows: [Gajim](https://gajim.org/) also runs on Windows.
- Android: [Conversations.im](https://conversations.im/) or
[snikket](https://snikket.org/)
-- Mac/iOS: [Monal IM](https://monal.im/) or
+- Mac/iOS: [Monal IM](https://monal-im.org/) or
[Siskin](https://siskin.im/) for iOS alone
- command-line (GNU/Linux, MacOS, Windows):
[Profanity](https://profanity-im.github.io/)
@@ -228,7 +259,7 @@ Install whichever of these clients you want on your computer or phone and you ca
### Account addresses
-XMPP account addressed look just like email addresses: `username@example.org`. You can message any account on any XMPP server on the internet with that format.
+XMPP account addresses look just like email addresses: `username@example.org`. You can message any account on any XMPP server on the internet with that format.
### Note on MUCs (multi-user chats)
@@ -236,6 +267,6 @@ Remember that MUCs are kept on a separate subdomain that we created and should'v
### Note on firewalls and opening ports
-If you use a firewall, you should open ports 5222 and 5281. The first one is needed for clients to be able to connect to your server. The second is only necessary if you are using the `http_upload` module for file sharing.
+If you use a firewall, you should open ports 5222 and 5281. The first one is needed for clients to be able to connect to your server. The second is only necessary if you are using the `http_file_share` module for file sharing, as 5281 is the port for serving content over HTTPS.
A complete list of ports used by Prosody can be found [here](https://prosody.im/doc/ports).
diff --git a/content/radicale.md b/content/radicale.md
index b24f8ef..c37f22c 100644
--- a/content/radicale.md
+++ b/content/radicale.md
@@ -49,6 +49,12 @@ Execute the following command to add a new user to Radicale.
htpasswd -B -c /etc/radicale/users username
```
+To create additional users, htpasswd is used again but without the additional modifier.
+
+```sh
+htpasswd -B /etc/radicale/users username2
+```
+
As Radicale stands now it is fully functional and after starting it by
executing its binary, can be accessed under example.org:5232. But there
are two additional things we can do to make using and managing Radicale
diff --git a/content/rainloop.md b/content/rainloop.md
index 97b59cb..b84413c 100644
--- a/content/rainloop.md
+++ b/content/rainloop.md
@@ -26,7 +26,7 @@ First we will install the required packages for Rainloop with the
following command:
```sh
-apt-get install php7.4 php7.4-common php7.4-curl php7.4-xml php7.4-fpm php7.4-json php7.4-dev php7.4-mysql unzip -y
+apt-get install php php-common php-curl php-xml php-fpm php-json php-dev php-mysql unzip -y
```
Then we will download the community version of Rainloop, unzip it into
@@ -65,7 +65,7 @@ server {
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_keep_conn on;
- fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ fastcgi_pass unix:/var/run/php/php-fpm.sock;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
diff --git a/content/rss-bridge.md b/content/rss-bridge.md
index 5876d88..5ff9fa7 100644
--- a/content/rss-bridge.md
+++ b/content/rss-bridge.md
@@ -25,7 +25,7 @@ setup Fail2Ban. There\'s a great tutorial on how to do this [which can be read h
Next we\'ll install the required packages:
```sh
-apt install -y curl unzip nginx certbot php-fpm php-mysql php-cli php7.4-mbstring php7.4-curl php7.4-xml php7.4-sqlite3 php7.4-json
+apt install -y curl unzip nginx certbot php-fpm php-mysql php-cli php-mbstring php-curl php-xml php-sqlite3 php-json
```
We now have to create the website configuration file. Create/open the a
@@ -49,7 +49,7 @@ server {
location ~ \.php$ {
include snippets/fastcgi-php.conf;
- fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ fastcgi_pass unix:/var/run/php/php-fpm.sock;
}
location ~ /\.ht {
diff --git a/content/sshkeys.md b/content/sshkeys.md
index f1c8c0d..7c39413 100644
--- a/content/sshkeys.md
+++ b/content/sshkeys.md
@@ -123,6 +123,22 @@ Once we\'ve done that, we will reload our SSH daemon:
systemctl reload sshd
```
+### **Warning:**
+
+It is possible that your ssh configuration
+will be overridden by the default configuration added when creating
+the VPS, which will leave you vulnerable to brute force attacks. To
+prevent this, remove the configuration file using the following
+command:
+
+```sh
+rm /etc/ssh/sshd_config/50-cloud-init.conf
+```
+
+Also verify that the `/etc/ssh/ssh_config.d/` path is empty. If not,
+make sure that the configuration files in that folder are not
+overriding yours.
+
### We\'re done!
Now you can log in quickly and password-less-ly to your server, despite
diff --git a/content/tor.md b/content/tor.md
index a0acdf8..b1c827d 100644
--- a/content/tor.md
+++ b/content/tor.md
@@ -87,7 +87,7 @@ mirror.
Now we are almost done, all we have to do is enable the site and reload
nginx which, is also covered in [the webserver
-tutorial](nginx.html#enable).
+tutorial](/basic/nginx#enable).
### Advertise your onion service
@@ -115,5 +115,3 @@ Make sure to update Tor on a regular basis by running:
You do **<u>not</u>** need to run certbot for an ssl certificate.
HTTP over tor is plenty secure!
-
-**Contributor** - [tomfasano.net](https://tomfasano.net)
diff --git a/content/transmission.md b/content/transmission.md
new file mode 100644
index 0000000..4930661
--- /dev/null
+++ b/content/transmission.md
@@ -0,0 +1,844 @@
+---
+title: "Transmission"
+date: 2023-07-22
+icon: "transmission.png"
+tags: ["service"]
+short_desc: "Decentralized file-sharing with BitTorrent."
+---
+
+[Transmission] allows you to send and receive files via the BitTorrent
+protocol. This tutorial shows you how to use Transmission to run a
+"seedbox" - a server for downloading and seeding torrents.
+
+(For an explanation of BitTorrent, see [Appendix 1].)
+
+[Transmission]: https://transmissionbt.com/
+[Appendix 1]: #appendix-1-what-is-bittorrent
+
+## Installation
+
+The Transmission daemon is available in the Debian repositories:
+
+```sh
+apt install transmission-daemon
+```
+
+Besides installing Transmission, this command creates:
+* A user for running the service (`debian-transmission`)
+* A default configuration file
+ (`/var/lib/transmission-daemon/info/settings.json`)
+* A default service file
+ (`/etc/systemd/system/multi-user.target.wants/transmission-daemon.service`)
+
+## Configuration
+
+### Transmission-Daemon
+
+Any time you need to modify Transmission\'s configuration, you must stop
+the `transmission-daemon` service. Otherwise, Transmission will
+overwrite your changes.
+
+```sh
+service transmission-daemon stop
+```
+
+Open `/var/lib/transmission-daemon/info/settings.json` to view
+Transmission\'s configuration. The file should look something like this:
+
+```json
+{
+ "alt-speed-down": 50,
+ "alt-speed-enabled": false,
+ "alt-speed-time-begin": 540,
+ "alt-speed-time-day": 127,
+ "alt-speed-time-enabled": false,
+ "alt-speed-time-end": 1020,
+ "alt-speed-up": 50,
+ "bind-address-ipv4": "0.0.0.0",
+ "bind-address-ipv6": "::",
+ "blocklist-enabled": false,
+ "blocklist-url": "http://www.example.com/blocklist",
+ "cache-size-mb": 4,
+ "dht-enabled": true,
+ "download-dir": "/var/lib/transmission-daemon/downloads",
+ "download-limit": 100,
+ "download-limit-enabled": 0,
+ "download-queue-enabled": true,
+ "download-queue-size": 5,
+ "encryption": 1,
+ "idle-seeding-limit": 30,
+ "idle-seeding-limit-enabled": false,
+ "incomplete-dir": "/var/lib/transmission-daemon/Downloads",
+ "incomplete-dir-enabled": false,
+ "lpd-enabled": false,
+ "max-peers-global": 200,
+ "message-level": 1,
+ "peer-congestion-algorithm": "",
+ "peer-id-ttl-hours": 6,
+ "peer-limit-global": 200,
+ "peer-limit-per-torrent": 50,
+ "peer-port": 51413,
+ "peer-port-random-high": 65535,
+ "peer-port-random-low": 49152,
+ "peer-port-random-on-start": false,
+ "peer-socket-tos": "default",
+ "pex-enabled": true,
+ "port-forwarding-enabled": false,
+ "preallocation": 1,
+ "prefetch-enabled": true,
+ "queue-stalled-enabled": true,
+ "queue-stalled-minutes": 30,
+ "ratio-limit": 2,
+ "ratio-limit-enabled": false,
+ "rename-partial-files": true,
+ "rpc-authentication-required": true,
+ "rpc-bind-address": "0.0.0.0",
+ "rpc-enabled": true,
+ "rpc-host-whitelist": "",
+ "rpc-host-whitelist-enabled": true,
+ "rpc-password": "{224c4b5e26569d0baa8a161a68263253bbc69c26dnhxDeWg",
+ "rpc-port": 9091,
+ "rpc-url": "/transmission/",
+ "rpc-username": "transmission",
+ "rpc-whitelist": "127.0.0.1",
+ "rpc-whitelist-enabled": true,
+ "scrape-paused-torrents-enabled": true,
+ "script-torrent-done-enabled": false,
+ "script-torrent-done-filename": "",
+ "seed-queue-enabled": false,
+ "seed-queue-size": 10,
+ "speed-limit-down": 100,
+ "speed-limit-down-enabled": false,
+ "speed-limit-up": 100,
+ "speed-limit-up-enabled": false,
+ "start-added-torrents": true,
+ "trash-original-torrent-files": false,
+ "umask": 18,
+ "upload-limit": 100,
+ "upload-limit-enabled": 0,
+ "upload-slots-per-torrent": 14,
+ "utp-enabled": true
+}
+```
+
+Here are the options you should definitely look at:
+1. `download-dir` specifies where Transmission should save downloaded
+ torrents. (You can probably leave this at the default of
+ `/var/lib/transmission-daemon/downloads`.) If you change this, make
+ sure `debian-transmission` has permissions to use the directory.
+2. `peer-port` specifies what port Transmission should listen on to
+ connect to peers. (You can probably leave this at the default of
+ `51413`.)
+3. `rpc-password` specifies the password required to control
+ Transmission. Change this by typing it in as plaintext. When the
+ Transmission service starts, it will be hashed and prefixed with a
+ left curly bracket (`{`).
+4. `rpc-port` specifies the port Transmission will listen on for remote
+ commands. (You can probably leave this at the default of `9091`,
+ unless you have another service listening on this port for some
+ reason.)
+5. `rpc-username` specifies the username required to control
+ Transmission. The default is `transmission`, but feel free to change
+ this.
+
+### Firewall
+
+If `peer-port-random-on-start` is set to the default of `false`, your
+firewall must allow TCP and UDP traffic on the `peer-port`. Assuming you
+are using `ufw`, and `peer-port` is at the default of `51413`, enter:
+
+```sh
+ufw allow 51413
+```
+
+#### Note on Port Randomization
+
+If you set `peer-port-random-on-start` to `true`, your firewall must
+allow both TCP and UDP traffic on the port range specified by
+`peer-port-random-low` and `peer-port-random-high`.
+
+Assuming you are using `ufw`, and `peer-port-random-high` is `65535`,
+and `peer-port-random-low` is `49152`, enter:
+
+```sh
+ufw allow 49152:65535/tcp
+ufw allow 49152:65535/udp
+```
+
+### Starting the Service
+
+After modifying and saving the `transmission-daemon` configuration,
+start the service:
+
+```sh
+service transmission-daemon start
+```
+
+Transmission will hash your password in the configuration. You should be
+able to connect to the daemon with `transmission-remote` locally on the
+server using your credentials as shown next.
+
+## Controlling Transmission Locally
+
+`transmission-daemon` runs your torrent session in the background. It is
+controlled by an HTTP API that it serves on the `rpc-port` at
+`localhost`. `transmission-remote` is the command line utility you can
+use to control the daemon, and it was installed automatically when you
+installed `transmission-daemon`.
+
+### Authentication
+
+You first need to authenticate `transmission-remote` using the username
+and password you set up in `settings.json`. There are 2 basic ways you
+can do this.
+
+#### .netrc File
+
+The first method is via a `.netrc` file in your home directory. The
+advantage of this method is that you do not need to provide your
+credentials every time you run a `transmission-remote` command. The
+disadvantage is that your Transmission password is stored in your home
+folder as plaintext.
+
+To add the necessary record to your `.netrc` file, run the following
+command, where `<username>` is the `rpc-username`, and `<password>` is
+the plaintext version of `rpc-password` in `settings.json`:
+
+```sh
+echo "machine localhost login <username> password <password>" >> ~/.netrc
+```
+
+Then, to authenticate, run:
+
+```sh
+transmission-remote --netrc
+```
+
+Subsequent `transmission-remote` commands will not require entering your
+credentials.
+
+#### \-\-auth Flag
+
+The second method to authenticate is to include an `auth` flag in every
+`transmission-remote` command you execute. Substituting your credentials
+for `username` and `password`, you can enter the following command to
+list your torrents:
+
+```sh
+transmission-remote --auth=username:password --list
+```
+
+At this point, you should be able to use `transmission-remote` on your
+server to manage your torrents.
+
+### Hosting Torrents
+
+Here is a cookbook of common `transmission-remote` commands for hosting
+torrents.
+
+Add a torrent via a magnet link:
+
+```sh
+transmission-remote --add "magnet:link"
+```
+
+Add a torrent via a .torrent file:
+
+```sh
+transmission-remote --add "your.torrent"
+```
+
+List the status of your torrents (and get their numerical IDs):
+
+```sh
+transmission-remote --list
+```
+
+Get information about a specific torrent (where `ID` is the torrent ID
+from the prior command):
+
+```sh
+transmission-remote --torrent=ID --info
+```
+
+Remove a torrent and keep its data (where `ID` is the torrent ID):
+
+```sh
+transmission-remote --torrent=ID --remove
+```
+
+Remove a torrent and delete its data (where `ID` is the torrent ID):
+
+```sh
+transmission-remote --torrent=ID --remove-and-delete
+```
+
+Get information about the current Transmission session:
+
+```sh
+transmission-remote --session-info
+```
+
+Get statistics about the current Transmission session:
+
+```sh
+transmission-remote --session-stats
+```
+
+### Downloading Completed Torrents via Secure Shell
+
+Completed torrent downloads will be saved in the directory indicated by
+`download-dir` in your configuration. (This is
+`/var/lib/transmission-daemon/downloads` by default.)
+
+You should be able to download those files and directories from your
+seedbox using tools like [`rsync`], `(s)ftp`, and `scp`.
+
+[`rsync`]: ../rsync/
+
+If this is sufficient for you, you do not need to configure Transmission
+for remote access.
+
+## Creating New Torrents
+
+`transmission-create` is used to create torrents. It was installed
+automatically on your server when you installed `transmission-daemon`.
+You can use it on any machine that has it installed and has a copy of
+the file or directory you want to share.
+
+(`transmission-edit` is also available to edit .torrent files. It can do
+things like add and delete tracker urls. However, this tool tends to be
+more useful when working with other\'s .torrent files and less so when
+creating torrents from scratch.)
+
+### Creating the .torrent File
+
+Here is a template command for creating a .torrent file:
+
+```sh
+transmission-create --outfile "my.torrent" \
+ --comment "My cool torrent" \
+ --tracker "https://tracker1.example.org/announce" \
+ --tracker "https://tracker2.example.org/announce" \
+ "path/to/my/file/or/directory"
+```
+
+* `outfile` specifies where to write the .torrent file.
+* `comment` specifies a comment for the torrent.
+* `tracker` specifies a torrent tracker to use. You can have multiple of
+ these. `udp://open.tracker.cl:1337/announce` is usually a good choice,
+ but there are many others.
+* The path indicates the file or directory you want to make a torrent
+ of.
+
+### Generating the Magnet Link
+
+`transmission-show` is used to generate magnet links from .torrent
+files, and it was installed when you installed `transmission-daemon`.
+Given any .torrent file, you can run:
+
+```sh
+transmission-show --magnet "my.torrent"
+```
+
+### Seeding Your New Torrent
+
+First, copy the file or directory that you are hosting to the download
+directory (`download-dir`) specified in the `transmission-daemon`
+configuration. If the `download-dir` is at the default, you could write:
+
+```sh
+cp "the-file-or-directory-to-share" \
+ "/var/lib/transmission-daemon/downloads/"
+```
+
+Then, add your torrent to Transmission via your .torrent file or magnet
+link:
+
+```sh
+transmission-remote --add "the-torrent-file-or-magnet-link"
+```
+
+Your server should begin seeding your torrent, and you can share it via
+the .torrent file or magnet link.
+
+**Warning:** Make sure you copy the file or directory you are seeding to
+the `download-dir` directory *before* adding the torrent to
+Transmission. If you copy the source file/directory into your download
+directory *after* adding the torrent, run `transmission-remote` to get
+the ID of your torrent:
+
+```sh
+transmission-remote --list
+```
+
+Then, where `ID` is the ID of the torrent, run this command so
+Transmission will know it already has the data:
+
+```sh
+transmission-remote --torrent=ID --verify
+```
+
+The torrent should then begin seeding.
+
+## Controlling Transmission Remotely
+
+At this point, you should be able to manage your seedbox locally by
+using `transmission-remote` on your server via secure shell. However, it
+may be convenient to also configure the box for remote access. You can
+do this by exposing Transmission\'s HTTP API, which includes a web app.
+
+The Transmission web app acts as a graphical stand-in for
+`transmission-remote`. You can manage your torrents and the daemon with
+it.
+
+Similar to `transmission-remote` itself, however, you cannot download
+completed torrents via the web app. (That requires serving the files via
+a different channel, whether that be `rsync`, `sftp`, `scp`, `http(s)`,
+etc. Serving completed torrents via `http(s)` is explained later.)
+
+Exposing Transmission\'s HTTP interface to the internet additionally
+allows you to control your seedbox from a different machine using
+`transmission-remote`.
+
+### Configuring Remote Access
+
+By default, `transmission-daemon` only allows RPC commands from
+`localhost`. For remote access, it must allow connections from the IP
+addresses you want to access the daemon from. The most direct way of
+doing this is by disabling the whitelist, which allows all IP addresses,
+but you can specify a whitelist if you like.
+
+Stop `transmission-daemon`:
+
+```sh
+service transmission-daemon stop
+```
+
+Then, set `rpc-whitelist-enabled` to `false` in your configuration. This
+makes it so that any IP address can connect and control
+`transmission-daemon`. (You will just need your `rpc-username` and the
+plaintext version of your `rpc-password` to authenticate.)
+
+Alternatively, if you want to use the whitelist, set
+`rpc-whitelist-enabled` to `true`, and set `rpc-whitelist` to a
+comma-separated list of IP addresses. (Asterisks are used as wildcards.)
+For example, you could write:
+
+```
+101.125.137.168,89.72.*.221
+```
+
+While you have the configuration open, take note of the value of
+`rpc-port`, which is 9091 by default. This value will be necessary for
+configuring remote access.
+
+After saving your configuration, start `transmission-daemon`:
+
+```sh
+service transmission-daemon start
+```
+
+### Running Nginx as a Reverse Proxy
+
+It is possible to open remote access to `transmission-daemon` simply by
+opening its `rpc-port` in the firewall, 9091 by default. This connection
+will be run over insecure HTTP, so your username and password will be
+sent unencrypted. While this may be acceptable when testing a system, it
+is generally preferable to use a web server with TLS as a reverse proxy
+to Transmission\'s HTTP interface.
+
+If you are already running nginx with working TLS, allowing access to
+Transmission\'s web interface simply requires adding a `location` block
+to your `server` block in your nginx configuration. Assuming `rpc-port`
+is 9091, and `rpc-url` is `/transmission/` in your `transmission-daemon`
+configuration, add the following block to your nginx configuration:
+
+```nginx
+location /transmission/ {
+ proxy_pass http://localhost:9091/transmission/ ;
+}
+```
+
+Reload nginx so your changes takes effect:
+
+```sh
+nginx -s reload
+```
+
+At this point, if `example.org` is your domain, and you are connected
+from a permitted IP address:
+* The Transmission web app will be available at
+ `https://example.org/transmission/web/`.
+* `transmission-remote` will be able to connect to
+ `https://example.org/transmission`. (Note the omission of the trailing
+ forward slash.)
+
+#### Serving Transmission at a Different Path
+
+By default, Transmission serves it\'s interface at the path
+`/transmission/`. You can change this in the configuration, but note
+that your chosen path must start and end with a forward slash.
+
+For example, to serve Transmission\'s interface at `/~luke/torrents/`:
+
+1. Stop the `transmission-daemon` service.
+2. Set `rpc-url` in the configuration to your chosen path. That is
+ `/~luke/torrents/` in this example.
+3. Modify the `location` block\'s path pattern and `proxy_pass` url in
+ your nginx configuration to use the new path (and the correct
+ `rpc-port`). For this example, that is:
+
+```nginx
+location /~luke/torrents/ {
+ proxy_pass http://localhost:9091/~luke/torrents/ ;
+}
+```
+
+4. Start the `transmission-daemon` service.
+5. Reload nginx.
+
+The Transmission web app will then be accessible at
+`https://example.org/~luke/torrents/web/`. `transmission-remote` will be
+able to connect to `https://example.org/~luke/torrents`.
+
+### Connecting via a Browser
+
+Where `example.org` is your website, and `/transmission/` is the
+`rpc-url` in your `transmission-daemon` configuration, point your web
+browser to `https://example.org/transmission/web/`. After entering your
+credentials into the login (using your `rpc-username` and plaintext
+`rpc-password`), you will be greeted by the web interface with a list of
+your torrents.
+
+Here is a Transmission instance that is downloading one torrent:
+
+{{<img src="/pix/transmission-web-interface.png"
+ alt="A screenshot of the Transmission web interface" >}}
+
+### Connecting via Transmission-Remote
+
+You can control `transmission-daemon` on your server from other machines
+that have `transmission-remote` installed. You do this by calling
+`transmission-remote` with a url consisting of the domain name (or IP),
+the `rpc-port`, and the path specified by `rpc-url` in the configuration
+(`/transmission/` by default) with the trailing forward slash omitted.
+For example, after inserting your credentials for `username` and
+`password`, assuming the `rpc-url` is at the default of
+`/transmission/`, you could invoke the following command on your local
+machine to list the status of the torrents on your server:
+
+```sh
+transmission-remote https://example.org/transmission \
+ --auth=username:password \
+ --list
+```
+
+Note how the `rpc-url` is `/transmission/`, but `/transmission` is
+specified in the command.
+
+**Warning:** The Transmission web app and `transmission-remote` both
+allow you to make changes to Transmission\'s port settings. Be careful
+change these, because you might also need to update your server\'s
+firewall configuration.
+
+## Serving Complete Torrent Downloads via HTTP(S)
+
+The Transmission web interface and `transmission-remote` do not allow
+you to download completed torrents from your seedbox via HTTP(S).
+However, in some scenarios, downloading via HTTP(S) may be preferable
+where shell access and other supporting tools (`rsync`, `scp`, `sftp`,
+`ftp`, etc.) are unavailable on the client machine. Serving completed
+torrent downloads involves configuring nginx to serve the `download-dir`
+of `transmission-daemon`.
+
+(Serving completed torrent downloads via HTTP(S) does not require
+exposing Transmission\'s HTTP API and web app.)
+
+**Warning:** The Transmission interfaces give you the option of saving
+completed torrent downloads to directories other than the `download-dir`
+specified in your `transmission-daemon` configuration. Downloading a
+torrent to a different directory and not serving that directory with
+nginx will prevent that completed torrent from being served to clients
+via the static file server shown here.
+
+Assuming you wish to serve your completed torrents from the directory
+`/downloads/` on your web server, and `download-dir` is at the default
+of `/var/lib/transmission-daemon/downloads/`, you can add this
+`location` block into the `server` block of your nginx configuration:
+
+```nginx
+location /downloads {
+ root /var/lib/transmission-daemon/downloads ;
+ proxy_max_temp_file_size 0 ;
+ autoindex on ;
+}
+```
+
+Note how the trailing forward slash has been omitted in both the
+`location` pattern and the `root` path.
+
+The `proxy_max_temp_file_size` option prevents disk caching that would
+potentially break nginx\'s ability to serve files larger than a few
+gigabytes.
+
+If you omit the `autoindex` option or set it to `off`, nginx will not
+show a directory listing of your downloaded torrents. (You will need the
+direct link to download a given torrent.)
+
+After saving the configuration, reload nginx.
+
+Where `example.org` is your website, and assuming `autoindex` is `on`,
+opening `https://example.org/downloads/` in a web browser should show a
+list of links to download your completed torrents.
+
+While downloading via HTTP(S) can be convenient, resuming interrupted
+downloads can be a nuisance. See [Appendix 2] for tips on how to combat
+this.
+
+[Appendix 2]: #appendix-2-reliable-downloading-via-https
+
+### Preventing Unauthorized Downloading
+
+If you want to prevent others from downloading completed torrents via
+HTTP(S) from your seedbox, you have a few options:
+1. When defining the nginx `location` block, you can use some random
+ string for the path match pattern, like `/DJRmdL8HPn`. Only those who
+ know the path will able to download your completed torrents.
+2. You can protect the directory with a username and password using
+ [HTTP basic authentication].
+
+[HTTP basic authentication]: ../auth/
+
+## Troubleshooting
+
+`journalctl` can be used to view the logs of `transmission-daemon`. For
+example, you could run:
+
+```sh
+journalctl | grep transmission-daemon
+```
+
+Transmission\'s [documentation] contains help and answers to common
+questions.
+
+[documentation]:
+ https://github.com/transmission/transmission/blob/main/docs/README.md
+
+## Appendix 1: What is BitTorrent?
+
+Many protocols for sending files over the internet, such as Hypertext
+Transfer Protocol (HTTP) and File Transfer Protocol (FTP), operate on a
+\"client-server\" (or \"server-client\") model. A server will store a
+file. A client will send a request for the file from the server. If the
+request is accepted, the server will respond with the file.
+
+In contrast, BitTorrent is a decentralized, peer-to-peer, file-sharing
+protocol. Instead of relying on a dedicated server, a file will be
+assembled by downloading it in chunks from many different hosts. Anyone
+who has the file (or pieces of it) can then help serve the file to
+others. This makes file-sharing via BitTorrent much less susceptible to
+data loss and downtime than the client-server model since the file can
+be replicated and shared across a potentially large number of
+independent hosts.
+
+The individual hosts are called \"peers\". The process of a host
+offering their copy of the file for download to others is called
+\"seeding\". The set of peers collectively hosting the file is called a
+\"swarm\".
+
+The peers usually find out about each other using \"trackers\",
+dedicated servers that help peers find those who possess or want a
+specific file. Trackers are identified by URLs. A peer can \"announce\"
+to a tracker that it possesses a specific file. If a peer wants to
+download a file, the peer can ask the tracker for peers that possess the
+file. Trackers do not actually transfer the torrent between peers. They
+simply facilitate peer-discovery.
+
+The BitTorrent network also uses other mechanisms for peer-discovery,
+including a \"DHT\", or Distributed Hash Table. Similar to trackers,
+these help peers find each other. Unlike trackers, a DHT is entirely
+peer-to-peer as it is based on a distributed data structure rather than
+a dedicated server. The DHT that BitTorrent uses is called the Mainline
+DHT. Most modern torrent clients will give you the option of using it to
+help you find peers. (Transmission supports it.)
+
+Before downloading a desired file or directory, you will need its
+.torrent file or magnet link. These are usually distributed via
+webpages, and they contain metadata and other information required for
+downloading the file, including:
+* The cryptographic hash of the file for validating its integrity. (A
+ .torrent file will also include hashes for individual chunks of the
+ file.)
+* The name of the torrent.
+* A list of tracker URLs to use for finding peers.
+
+Once the .torrent file or magnet link has been imported into a torrent
+client, the client will query the network to discover peers that possess
+the file. The swarm will then work together to send the user the file in
+chunks. The chunks will be cryptographically validated and assembled to
+create the final file. After the user has downloaded the file (or even
+if they only have pieces of it), they also can be part of the swarm by
+helping to seed the file to others who want it.
+
+\"Leeching\" is when a user downloads torrents and does not seed them to
+others. This practice hurts the overall functioning of the swarm and
+will also usually reduce the bandwidth that other peers are willing to
+dedicate to you in the future. Always reseed. 🌱
+
+## Appendix 2: Reliable Downloading via HTTP(S)
+
+Downloading via HTTP(S) can be very convenient when shell access is
+unavailable. It can also be very troublesome with large files due to
+interrupted or corrupted downloads. Thankfully, utilities like `wget`
+and `zsync` can help combat this.
+
+### wget
+
+`wget` supports resuming interrupted downloads. It isn\'t as robust for
+this use case as other utilities (like `zsync`), but it can be
+convenient because:
+* It doesn\'t require any extra setup on your server.
+* It comes preinstalled on most \*nix systems.
+
+Supposing you want to download a very large file from your web server
+and save it to your current directory, you might run:
+
+```sh
+wget https://example.org/downloads/large.file
+```
+
+If this command is stopped or interrupted, running it again with the
+`--continue` flag will cause `wget` to resume your download:
+
+```sh
+wget --continue https://example.org/downloads/large.file
+```
+
+If your network connection is particularly poor, you can also specify
+the `--tries=0` flag. `wget` will retry connecting indefinitely, so you
+don\'t need to run the command multiple times if it disconnects.
+
+One major downside of using `wget` is that the resumption of the
+download is based on the difference between the file length on the
+server and the length of the partial file on your disk. No cryptography
+or checksum is used to validate the file's integrity.
+
+`wget` also supports downloading directories, but this can be finicky.
+You might need to experiment with the arguments depending on the
+contents of the directory. For example, assuming directory listing is
+enabled in the relevant directory on your web server, you might run a
+command like:
+
+```sh
+wget --recursive --no-parent \
+ https://example.org/downloads/large-directory/
+```
+
+The `--recursive` flag indicates that `wget` should download the
+contents of the directory as well as its subdirectories up to 5 levels
+deep.
+
+The `--no-parent` flag indicates that `wget` should not download any
+files at higher levels in the directory hierarchy.
+
+**Note:** Enabling `autoindex` for a directory in nginx implicitly
+creates `index.html` files in the directory and its subdirectories from
+the perspective of HTTP(S) clients like `wget`. However, the `--reject
+index.html` flag is omitted in the above command because `wget` needs
+the links in those index files to download all of the files in the
+target directory. (In fact, for this reason, the above command might
+potentially fail to download all the files in the directory if the
+target directory contains `index.html` files.) Once the directory has
+been downloaded to your disk, you would then need to delete the
+`index.html` files that were created by the web server's directory
+listing in your downloaded copy. Additionally, the actual directory
+structure created on your disk with this example would be
+`example.org/downloads/large-directory/`, not `large-directory/`.
+
+### zsync
+
+`zsync` is another option for more reliable HTTP(S) downloading.
+
+The advantages of `zsync` include:
+* It offers significantly more data validation than `wget` by using
+ hashes and checksums.
+* By using the `-i` flag, you can specify file chunks you have on disk
+ from the same or similar downloads to potentially accelerate the
+ current download.
+
+The disadvantages of `zsync` include:
+* It does not usually come pre-installed on *nix systems.
+* Unlike `wget`, it does not support downloading directories. It only
+ supports files.
+* It must be installed on the client-side.
+* It requires additional setup on the server-side.
+
+`zsync` is available in the Debian repositories. Install it on your
+server by running:
+
+```sh
+apt install zsync
+```
+
+(You will also need to install it on your client machine.)
+
+On your server, change your directory to your torrent download
+directory, `/var/lib/transmission-daemon/downloads/` by default. Then,
+run `zsyncmake` by providing the url and name of the file you want to
+use `zsync` on:
+
+```sh
+zsyncmake -u "https://example.org/downloads/large.file" large.file
+```
+
+This will create a new file with the same name as your original file but
+with the `.zsync` extension added: `large.file.zsync` in this case.
+(Note that if the file you are sharing changes, you need to regenerate
+the `.zsync` file.)
+
+If you view your torrent download directory in a browser, and nginx has
+`autoindex` turned `on`, you should notice the addition of the `.zsync`
+file in the directory.
+
+On your HTTP(S) client, where the provided url is the link to the new
+`.zsync` file, run:
+
+```sh
+zsync "https://example.org/downloads/large.file.zsync"
+```
+
+If your download is interrupted, just run the command again, and `zsync`
+will read your partial download, resume it, checksum it, and cleanly
+assemble the target file, `large.file`.
+
+If your downloads directory is protected with HTTP basic authentication,
+you can specify your credentials by adding an `-A` flag before the URL:
+
+```sh
+zsync -A example.org=username:password \
+ "https://example.org/downloads/large.file.zsync"
+```
+
+If you have a piece of the file with a different name or a different
+version of the file, you can specify those pieces with the `-i` flag to
+potentially reduce what `zsync` needs to fetch over the network:
+
+```sh
+zsync -i "large.file.piece" -i "large.file.old" \
+ "https://example.org/downloads/large.file.zsync"
+```
+
+`zsync` will attempt to look for file chunks in `large.file.piece` and
+`large.file.old` that can be used to help assemble `large.file`.
+
+For example, if you have a Linux ISO on your computer, and you want to
+download an updated version from your seedbox, there\'s a good chance
+that only certain sections of the ISO changed from the version you
+already have. You can specify the old version of the ISO you have with
+the `-i` flag to potentially reuse chunks from the old version when
+downloading the new ISO.
+
+---
+
+*Written by: Luke Hamann*
diff --git a/content/wireguard.md b/content/wireguard.md
index 93e722f..c0d1879 100644
--- a/content/wireguard.md
+++ b/content/wireguard.md
@@ -1,8 +1,9 @@
---
-title: "Wireguard"
-date: 2022-07-26
-icon: 'wireguard.svg'
-tags: ['service']
+title: Wireguard
+date: 2022-07-26T00:00:00.000Z
+icon: wireguard.svg
+tags:
+ - service
short_desc: "Fast, Modern, Secure VPN Tunnel"
---
@@ -16,6 +17,7 @@ As an example, we'll be using a virtual 172.16.0.0/24 network, but any private i
## Installation
### On the Server
+
Install the WireGuard management tools:
apt install wireguard
@@ -29,6 +31,7 @@ Run the following command to apply the change:
sysctl -w net.ipv4.ip_forward=1
### On the Client
+
Use your package manager to install the WireGuard Management Tools.
On Arch and Fedora based distros the package is `wireguard-tools`. For Debian based, it's listed above.
@@ -37,7 +40,6 @@ Create the public and private keys for your machine:
sudo bash -c "umask 077 ; wg genkey > /etc/wireguard/client_priv.key"
sudo bash -c "wg pubkey < /etc/wireguard/client_priv.key > /etc/wireguard/client_pub.key"
-
### Back to the Server
Generate the public and private keys for your server:
@@ -106,6 +108,7 @@ there's a good chance you're behind a corporate firewall. Read on.
## WebSocket Tunnel
#### Note on TLS
+
If your server hosts a website with https, you won't be able to use port 443 to
obfuscate your WireGuard packets as TLS traffic. You may use some other innocuous
port, but there's no guarantee you'll punch through the picky firewall.
@@ -145,7 +148,7 @@ Download and install wstunnel and a helper script:
wget https://github.com/erebe/wstunnel/releases/download/v4.0/wstunnel-x64-linux
sudo mv wstunnel-x64-linux /usr/local/bin/wstunnel
sudo chmod +x /usr/local/bin/wstunnel
- wget https://codeberg.org/onasaft/sbx/raw/branch/main/vpn/wstunnel.sh
+ wget https://raw.githubusercontent.com/jnsgruk/wireguard-over-wss/master/wstunnel.sh
sudo mv wstunnel.sh /etc/wireguard/wstunnel.sh
sudo chmod +x /etc/wireguard/wstunnel.sh
@@ -168,5 +171,3 @@ Start WireGuard again:
sudo wg-quick up myvpn
To disconnect, type `down` instead of `up`. And just like that, you now host a WireGuard VPN server!
-
-**Contributor** - [tomfasano.net](https://tomfasano.net)
diff --git a/static/pix/dns-epik.png b/static/pix/dns-epik.png
index 33d2c40..0bbc8c5 100644
--- a/static/pix/dns-epik.png
+++ b/static/pix/dns-epik.png
Binary files differ
diff --git a/static/pix/monerod/monerod-step-1.webp b/static/pix/monerod/monerod-step-1.webp
new file mode 100644
index 0000000..382a1b8
--- /dev/null
+++ b/static/pix/monerod/monerod-step-1.webp
Binary files differ
diff --git a/static/pix/monerod/monerod-step-2.webp b/static/pix/monerod/monerod-step-2.webp
new file mode 100644
index 0000000..48255d6
--- /dev/null
+++ b/static/pix/monerod/monerod-step-2.webp
Binary files differ
diff --git a/static/pix/monerod/monerod-step-3.webp b/static/pix/monerod/monerod-step-3.webp
new file mode 100644
index 0000000..77630ec
--- /dev/null
+++ b/static/pix/monerod/monerod-step-3.webp
Binary files differ
diff --git a/static/pix/monerod/monerod-step-4.webp b/static/pix/monerod/monerod-step-4.webp
new file mode 100644
index 0000000..e0d6759
--- /dev/null
+++ b/static/pix/monerod/monerod-step-4.webp
Binary files differ
diff --git a/static/pix/monerod/monerod-step-5.webp b/static/pix/monerod/monerod-step-5.webp
new file mode 100644
index 0000000..f2050a3
--- /dev/null
+++ b/static/pix/monerod/monerod-step-5.webp
Binary files differ
diff --git a/static/pix/mumble.svg b/static/pix/mumble.svg
new file mode 100644
index 0000000..263b86a
--- /dev/null
+++ b/static/pix/mumble.svg
@@ -0,0 +1,127 @@
+<?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="400" height="400" id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" version="1.0" sodipodi:docname="mumble.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" style="display:inline">
+ <title id="title3169">Mumble logo</title>
+ <defs id="defs4">
+ <linearGradient id="linearGradient4117">
+ <stop style="stop-color:#000000;stop-opacity:0;" offset="0" id="stop4119"/>
+ <stop id="stop4125" offset="0.81720757" style="stop-color:#000000;stop-opacity:0.01960784;"/>
+ <stop style="stop-color:#000000;stop-opacity:0.14509804;" offset="0.89931339" id="stop4127"/>
+ <stop id="stop4129" offset="0.91198522" style="stop-color:#000000;stop-opacity:0.20784314;"/>
+ <stop style="stop-color:#000000;stop-opacity:0.25098039;" offset="0.95598048" id="stop4131"/>
+ <stop style="stop-color:#000000;stop-opacity:0.33333334;" offset="1" id="stop4121"/>
+ </linearGradient>
+ <linearGradient inkscape:collect="always" id="linearGradient3972">
+ <stop style="stop-color:#b3b3b3;stop-opacity:1;" offset="0" id="stop3974"/>
+ <stop style="stop-color:#b3b3b3;stop-opacity:0;" offset="1" id="stop3976"/>
+ </linearGradient>
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient1125-2" id="radialGradient1131-6" cx="333.52826" cy="217.58252" fx="333.52826" fy="217.58252" r="29.875" gradientTransform="matrix(-0.95122439,-0.37973408,-0.79004638,1.9790465,561.77552,-104.77634)" gradientUnits="userSpaceOnUse"/>
+ <linearGradient inkscape:collect="always" id="linearGradient1125-2">
+ <stop style="stop-color:#e6e6e6;stop-opacity:1;" offset="0" id="stop1127-4"/>
+ <stop style="stop-color:#e6e6e6;stop-opacity:0;" offset="1" id="stop1129-5"/>
+ </linearGradient>
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient961-9" id="radialGradient967-9" cx="172.61411" cy="303.20566" fx="172.61411" fy="303.20566" r="22.630014" gradientTransform="matrix(1,0,0,0.63328545,0,119.49923)" gradientUnits="userSpaceOnUse"/>
+ <linearGradient inkscape:collect="always" id="linearGradient961-9">
+ <stop style="stop-color:#999999;stop-opacity:1;" offset="0" id="stop963-8"/>
+ <stop style="stop-color:#999999;stop-opacity:0;" offset="1" id="stop965-3"/>
+ </linearGradient>
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient1125-6" id="radialGradient1131-8" cx="335.08649" cy="219.03677" fx="335.08649" fy="219.03677" r="29.875" gradientTransform="matrix(0.54659184,-0.27740671,0.6404924,1.2620022,11.607646,18.444794)" gradientUnits="userSpaceOnUse"/>
+ <linearGradient id="linearGradient1125-6">
+ <stop style="stop-color:#969696;stop-opacity:1;" offset="0" id="stop1127-9"/>
+ <stop style="stop-color:#e6e6e6;stop-opacity:0;" offset="1" id="stop1129-8"/>
+ </linearGradient>
+ <radialGradient r="38.624973" fy="25.979427" fx="250.46019" cy="25.979427" cx="250.46019" gradientTransform="matrix(-1.1864466,0.79500993,0.21180507,0.31609089,435.38812,-174.97097)" gradientUnits="userSpaceOnUse" id="radialGradient1193-8" xlink:href="#linearGradient1117-8-2" inkscape:collect="always"/>
+ <linearGradient id="linearGradient1117-8-2">
+ <stop style="stop-color:#afafaf;stop-opacity:1;" offset="0" id="stop1119-1-6"/>
+ <stop style="stop-color:#e6e6e6;stop-opacity:0;" offset="1" id="stop1121-2-2"/>
+ </linearGradient>
+ <linearGradient id="linearGradient1284-7">
+ <stop style="stop-color:#bebebe;stop-opacity:1;" offset="0" id="stop1286-8"/>
+ <stop style="stop-color:#b3b3b3;stop-opacity:0;" offset="1" id="stop1288-0"/>
+ </linearGradient>
+ <radialGradient r="103.51558" fy="230.12292" fx="458.02847" cy="230.12292" cx="458.02847" gradientTransform="matrix(0.41734111,-0.01064379,0.00887794,0.34810258,9.439031,55.321448)" gradientUnits="userSpaceOnUse" id="radialGradient1847" xlink:href="#linearGradient1284-7" inkscape:collect="always"/>
+ <linearGradient id="linearGradient1117-8-2-0">
+ <stop style="stop-color:#afafaf;stop-opacity:1;" offset="0" id="stop1119-1-6-8"/>
+ <stop style="stop-color:#e6e6e6;stop-opacity:0;" offset="1" id="stop1121-2-2-9"/>
+ </linearGradient>
+ <radialGradient r="38.624973" fy="25.979427" fx="250.46019" cy="25.979427" cx="250.46019" gradientTransform="matrix(1.1864466,0.79500993,-0.21180507,0.31609089,-32.887133,-175.8174)" gradientUnits="userSpaceOnUse" id="radialGradient2262" xlink:href="#linearGradient1117-8-2-0" inkscape:collect="always"/>
+ <linearGradient id="linearGradient1125-6-2">
+ <stop style="stop-color:#969696;stop-opacity:1;" offset="0" id="stop1127-9-0"/>
+ <stop style="stop-color:#e6e6e6;stop-opacity:0;" offset="1" id="stop1129-8-5"/>
+ </linearGradient>
+ <radialGradient r="29.875" fy="219.03677" fx="335.08649" cy="219.03677" cx="335.08649" gradientTransform="matrix(-0.54659184,-0.27740671,-0.6404924,1.2620022,394.97125,17.340932)" gradientUnits="userSpaceOnUse" id="radialGradient2300" xlink:href="#linearGradient1125-6-2" inkscape:collect="always"/>
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient3972" id="radialGradient3978" cx="9.0" cy="10.0" fx="1.0" fy="10.0" r="10.0" gradientUnits="userSpaceOnUse"/>
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient3972" id="radialGradient3980" cx="212.03125" cy="217.67747" fx="212.03125" fy="217.67747" r="16.494078" gradientTransform="matrix(1,0,0,1.5166132,0,-112.45505)" gradientUnits="userSpaceOnUse"/>
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient3972" id="radialGradient3982" cx="248.85938" cy="217.67747" fx="248.85938" fy="217.67747" r="16.697203" gradientTransform="matrix(1,0,0,1.4981632,0,-108.43892)" gradientUnits="userSpaceOnUse"/>
+ <radialGradient inkscape:collect="always" xlink:href="#linearGradient4117" id="radialGradient4123" cx="206.64375" cy="214.43469" fx="206.64375" fy="214.43469" r="190.25014" gradientTransform="matrix(0.97267227,0.01617535,-0.01665626,0.97473856,9.2187856,2.0743911)" gradientUnits="userSpaceOnUse"/>
+ </defs>
+ <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.8075" inkscape:cx="200.0" inkscape:cy="200.0" inkscape:document-units="px" inkscape:current-layer="layer3" showgrid="false" inkscape:snap-page="false" inkscape:snap-global="false" inkscape:window-width="1920" inkscape:window-height="996" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:snap-object-midpoints="true" inkscape:snap-nodes="true" inkscape:snap-grids="false" inkscape:snap-to-guides="false" inkscape:snap-center="true" inkscape:snap-bbox="true" inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" inkscape:bbox-paths="true"/>
+ <metadata id="metadata7">
+ <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>Mumble logo</dc:title>
+ <dc:date>2009.08.17</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Martin Skilnand</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title>Martin Skilnand</dc:title>
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title>Mumble team</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:identifier>mumble.svg</dc:identifier>
+ <dc:source>https://github.com/mumble-voip/mumble/</dc:source>
+ <dc:description>Logo for voice chat program mumble</dc:description>
+ <cc:license rdf:resource="BSD"/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g inkscape:label="Circle" inkscape:groupmode="layer" id="layer1" transform="translate(0,-652.36218)" style="display:inline" sodipodi:insensitive="true">
+ <path sodipodi:type="arc" style="fill:#1a1a1a;stroke:#000000;stroke-width:4.57597017;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" id="path26" sodipodi:cx="206.64375" sodipodi:cy="214.43469" sodipodi:rx="178.98123" sodipodi:ry="174.04742" d="M 385.62498,214.43469 A 178.98123,174.04742 0 0 1 206.64375,388.48212 178.98123,174.04742 0 0 1 27.662521,214.43469 178.98123,174.04742 0 0 1 206.64375,40.387268 178.98123,174.04742 0 0 1 385.62498,214.43469 Z" transform="matrix(1.0811038,0,0,1.1043488,-22.437604,617.97608)"/>
+ <path sodipodi:type="arc" style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" id="path26-9-9-8-6" sodipodi:cx="206.64375" sodipodi:cy="214.43469" sodipodi:rx="178.98123" sodipodi:ry="174.04742" d="M 385.62498,214.43469 A 178.98123,174.04742 0 0 1 206.64375,388.48212 178.98123,174.04742 0 0 1 27.662521,214.43469 178.98123,174.04742 0 0 1 206.64375,40.387268 178.98123,174.04742 0 0 1 385.62498,214.43469 Z" transform="matrix(1.070643,0,0,1.1009928,-22.08154,583.61968)"/>
+ <path sodipodi:type="arc" style="opacity:0.9;fill:#ffffff;stroke:none;display:inline" id="path26-9-0" sodipodi:cx="206.64375" sodipodi:cy="214.43469" sodipodi:rx="178.98123" sodipodi:ry="174.04742" d="M 385.62498,214.43469 A 178.98123,174.04742 0 0 1 206.64375,388.48212 178.98123,174.04742 0 0 1 27.662521,214.43469 178.98123,174.04742 0 0 1 206.64375,40.387268 178.98123,174.04742 0 0 1 385.62498,214.43469 Z" transform="matrix(1.0422741,0,0,1.0695007,-13.735541,622.74462)"/>
+ <path sodipodi:type="arc" style="fill:#ffffff;stroke:#333333;stroke-width:1.41267002;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" id="path26-9" sodipodi:cx="206.64375" sodipodi:cy="214.43469" sodipodi:rx="178.98123" sodipodi:ry="174.04742" d="M 385.62498,214.43469 A 178.98123,174.04742 0 0 1 206.64375,388.48212 178.98123,174.04742 0 0 1 27.662521,214.43469 178.98123,174.04742 0 0 1 206.64375,40.387268 178.98123,174.04742 0 0 1 385.62498,214.43469 Z" transform="matrix(1.0641261,0,0,1.0786838,-20.794262,620.64438)"/>
+ <path sodipodi:type="arc" style="fill:none;stroke:#000000;stroke-width:1.83038807;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" id="path26-8" sodipodi:cx="206.64375" sodipodi:cy="214.43469" sodipodi:rx="178.98123" sodipodi:ry="174.04742" d="M 385.62498,214.43469 A 178.98123,174.04742 0 0 1 206.64375,388.48212 178.98123,174.04742 0 0 1 27.662521,214.43469 178.98123,174.04742 0 0 1 206.64375,40.387268 178.98123,174.04742 0 0 1 385.62498,214.43469 Z" transform="matrix(1.0856629,0,0,1.109006,-24.345467,616.20735)"/>
+ </g>
+ <g inkscape:groupmode="layer" id="layer6" inkscape:label="Effects" style="display:inline" sodipodi:insensitive="true">
+ <path sodipodi:type="arc" style="opacity:0.75;fill:url(#radialGradient4123);fill-opacity:1;stroke:none;display:inline" id="path26-9-5" sodipodi:cx="206.64375" sodipodi:cy="214.43469" sodipodi:rx="178.98123" sodipodi:ry="174.04742" d="m 385.62498,214.43469 a 178.98123,174.04742 0 1 1 -357.962459,0 178.98123,174.04742 0 1 1 357.962459,0 z" transform="matrix(1.0764906,0,0,1.1009349,-20.513668,-34.695518)"/>
+ </g>
+ <g inkscape:groupmode="layer" id="layer4" inkscape:label="Headstrap" style="display:inline" sodipodi:insensitive="true">
+ <path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff" d="m 152.40625,31.610002 c -24.65159,-0.615413 -49.62289,15.704618 -55.852503,40.126444 -1.451111,5.920437 -2.042948,11.533344 -2.147497,17.25104 0,21.207504 0,42.415014 0,63.622514 8.33333,0 16.66667,0 25,0 0.0881,-22.3821 -0.12668,-44.64411 0.1701,-67.071988 0.76858,-14.243077 11.77335,-29.258147 27.0486,-29.08431 0.11203,22.668722 -0.22918,45.351398 0.18004,68.010988 1.30284,18.42605 18.76217,33.67641 37.24339,32.11401 11.54558,-0.2802 23.17762,0.67313 34.64753,-0.72475 17.46577,-3.27442 29.55308,-21.06252 27.92904,-38.4493 0,-20.285732 0,-40.571465 0,-60.857198 15.88808,-1.160259 27.93757,14.263321 28.64235,29.08431 0.29501,22.427208 0.0825,44.692338 0.1701,67.071988 8.33333,0 16.66667,0 25,0 0,-22.5 0,-45 0,-67.499998 -0.81797,-7.276075 -1.9718,-16.180186 -5.9149,-23.198476 -10.22889,-20.751216 -34.15317,-31.947919 -56.71743,-30.261229 -6.591,-0.83713 -13.68143,3.619737 -15.48689,9.866559 0.10876,26.738504 0.18577,53.486212 -0.015,80.219854 -0.75343,11.19988 -11.79041,19.76398 -22.80523,18.34204 -7.79212,0.33854 -16.59364,0.0136 -21.90827,-6.68171 -7.16232,-7.57045 -4.76318,-18.40537 -5.18362,-27.81167 0.0193,-21.718966 -0.0713,-43.418377 0.1249,-65.100368 -3.25934,-6.591257 -10.50309,-9.993605 -17.67905,-8.911927 l -1.18772,-0.01641 -1.25823,-0.04042 2.5e-4,0 z" id="rect1019" transform="matrix(1.05,0,0,1.05,-5.3555131,0.50955272)"/>
+ <path style="opacity:0.96660007;fill:url(#radialGradient1131-6);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" d="m 107.26989,156.26167 0,177.84375 c -35.128105,-3.85349 -62.737498,-42.18816 -62.737498,-88.92187 0,-46.73372 27.609393,-85.06839 62.737498,-88.92188 z" id="path833-1-4"/>
+ </g>
+ <g inkscape:groupmode="layer" id="layer2" inkscape:label="Headphones" style="display:inline" sodipodi:insensitive="true">
+ <path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff" d="m 290.42422,313.15625 c -0.69916,-0.007 -3.31052,-0.57507 -3.94043,-0.16697 0,0 -1.03559,3.01675 -4.60424,5.67254 -3.13272,2.33137 -6.10765,4.56617 -9.29463,6.66254 -2.86157,1.88231 -5.93275,3.91773 -8.80984,5.30245 -2.26396,1.08961 -4.11397,1.24819 -4.11397,1.24819 l -32.21955,0 c -2.01273,0 -3.66178,1.58716 -3.66178,3.5625 l 0,0.875 c 0,1.97534 1.64905,3.59375 3.66178,3.59375 l 33.87945,0 c 0.77968,0 3.59712,-0.82022 5.27249,-1.55528 4.17684,-1.83257 6.89898,-4.16602 11.7099,-7.02744 5.11436,-3.27118 14.57263,-10.88603 14.57263,-10.88603 1.67973,-1.08826 2.12779,-3.28897 1.01893,-4.9375 l -0.47763,-0.75 c -0.69304,-1.03033 -1.82785,-1.58241 -2.99311,-1.59375 z" id="rect134" sodipodi:nodetypes="ccsasccccccaccccc" transform="matrix(1.05,0,0,1.05,-5.3555131,0.50955272)"/>
+ <path style="opacity:0.96660007;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff" d="m 288.25,148.4375 0,169.375 C 321.70534,314.14251 348,277.6333 348,233.125 c 0,-44.5083 -26.29466,-81.01751 -59.75,-84.6875 z" id="path833" transform="matrix(1.05,0,0,1.05,-5.3555131,0.50955272)"/>
+ <path style="opacity:0.96660007;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;display:inline" d="m 106.22355,149.3374 0,169.375 c -33.455343,-3.66999 -59.750003,-40.1792 -59.750003,-84.6875 0,-44.5083 26.29466,-81.01751 59.750003,-84.6875 z" id="path833-2" transform="matrix(1.05,0,0,1.05,-5.3555131,0.50955272)"/>
+ <path sodipodi:type="arc" style="opacity:0.96660007;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff" id="path906" sodipodi:cx="172.61411" sodipodi:cy="325.86444" sodipodi:rx="22.130014" sodipodi:ry="13.831259" d="m 194.74412,325.86444 a 22.130014,13.831259 0 1 1 -44.26003,0 22.130014,13.831259 0 1 1 44.26003,0 z" transform="matrix(1.304789,0,0,1.21464,-20.460693,-43.799678)"/>
+ <rect style="opacity:0.96660007;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.05377054;display:inline" id="rect908-1" width="13.329355" height="171.94623" x="274.71799" y="146.09026" rx="3.8877287" ry="3.5400696" transform="matrix(1.0433338,0,0,1.0500168,-4.6562937,0.09487302)"/>
+ <rect style="opacity:0.96660007;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.04323161;display:inline" id="rect908-1-6" width="13.063269" height="171.95677" x="106.56075" y="147.08498" rx="3.8101201" ry="3.5402865" transform="matrix(1.0433338,0,0,1.0500168,-3.8347589,0.09487302)"/>
+ </g>
+ <g inkscape:groupmode="layer" id="layer3" inkscape:label="Sign" style="display:inline" sodipodi:insensitive="true">
+ <rect style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" id="rect287" width="140.83455" height="111.88522" x="131.63644" y="188.83058"/>
+ <path id="path1297-8" style="fill:url(#radialGradient3978);fill-rule:evenodd;fill-opacity:1;stroke:none" d="M 4.4,18.6 h -4.4 v -18.6 h 4.5 c 5.6 0.0 4.3 8 2 8.5 c 3.5 0.0 4.0 9.4 -1 10.1 z M 2.8,7.4 v -3.9 h 1.2 a 0.8 1.0 0 0 1 0 3.9 z M 2.8,15.2 v -4.6 h 1.7 a 0.8 1.0 0 0 1 0 4.6 z" transform="translate(144,198) scale(4.4, 5)"/>
+ <path id="path1297" style="fill:#ffffff;fill-rule:evenodd;fill-opacity:1;stroke:none" d="M 4.4,18.6 h -4.4 v -18.6 h 4.5 c 5.6 0.0 4.3 8 2 8.5 c 3.5 0.0 4.0 9.4 -1 10.1 z M 2.8,7.4 v -3.9 h 1.2 a 0.8 1.0 0 0 1 0 3.9 z M 2.8,15.2 v -4.6 h 1.7 a 0.8 1.0 0 0 1 0 4.6 z" transform="translate(140,198) scale(4.4, 5)" inkscape:connector-curvature="0"/>
+ <path id="path1299-8" style="font-size:64px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:url(#radialGradient3980);fill-opacity:1;stroke:none;display:inline;font-family:Tahoma;-inkscape-font-specification:Tahoma Bold" d="m 227.5625,240.9431 l -31.0625,0 l 0,-46.53125 l 11.6875,0 l 0,37.65625 l 19.375,0 z" transform="matrix(1.100722,0,0,2.0000717,-23.811797,-190.28066)"/>
+ <path style="fill:#ffffff;fill-opacity:1;stroke:none" d="m 187.3125,197.5625 l 0,94.53125 l 14.125,0 l 0.0625,0 l 21.375,0 l 0,-19.25 l -21.375,0 l 0,-75.28125 l -14.1875,0 z" id="rect3178"/>
+ <path id="path1301-2" style="font-size:64px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:url(#radialGradient3982);fill-opacity:1;stroke:none;display:inline;font-family:Tahoma;-inkscape-font-specification:Tahoma Bold" d="m 233.125,240.9431 l 0,-46.53125 l 31.46875,0 l 0,8.875 l -19.84375,0 l 0,8.15625 l 18.28125,0 l 0,8.875 l -18.28125,0 l 0,11.75 l 19.84375,0 l 0,8.875 z" transform="matrix(1.100722,0,0,2.0000717,-23.811797,-190.28066)"/>
+ <path style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline" d="m 227.8125,197.5 l 0,94.53125 l 14.1875,0 l 21.375,0 l 0,-19.25 l -21.375,0 L 242,250.5 l 19.65625,0 l 0,-18.65625 l -19.65625,0 L 242,216.75 l 21.375,0 l 0,-19.25 l -21.375,0 l -0.0625,0 l -14.125,0 z" id="rect3178-7"/>
+ </g>
+ <g inkscape:groupmode="layer" id="layer5" inkscape:label="Shadow-Glows" style="display:inline" sodipodi:insensitive="true">
+ <path style="fill:url(#radialGradient1847);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" d="m 155.36979,33.010124 c -25.88417,-0.646184 -52.10402,16.489853 -58.645119,42.132764 -1.523665,6.216465 -2.145097,12.11002 -2.254875,18.113595 0,22.267867 0,44.535757 0,66.803627 8.750004,0 17.499994,0 26.249994,0 0.0925,-23.5012 -0.13301,-46.87631 0.17861,-70.425571 0.807,-14.955237 12.36201,-30.72106 28.40103,-30.538528 0.11763,23.802159 -0.24064,47.618949 0.18905,71.411529 1.36798,19.34735 19.70027,35.36023 39.10555,33.71971 12.12286,-0.29421 24.3365,0.70678 36.37991,-0.76099 18.33906,-3.43814 31.03074,-22.11565 29.32549,-40.37177 0,-21.30001 0,-42.600022 0,-63.900042 16.68248,-1.218273 29.33444,14.976486 30.07447,30.538529 0.30976,23.548553 0.0866,46.926943 0.17861,70.425573 8.74998,0 17.5,0 26.25,0 0,-23.625 0,-47.25 0,-70.874984 -0.85887,-7.639884 -2.07039,-16.989202 -6.21065,-24.358407 -10.74033,-21.788774 -35.86083,-33.545313 -59.5533,-31.774288 -6.92055,-0.878987 -14.3655,3.800724 -16.26123,10.359887 0.1142,28.075433 0.19506,56.160521 -0.0157,84.230832 -0.7911,11.75988 -12.37993,20.75218 -23.94549,19.25915 -8.18173,0.35546 -17.42333,0.0143 -23.00369,-7.0158 -7.52043,-7.94897 -5.00134,-19.32564 -5.4428,-29.20225 0.0203,-22.804904 -0.0749,-45.589287 0.13115,-68.355379 -3.42231,-6.92082 -11.02825,-10.493285 -18.56301,-9.357523 l -1.2471,-0.01723 -1.32114,-0.04244 2.6e-4,0 z" id="rect1019-2"/>
+ <path style="fill:url(#radialGradient1193-8);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" d="m 154.53194,34.268657 c -31.65505,0 -56.16894,21.233495 -59.981238,48.759372 l 26.971868,0 c 3.64479,-12.426072 13.11379,-21.517343 24.51094,-22.574997 0.74035,-0.69976 1.77197,-1.148438 2.92031,-1.148438 l 26.61094,0 0.0984,-15.61875 c 0,0 -2.37838,-3.725289 -4.29844,-5.479687 -2.17544,-1.987733 -5.11175,-3.428347 -8.00625,-3.740625 -2.4252,-0.261648 -5.19957,-0.04115 -8.82656,-0.196875 z" id="rect1019-7-4-1"/>
+ <path sodipodi:type="arc" style="opacity:0.96660007;fill:url(#radialGradient967-9);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" id="path906-4" sodipodi:cx="172.61411" sodipodi:cy="325.86444" sodipodi:rx="22.130014" sodipodi:ry="13.831259" d="m 194.74412,325.86444 a 22.130014,13.831259 0 1 1 -44.26003,0 22.130014,13.831259 0 1 1 44.26003,0 z" transform="matrix(1.304789,0,0,1.21464,-20.43351,-43.907478)"/>
+ <path style="opacity:0.96660007;fill:url(#radialGradient1131-8);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" d="m 298.65695,157.25586 0,177.84375 c 35.12811,-3.85349 62.7375,-42.18816 62.7375,-88.92188 0,-46.73371 -27.60939,-85.06838 -62.7375,-88.92187 z" id="path833-1"/>
+ <path style="fill:url(#radialGradient2262);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" d="m 247.96904,33.42223 c 31.65505,0 56.16894,21.233495 59.98124,48.759372 l -26.97187,0 C 277.33362,69.75553 267.86462,60.664259 256.46748,59.606605 c -0.74036,-0.69976 -1.77197,-1.148438 -2.92032,-1.148438 l -26.61093,0 -0.0984,-15.61875 c 0,0 2.37838,-3.725289 4.29844,-5.479687 2.17544,-1.987733 5.11176,-3.428347 8.00625,-3.740625 2.4252,-0.261648 5.19957,-0.04115 8.82656,-0.196875 z" id="rect1019-7-4-1-2"/>
+ <path style="opacity:0.96660007;fill:url(#radialGradient2300);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" d="m 107.92195,156.152 0,177.84375 c -35.128104,-3.85349 -62.737497,-42.18816 -62.737497,-88.92187 0,-46.73372 27.609393,-85.06839 62.737497,-88.92188 z" id="path833-1-5"/>
+ </g>
+</svg> \ No newline at end of file
diff --git a/static/pix/mumble/mumble-1.png b/static/pix/mumble/mumble-1.png
new file mode 100644
index 0000000..8679301
--- /dev/null
+++ b/static/pix/mumble/mumble-1.png
Binary files differ
diff --git a/static/pix/mumble/mumble-2.png b/static/pix/mumble/mumble-2.png
new file mode 100644
index 0000000..a3fb8ae
--- /dev/null
+++ b/static/pix/mumble/mumble-2.png
Binary files differ
diff --git a/static/pix/transmission-web-interface.png b/static/pix/transmission-web-interface.png
new file mode 100644
index 0000000..8b305dd
--- /dev/null
+++ b/static/pix/transmission-web-interface.png
Binary files differ
diff --git a/static/pix/transmission.png b/static/pix/transmission.png
new file mode 100644
index 0000000..6514c24
--- /dev/null
+++ b/static/pix/transmission.png
Binary files differ
diff --git a/static/pix/xmr.svg b/static/pix/xmr.svg
index 002ad9b..ed940b8 100644
--- a/static/pix/xmr.svg
+++ b/static/pix/xmr.svg
@@ -1,7 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
- <g>
- <path d="M127.9983,0.0005 C57.3183,0.0005 0.0003,57.3155 0.0003,127.9975 C0.0003,142.1255 2.2893,155.7145 6.5183,168.4275 L44.7993,168.4275 L44.7993,60.7335 L127.9983,143.9335 L211.1973,60.7335 L211.1973,168.4275 L249.4793,168.4275 C253.7103,155.7145 256.0003,142.1255 256.0003,127.9975 C256.0003,57.3155 198.6813,0.0005 127.9983,0.0005" fill="#FF6600"></path>
- <path d="M108.8673,163.0617 L72.5573,126.7507 L72.5573,194.5157 L58.6773,194.5157 L44.7973,194.5157 L18.6233,194.5157 C41.0923,231.3787 81.6743,255.9967 127.9963,255.9967 C174.3183,255.9967 214.9033,231.3787 237.3703,194.5157 L211.1933,194.5157 L186.3673,194.5157 L183.4373,194.5157 L183.4373,126.7507 L147.1263,163.0617 L127.9963,182.1897 L108.8693,163.0617 L108.8673,163.0617 Z" fill="#4C4C4C"></path>
- </g>
-</svg>
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3756.09 3756.49"><title>monero</title><path d="M4128,2249.81C4128,3287,3287.26,4127.86,2250,4127.86S372,3287,372,2249.81,1212.76,371.75,2250,371.75,4128,1212.54,4128,2249.81Z" transform="translate(-371.96 -371.75)" style="fill:#fff"/><path id="_149931032" data-name=" 149931032" d="M2250,371.75c-1036.89,0-1879.12,842.06-1877.8,1878,0.26,207.26,33.31,406.63,95.34,593.12h561.88V1263L2250,2483.57,3470.52,1263v1579.9h562c62.12-186.48,95-385.85,95.37-593.12C4129.66,1212.76,3287,372,2250,372Z" transform="translate(-371.96 -371.75)" style="fill:#f26822"/><path id="_149931160" data-name=" 149931160" d="M1969.3,2764.17l-532.67-532.7v994.14H1029.38l-384.29.07c329.63,540.8,925.35,902.56,1604.91,902.56S3525.31,3766.4,3855,3225.6H3063.25V2231.47l-532.7,532.7-280.61,280.61-280.62-280.61h0Z" transform="translate(-371.96 -371.75)" style="fill:#4d4d4d"/></svg>