diyhosting.bhh.sh: Web Guides for Internet Landchads! Tutorials on minimalist webpage creation and server maintenance. en-us https://diyhosting.bhh.sh/rss.xml diyhosting.bhh.sh Web Guides for Internet LandChads https://diyhosting.bhh.sh/pix/chad.gif https://diyhosting.bhh.sh/rss.xml Setting up Cgit https://diyhosting.bhh.sh/cgit.html https://diyhosting.bhh.sh/cgit.html Tue, 14 Sep 2021 14:06:48 -0400

Setting up Cgit

Once you have your server hosting your git repositories, you might want to allow others to browse your repositories on the web. Cgit is a Free Software that allows browsing git repositories through the web.

Note that Cgit is a read-only frontend for Git repositories and doesn't have issues, pull requests or user management. If that's what you want, consider installing Gitea instead.

Installing cgit and fcgiwrap

Install fcgiwrap

NGINX doesn't have the capability to run CGI scripts by itself, it depends on an intermediate layer like fcgiwrap to run CGI scripts like cgit:

apt install fcgiwrap

And now we can install cgit itself with:

apt install cgit

Setting up NGINX

You should have an NGINX server running with a TLS certificate by now. Add the following configuration to your server to pass the requests to Cgit, while serving static files directly:


server {
	listen 443 ssl;
	listen [::]:443 ssl;
    ssl_certificate /etc/ssl/nginx/git.example.org.crt;
    ssl_certificate_key /etc/ssl/nginx/git.example.org.key;
    server_name git.example.org;
	root /usr/share/cgit ;
	try_files $uri @cgit ;
	location @cgit {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
		fastcgi_param PATH_INFO $request_uri;
		fastcgi_param QUERY_STRING $query_string;
		fastcgi_pass unix:/run/fcgiwrap.socket;
	}
}
		

Then get NGINX to reload your configuration.

Configuring cgit

You've got cgit up and running now, but you'll probably see it without any style and without any repository. To change this, we need to configure Cgit to our liking, by editing /etc/cgitrc.


css=/cgit.css
logo=/cgit.svg
virtual-root=/
# Title and description shown on top of each page
root-title=Chad's git server
root-desc=A web interface to LandChad's git repositories, powered by Cgit
# The location where git repos are stored on the server
scan-path=/srv/git/
		

This configuration assumes you followed the git hosting guide and store your repositories on the /srv/git/ directory.

Cgit's configuration allows changing many settings, as documented on the cgitrc(5) manpage installed with Cgit.

Changing the displayed repository owner

Cgit's main page shows each repo's owner, which is "git" in case you followed the git hosting guide, but you might want to change the name to yours. Cgit shows the owner's system name, so you need to modify the git user to give it your name:


usermod -c "Your Name" git
		

Changing the repository description

Navigate to your bare repository on the server and edit the description file inside it

Displaying the repository idle time

To do this, we need to create a post-receive hook for each repository that updates the file cgit uses to determine the idle time. Inside your repository, create a file hooks/post-receive and add the following contents:


#!/bin/sh
agefile="$(git rev-parse --git-dir)"/info/web/last-modified
mkdir -p "$(dirname "$agefile")" &&
git for-each-ref \
	--sort=-authordate --count=1 \
	--format='%(authordate:iso8601)' \
	>"$agefile"
		

And give it execution permissions with:

chmod +x hooks/post-receive

Next time you push to that repository, the idle time should reset and show the correct value.

Contribution

]]>
Self hosting https://diyhosting.bhh.sh/selfhosting.html https://diyhosting.bhh.sh/selfhosting.html Sun, 29 Aug 2021 15:35:48 -0400

Self hosting

Introduction

When you have a(n old) computer lying around, and you have cheap electricity and a good internet connection, self hosting might be a good option for you.

Why would you choose selfhosting?

  • You have control over the hardware, and you can upgrade your server in the future. For example: if you host a file server and your hard drive goes full, you can simply add another hard drive or upgrade it.
  • No bandwith limits, storage limits, etc. (some VPSes have this)
  • It can be cheaper than using a VPS. This only is the case if you got the server for really cheap and your electricity is cheap.
  • You can have a media server to consoom your content (for example with Jellyfin). You can technically do this on a VPS, but that will be more expensive than self hosting. If you have a media server, you can stream media from your server to more devices. (I recommend just downloading it on your device, but if you have multiple devices, this could be a good solution)

Downsides

Some possible downsides of choosing to host at home could be:

  • Your ISP not approving of what you're doing. Some ISP's do not condone you hosting at home. Usually when this is the case, it could be harder if you want to forward ports, or it could be impossible to get a static IP address. Check your ISP's terms of service. Sometimes, it will say that hosting a webserver, email server, and more, is not allowed.
  • This can also include blocked ports. ISPs can block certain ports to the world. Sometimes ISPs only block 445/139 (which is for the better as Samba, using these ports isn't really secure and it's outdated). But some ISPs (sadly) block crucial ports like 80 and/or 443. You need to check this before trying anything. If this is the case, a way to get around it is to get another ISP or use an alternative port. A great website to check this is: canyouseeme.org. You can also check if you did the port forwaring correctly here.
  • Security. Opening your network to the public could bring security risks. For example, never open a Samba server to the public, because it's a pretty old protocol, and it has some security vulnerabilities. Be sure you are forwarding the right port, and don't just forward random ports to the internet. Also, if you are getting DDoSed, your ISP will temporarily shut down your whole internet connection.
  • When setting up an email server, it can be way harder to not have your email show up as spam in other's people email. If you use a VPS, this is way easier.
  • Space, power consumption and noise. Of course, this differs per server.

Your mileage may vary, go and check each of these points, and see if selfhosting is the right choice for you. Try and calculate your power consumption and see if your electricity cost is not too expensive.

For me, the upsides outweighed the downsides, which is why I chose to host at home. But, this differs with each person and scenario. Go and research what your exact situation is, before trying anything. Otherwise you'll have to face some bad surprises.

Hardware

What kind of hardware should you choose?

If you pay your own electricity bill, power consumption is a big factor. Most old laptop computers are ideal in the sense that they don't use a lot of power, and if the battery still works, you have a built-in UPS! The bad thing is, most old laptop computers aren't that powerful, and they lack in upgradability. (you shouldn't really be using anything older than 2006, and I recommend at least a performance equivalant of a Core 2 CPU)

If you can find an energy efficient desktop (under 100W), that is a great option. They are pretty upgradable and they don't use a lot of power. They can also be pretty cheap, but old laptops are usually cheaper. If you can afford new hardware, and are willing to build a PC, you can find really power effecient CPU/motherboard combos, and they can be cheap, for example the Celeron J3060. I recommend a low wattage power supply or an effecient one for these kinds of builds. Pico PSUs are pretty tiny and efficient solutions in these builds.

Of course, if you don't pay your electricity bill or cost is not a problem for you, you can use just about any old desktop (as long as it's not from the 90's, I recommend at least a Core 2 chip again, or an Athlon 64 X2).

Usecases

Of course, hardware choices depend on the usecase. The above recommendations I gave you work fine for e-mail server, webserver and fileserver types of applications, but they will struggle to transcode video if you are going to host a media server. You'll need a faster CPU, but also a faster GPU. As an example, the Athlon 200GE or 3000G are good and efficient choices for these builds. They are decent CPUs, but also have a built in GPU that will transcode video just fine.

If you need a lot of storage, go for a case with a lot of mounts for hard drives, this way you can easily mount multiple hard drives. Pros of multiple hard drives are redundancy and speed. Cons could be that they create more heat and noise. You can't use a laptop if you want multiple drives, except if you use a hard drive caddy for the CD/DVD drive bay. Some business laptops even support RAID 1 (redundancy) and RAID 0 (speed and more storage, but you lose your files if one hard drive breaks) this way.

Getting started

Installing Debian

Once you have the machine, you can install the OS. I recommend Debian, as all of the guides on this website are Debian specific. Debian just werks as a server OS.

You'll need to burn a Debian install image onto a USB flash drive or a CD. You can download the image here, and you can also find information on how to burn the image onto a USB flash drive or CD there.

While installing Debian, do not install any desktop environment. But install an SSH server when you get the chance. Also leave webserver unchecked, even if you want to use it as a webserver. You'll have a chance to install this later.

Port forwaring

Every time you are going to set up a new server program, you need to forward a port corresponding to that program. For example, HTTP is port 80, HTTPS is 443, etc. You need to set this up on your router's NAT settings (sometimes just called port forwarding, this differs per router). These steps differ for each router. Refer to your routers manual. A simple command to see what your servers IP address is, is to run ifconfig on your server. This shows a lot of network info, but it will also show your local IP address needed for port forwarding.

Basic ports:

  • SSH: port 22 (open this port if you want to admin your server outside your network)
  • HTTP: port 80 (open this port if you want basic webserver functionality)
  • HTTPS: port 443 (you should open this port if you are setting up a webserver because encryption)

Static or dynamic IP address

If you want to host your server at home, make sure you have a static IP address, or you can change your dynamic IP address to a static one. Refer to your router settings, some ISPs will have options on this here. If you can't find anything on this, get in touch with your ISP.

Once you've made sure you have a static IP address, you can find out what the IP address is with various websites. You can use a search engine to easily find this out. Write this down as you'll need it later.

Once you're done, you can pretty much follow every guide on this website, the only difference is that you'll need to forward the ports you'll be using for the server.

Finding the ports you'll need to forward

If you need to know what port you'll need to forward, there's a command for that. Just type netstat -tulpn in your servers command line. If you want to see the name of the programs, you need to run it as a root user. You can do this by putting sudo before the command.

Local Address                    State       PID/Program name
0.0.0.0:25                       LISTEN      887/master
0.0.0.0:1883                     LISTEN      22452/mosquitto
0.0.0.0:445                      LISTEN      798/smbd
0.0.0.0:993                      LISTEN      381/dovecot
127.0.0.1:3306                   LISTEN      560/mysqld
0.0.0.0:587                      LISTEN      887/master
0.0.0.0:139                      LISTEN      798/smbd
127.0.1.1:12301                  LISTEN      412/opendkim
0.0.0.0:143                      LISTEN      381/dovecot
0.0.0.0:465                      LISTEN      887/master
0.0.0.0:22                       LISTEN      472/sshd
:::25                            LISTEN      887/master
:::443                           LISTEN      1769/apache2
:::1883                          LISTEN      22452/mosquitto
:::445                           LISTEN      798/smbd

Example output

In this example, if you need to find the port number from dovecot, you can look for it in the Program name column. Then you can see in the local address column that the reported local address is 0.0.0.0:993. You need to look for the part after the semicolon. In this case it's 993. So you'll need to forward port 993.

Next: Connect Your Domain and Server

Written by hiddej

]]>
Mirror your site over I2P https://diyhosting.bhh.sh/i2p.html https://diyhosting.bhh.sh/i2p.html Sun, 29 Aug 2021 15:32:44 -0400

Mirror Your Site Over I2P

I2P logo

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.

Installing I2P

i2pd is in most repos, in debian/ubuntu you can install it simply with

apt install i2pd

Enabling I2P

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:

useradd -m i2p -s /bin/bash
su -l i2p
mkdir ~/.i2pd
cd ~/.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:

[example]
type = http
host = 127.0.0.1
port = 8080
keys = example.dat

Getting your I2P Hostname

Then, run /usr/sbin/i2pd --daemon to start i2pd and we can retreive our 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:

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)

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 up until the server block of code. Instead, paste this:

server {
listen 127.0.0.1:8080 ;
root /var/www/example ;
index index.html ;
}

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.

Update regularly!

Make sure to update I2P on a regular basis by running:

apt update && apt install i2pd

Contributor - qorg11

]]>
Setting up a Calibre library server https://diyhosting.bhh.sh/calibre.html https://diyhosting.bhh.sh/calibre.html Tue, 03 Aug 2021 13:49:21 -0400

Setting up a Calibre library server

Calibre logo

The Calibre library server is a great way to store your eBooks. It allows you to:

  • Share your books with others.
  • Easily transfer your books between devices and access them from anywhere.

Installation

Install the Calibre package. You might also want rsync to upload books.

apt install -y calibre rsync
mkdir /opt/calibre

Either upload your existing library using rsync. For example to /opt/calibre/.

On client:

cd ~/Documents
rsync -avuP your-library-dir root@example.org:/opt/calibre/

Or create a library and add a book to it:

cd /opt/calibre
calibredb add book.epub --with-library your-library

Add a new user to protect your server:

calibre-server --manage-users

Creating a service

Create a new file /etc/systemd/system/calibre-server.service and add the following:

[Unit]
Description=Calibre library server
After=network.target
[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/bin/calibre-server --enable-auth --enable-local-write /opt/calibre/your_library --listen-on 127.0.0.1
[Install]
WantedBy=multi-user.target

Issue systemctl daemon-reload to apply the changes.

Enable and start the service.

systemctl enable calibre-server
systemctl start calibre-server

A reverse proxy with Nginx

Create a new file /etc/nginx/sites-available/calibre and enter the following:

server {
    listen 80;
    client_max_body_size 64M; # to upload large books
    server_name calibre.example.org ;
    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

Issue a Let's Encrypt certificate. Detailed instructions and additional information.

certbot --nginx

Now just go to calibre.example.org. The server will request an username and a password.

calibre

After login you will see something like this.

calibre

Contribution

  • Author: rflx – website -- XMR: 48T5XpHTXAZ5Nn8YCypA4aWn1ffQLHJkFGDArXQB6cmrP6cqLY72cu7CR2iq2MmL5Ndu3d47e5MKjGpL4prYgdrTCFAHD9c
  • ]]>
    Jitsi Video Chat https://diyhosting.bhh.sh/jitsi.html https://diyhosting.bhh.sh/jitsi.html Tue, 03 Aug 2021 13:00:23 -0400

    Jitsi Video Chat

    Jitsi

    Jitsi is a set of open-source projects that allows you to easily build and deploy secure video conferencing solutions.

    Is really easy to install, and also a really good private, federated and libre alternative to Zoom or other video conferencing software. You can create calls just by typing the URL, and loging-in is not necessary.

    Dependencies and Installation

    First, install some dependencies:

    apt install gpg apt-transport-https nginx python3-certbot-nginx

    Jitsi has its own package repository, so let's add it.

    curl https://download.jitsi.org/jitsi-key.gpg.key | gpg --dearmor > /usr/share/keyrings/jitsi-keyring.gpg
    echo 'deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/' > /etc/apt/sources.list.d/jitsi-stable.list
    apt update -y

    Ok. So now we can install Jitsi, but before we do that, let's the firewall ufw, in case you have it enabled, and the SSL certificate.

    Enable Required Ports

    If you are using ufw or another firewall, there are several ports we need to ensure are open:

    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw allow 10000/udp
    ufw allow 3478/udp
    ufw allow 5349/tcp
    ufw enable

    For your information, these allow the following:

    • 80 TCP – Certbot.
    • 443 TCP – General access to Jitsi Meet.
    • 10000 UDP – General network video/audio communications.
    • 3478 UDP – Quering the stun server (coturn, optional, needs config.js change to enable it).
    • 5349 TCP – Fallback network video/audio communications over TCP (when UDP is blocked for example), served by coturn.

    SSL certificate

    I'll be using certbot and Nginx to generate a certificate for the Jitsi subdomain to allow encrypted connections.

    certbot --nginx certonly -d meet.example.org

    We will not create an Nginx config file for Jitsi because the Jitsi package we will be installing will do that automatically.

    Installation

    To begin the installation process, just run:

    apt install jitsi-meet

    It will ask you for your hostname; there you'll need to input the subdomain you have just added to Nginx, like meet.example.org.

    For the SSL certificate, choose I want to use my own certificate.

    When it ask you for the certification key and cert files, input /etc/letsencrypt/live/meet.example.org/privkey.pem and /etc/letsencrypt/live/meet.example.org/cert.pem respectively.

    Using Jitsi

    Jitsi once installed

    Jitsi can be used in a browser by then just going to meet.example.org.

    Note that there are also Jitsi clients for all major platforms:

    When using a Jitsti app for the first time, remember to go to the "Settings" menu and change your server name to the Jitsi site you just created.

    When you create a video chatroom, its address will appear as meet.example.org/yourvideochatname and can be shared as such.

    More info

    This article is based on the original documentation. There you can find more details and configurations.

    • Written by Jose Fabio. Donate Monero: 484RLdsXQCDGSthNatGApRPTyqcCbM3PkM97axXezEuPZppimXmwWegiF3Et4BHBgjWR7sVXuEUoAeVNpBiVznhoDLqLV7j [QR]
    • Edited and revised by Luke.
    ]]>
    PeerTube Instance https://diyhosting.bhh.sh/peertube.html https://diyhosting.bhh.sh/peertube.html Thu, 29 Jul 2021 10:44:56 -0400

    PeerTube Instance

    PeerTube logo

    PeerTube is a self-hosted and (optionally) federated video sharing platform that saves bandwith on videos the more people watch. PeerTube instances can follow each other to share videos and grow the federated network, but you can always keep your instance to yourself if you choose to.

    Prerequisites

    Most of PeerTube's dependencies can be installed with this command:

    apt install -y curl sudo unzip vim ffmpeg postgresql postgresql-contrib g++ make redis-server git python-dev cron wget

    It's also important to start all associated daemons:

    systemctl start postgresql redis

    PeerTube also requires NodeJS 14 and yarn which cannot be installed from the Debian repositories. This means they have to be installed from separate, external repos:

    curl -fsSL https://deb.nodesource.com/setup_14.x | bash -
    apt install -y nodejs
    npm install --global yarn

    In addition to these dependencies, it's recommended to create a dedicated PeerTube user to install and manage PeerTube.

    useradd -m -d /var/www/peertube -s /bin/bash -p peertube peertube

    Database

    PeerTube requires a PostgreSQL database to function. To create it, first make a new Postgres user named PeerTube:

    su postgres
    createuser -P peertube
    createdb -O peertube -E UTF8 -T template0 peertube_prod
    psql -c "CREATE EXTENSION pg_trgm;" peertube_prod
    psql -c "CREATE EXTENSION unaccent;" peertube_prod
    exit

    Be sure to make note of your Postgres user password, as it will be needed later when setting up PeerTube.

    Installation

    This handy one-liner can be used to determine the latest PeerTube version:

    VERSION=$(curl -s https://api.github.com/repos/chocobozzz/peertube/releases/latest | grep tag_name | cut -d '"' -f 4) && echo "Latest Peertube version is $VERSION"

    Next, a basic directory structure needs to be setup in the PeerTube user's home directory (/var/www/peertube).

    To ensure permissions remain the same while managing files as PeerTube, sudo can be used to perform actions:

    sudo -u peertube mkdir config storage versions
    sudo -u peertube chmod 750 config

    Finally, a PeerTube release can be downloaded from the GitHub page and installed using yarn:

    cd versions
    sudo -u peertube ln -s versions/peertube-${VERSION} ./peertube-latest
    cd ./peertube-latest && sudo -H -u peertube yarn install --production --pure-lockfile

    Configuration

    PeerTube's default config file can be copied over to /var/www/peertube/config.production.yaml so it can actually be used:

    cd /var/www/peertube
    	sudo -u peertube cp peertube-latest/production.yaml config/production.yaml

    Now the production.yaml file must be edited in the following ways:

    First, add the hostname:

    webserver:
      https: true
      hostname: 'example.org'
      port: 443

    Then, the database:

    database:
      hostname: 'localhost'
      port: 5432
      ssl: false
      suffix: '_prod'
      username: 'peertube'
      password: 'your_password'
      pool:
         max: 5

    An email to generate the admin user:

    admin:
      # Used to generate the root user at first startup
      # And to receive emails from the contact form
      email: 'chad@example.org'

    And optionally, email server information:

    smtp:
      # smtp or sendmail
      transport: smtp
      # Path to sendmail command. Required if you use sendmail transport
      sendmail: null
      hostname: mail.example.org
      port: 465 # If you use StartTLS: 587
      username: your_email_username
      password: your_email_password
      tls: true # If you use StartTLS: false
      disable_starttls: false
      ca_file: null # Used for self signed certificates
      from_address: 'admin@example.org'

    NGINX

    PeerTube includes an NGINX configuration that can be copied over to /etc/nginx/sites-available:

    cp /var/www/peertube/peertube-latest/support/nginx/peertube /etc/nginx/sites-available/peertube

    Because the PeerTube config is so long, it's recommended to use sed to modify the contents of the file, replacing ${WEBSERVER_HOST} with your hostname, and $(PEERTUBE_HOST) with your localhost and port, which by default should be 127.0.0.1:9000:

    sed -i 's/${WEBSERVER_HOST}/example.org/g' /etc/nginx/sites-available/peertube
    sed -i 's/${PEERTUBE_HOST}/127.0.0.1:9000/g' /etc/nginx/sites-available/peertube

    Once you're happy with the NGINX config file, link it to sites-enabled to activate it:

    ln -s /etc/nginx/sites-available/peertube /etc/nginx/sites-enabled/peertube

    Encryption with Certbot

    It's highly recommended to generate certificates for use with your PeerTube site, and this can be easily done with Let's Encrypt's certbot command:

    systemctl stop nginx
    certbot certonly --standalone -d example.org
    sudo systemctl restart nginx

    The certificates are generated standalone since the PeerTube NGINX config file already includes configuration for certbot.

    Running PeerTube

    A config file for a systemd daemon is included in PeerTube and can be setup like so:

    cp /var/www/peertube/peertube-latest/support/systemd/peertube.service /etc/systemd/system/
    systemctl daemon-reload

    Now, finally, run the PeerTube daemon to start PeerTube:

    systemctl start peertube

    Using PeerTube

    To set a password for your admin user, run:

    cd /var/www/peertube/peertube-latest && NODE_CONFIG_DIR=/var/www/peertube/config NODE_ENV=production npm run reset-password -- -u root

    Login to your PeerTube instance using the admin email specified in your production.yaml file and the admin password you just set.

    Once logged in, it's recommended to create a separate user without admin privileges for uploading videos to PeerTube. This can be done easily from the users tab in the administration section:

    Enjoy your PeerTube instance!


    Updating PeerTube

    PeerTube is constantly adding new features, so it's a good idea to check for new updates and add them if you wish. Just in the past year, they have added livestreaming and more.

    Updating is fairly easy now since an upgrade.sh script has been added. Just run:

    cd /var/www/peertube/peertube-latest/scripts && sudo -H -u peertube ./upgrade.sh

    Although check the changelog to see if there are additional manual requirements for particular updates.


    Written by Denshi. Donate Monero here [QR]

    ]]>
    Server-Side Scripting with CGI https://diyhosting.bhh.sh/cgi.html https://diyhosting.bhh.sh/cgi.html Sun, 25 Jul 2021 14:29:44 -0400

    Server-Side Scripting with CGI

    The basic website tutorial here describes how to set up a static website — one that just serves HTML files saved on your server, and until you change something manually, the same content will be served each time a given page is requested. This is perfectly enough for most personal website needs. This is how blogs should be implemented, instead of relying on bloatware like WordPress!

    But sometimes you genuinely do need something more. You need your website to serve different contents depending on the time, on who the requester is, on the contents of a database, or maybe process user input from a form.

    CGI

    CGI, or the Common Gateway Interface, is a specification to allow you, the server owner, to program your web server using pretty much any programming language you might know. The specification is almost as old as the Internet itself and for a long time CGI scripting was the primary method of creating dynamic websites.

    CGI is a very simple specification indeed. You write a script in your favorite language, the script receives input about the request in environment variables, and whatever you print to the standard output will be the response. Most likely, though, you will want to use a library for your language of choice that makes a lot of this request/response handling simpler (e.g. parsing query parameters for you, setting appropriate headers, etc.).

    Limitations of CGI

    While in theory you could implement any sort of functionality with CGI scripts, it's going to get difficult managing a lot of separate scripts if they're supposed to be working in tandem to implement a dynamic website. If you want to build a full out web application, you'd probably be better off learning a web framework than gluing together Perl scripts.

    That said, just as most of the web could be replaced with static websites, much of the remaining non-static web could be replaced with a few simple scripts, rather than bloated Ruby on Rails or Django applications.

    Let's write a CGI script!

    We'll implement a simple example CGI script. I'll use Ruby for this tutorial, but you'll be able to follow along even if you don't know Ruby, just treat it as pseudocode then find a CGI library for your language.

    The working example

    Our working example will be the Lazy Calculator. Yeah, you're probably tired of seeing calculator examples in every programming tutorial, but have you ever implemented one that takes the weekends off?

    Here's how it will work. When in a browser you submit a request to your website like

    example.com/calculator.html?a=10&b=32

    you will receive a page with the result of the addition of 10 and 32: 42.

    Unless you send your request on a weekend. Then the website will respond with

    I don't get paid to work on weekends! Come back Monday.

    This example will show a few things that CGI scripts can do that you wouldn't have been able to get using just file hosting in your web server:

    • getting inputs from the user;
    • getting external information (here just the system time, but you could imagine instead connecting to a database);
    • using the above to create dynamic output.

    The code

    Here's an implementation of the lazy calculator as a Ruby CGI script:

    #!/bin/env ruby
    require 'cgi'
    require 'date'
    cgi = CGI.new
    today = Date::today
    a = cgi["a"].to_i
    b = cgi["b"].to_i
    if today.saturday? || today.sunday?
      cgi.out do
        "I don't get paid to work on weekends! Come back Monday."
      end
    else
      cgi.out do
        (a + b).to_s
      end
    end

    Let's go through what's happening here.

    The shebang line

    CGI works by pointing your web server to an executable program. A Ruby or Python script by itself is not immediately executable by a computer. But on Unix-like systems you can specify the program that will be able to execute your file in its first line if it starts with #! (known as the shebang; read more about it on Wikipedia).

    So if you're going to be using a scripting language, you'll probably need the appropriate shebang line at the top of your script. If you use a compiled language, you'll just point your web server to the compiled executable binary.

    Query parameters

    The next interesting lines of code are where we set the variables a and b. Here we are getting user inputs from the request.

    In the example request we mentioned above (example.com/calculator.html?a=10&b=32), the part starting from the question mark, ?a=10&b=32, is the query string. This is how users can submit parameters with their web requests. Usually these parameters are set by e.g. a form on your website, but in our simple example we'll be just manually manipulating the URL.

    The query string contains key-value pairs. The Ruby CGI library makes them available in the CGI object it provides. We just need to index it with the desired key, and we'll get the corresponding value.

    Wrapping it up

    The remaining parts of the code should be pretty self-explanatory. We get today's date, check if it's a Saturday or a Sunday, and depending on that, we instruct the CGI library to output either the answer, or a "come back later" message.

    The Ruby library by default returns an HTML response, so we really should have wrapped our outputs in some html, body, etc. tags. Alternatively, we could have specified that the response is just plain text with

    cgi.out 'text/plain' do

    In general, your CGI library will probably have ways of specifying all sorts of HTTP response headers, like status code, content type, etc.

    Making it work

    We have a CGI script, now let's point our web server to it.

    Installing FastCGI

    If you're using Nginx, install fcgiwrap:

    apt install fcgiwrap

    This installs the necessary packages for Nginx to use FastCGI — a layer between your web server and CGI script that allows for faster handling of scripts than if the web server had to handle it all by itself.

    Other web servers will probably have a similarly simple way of enabling FastCGI, or you can look into other methods for launching CGI scripts.

    Nginx configuration

    In the configuration file for your website, add something like the following:

    location /calculator.html {
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME /usr/local/bin/lazy-calculator.rb;
      fastcgi_param QUERY_STRING $query_string;
      fastcgi_pass unix:/run/fcgiwrap.socket;
    }

    fastcgi_param directives specify various parameters for FastCGI. SCRIPT_FILENAME should point to your executable. For QUERY_STRING, we just copy Nginx's $query_string variable. You might want to pass other information to your CGI script as well, see for example the Debian wiki for a more detailed example, including pointing to an entire directory of CGI scripts, rather than adding each one by hand to your web server config.

    Contribution

    ]]>
    XMPP Server (Prosody) https://diyhosting.bhh.sh/xmpp.html https://diyhosting.bhh.sh/xmpp.html Wed, 21 Jul 2021 22:58:21 -0400

    XMPP Server (Prosody)

    XMPP Logo and Icon

    XMPP is a fantastically simple protocol that's usually used as a messenger. It's highly extensible, better than IRC, lighter and more decentralized and Matrix and Telegram and normie social media can't hold a candle to it.

    XMPP is so decentralized and extensible that there are many different XMPP servers. Here, let's set up an Prosody XMPP server.

    Installation

    Prosody is in the Debian repositories, so we can easily install it on our server with the following command:

    apt install prosody

    Configuration

    The Prosody configuration file is in /etc/prosody/prosody.cfg.lua. To set it all up, we will be changing several things.

    Setting Admins

    Let's go ahead and set who our admin(s) will be. Find the line that says admins = { } and to this we can specify one or more server admins.

    # To add one admin:
    admins = { "chad@example.org" }
    # We can add more than one by separating them by commas. (This file is written in Lua.)
    admins = { "chad@example.org", "chadmin@example.org" }

    Note that we have not created these accounts yet, we will do this below.

    Set the Server URL

    Find the line VirtualHost "localhost" and replace localhost with your domain. In our case, we will have VirtualHost "example.org"

    Multi-User Chats

    Most people will probably want the ability to have chats with more than two users. This is easily enough to enable. In the config file, add the following:

    Component "chat.example.org" "muc"
        modules_enabled = { "muc_mam" }
        restrict_room_creation = "admin"

    On the first line, you must have a separate subdomain for your multi-user chats. I use the chat. subdomain, but some use muc.. Anything if possible.

    The second line is important because it prevents non-admins from creating and squatting rooms on your server. The only situation where you might not want that is if you indend to open a general public chat system for people you don't know.

    End-to-end Encryption

    Importantly, we'll want end-to-end encryption enabled for user privacy.

    Find the array beginning with modules_enabled. This includes a list of modules to be used. Add "omemo_all_access"; to that list. Additionally, be sure to change the module pep to pep_simple or this will cause a conflict.

    This module is not installed by default, but you can easily download it by running the following command on the command prompt to download and install the module to the correct directory.

    curl -sL https://hg.prosody.im/prosody-modules/raw-file/785389a2d2b3/mod_omemo_all_access/mod_omemo_all_access.lua > /usr/lib/prosody/modules/mod_omemo_all_access.lua

    Other things to check

    Check the config file for other settings you might want to change. For example, if you want to run a general public XMPP server, you can allow anyone to create an account by changing allow_registration to true.

    Certificates

    Obviously, we want to have client-to-server and server-to-server encryption. Nowadays, use can use Certbot to generate certificates and use a convenient command below prosodyctl to import them.

    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.

    certbot -d chat.example.org --nginx

    Once you have the certificates for encryption, run the following to import them into Prosody.

    prosodyctl --root cert import /etc/letsencrypt/live/

    Note that you might get an error that a certificate has not been found if your muc subdomain and your main domain share a certificate. It should still work, this is just notifying you that no specific

    For user privacy, we will definitely want to install and enable encryption with OMEMO.

    Creating users/admins manually

    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:

    prosodyctl adduser chad@example.org

    This will prompt you to create a password as well.

    Make changes active

    With any system service, use systemctl reload or systemctl restart to make the new settings active:

    systemctl restart prosody

    Using your Server!

    Once your server is set up, you just need an XMPP client to use your new and secure chat system.

    Install whichever of these clients you want on your computer or phone and you can log into your new XMPP server with the account you made. Note that if you enabled public registration, anyone can create an account on your server through one of these clients.

    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.

    Note on MUCs (multi-user chats)

    Remember that MUCs are kept on a separate subdomain that we created and should've gotten a certificate for above, for example, muc.example.org. Chatrooms are created and referred to in the following format: #chatroomname@muc.example.org.

    ]]>
    Setting up RSS Bridge https://diyhosting.bhh.sh/rss-bridge.html https://diyhosting.bhh.sh/rss-bridge.html Mon, 05 Jul 2021 18:11:15 -0400

    Setting up RSS Bridge

    RSS Bridge is a useful utility you can use to help you avoid the big tech sites, like Facebook and Twitter, which instead of the feed you usually would see, will be a based and minimalist RSS feed.

    You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address which is explained in this tutorial.

    Installation

    Setting Up and Configuring

    First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban. There's a great tutorial on how to do this which can be read here.

    Next we'll install the required packages:

    apt install -y curl unzip nginx certbot php-fpm php-mysql php-cli php7.3-mbstring php7.3-curl php7.3-xml php7.3-sqlite3 php7.3-json

    We now have to create the website configuration file. Create/open the a file below:

    nano /etc/nginx/sites-available/rss-bridge

    And add the following content:

    server {
        root /var/www/rss-bridge;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name rss-bridge.example.org;
        location / {
                try_files $uri $uri/ =404;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
        }
        location ~ /\.ht {
                deny all;
        }
    }
    

    After you have saved the file, you need to create a symlink so the server actually will read the file.

    ln -s /etc/nginx/sites-available/rss-bridge /etc/nginx/sites-enabled/rss-bridge

    Then we have to create the folder where the service will reside in.

    mkdir -p /var/www/rss-bridge
    cd /var/www/rss-bridge
    

    Lets download the latest version of RSS-Bridge in the directory.

    The newest version can be found here, at the time of writing that is "RSS-Bridge 2021-04-25."

    wget https://github.com/RSS-Bridge/rss-bridge/archive/refs/tags/2021-04-25.zip

    Unzip the file:

    unzip 2021-04-25.zip

    This will create a directory called rss-bridge-version-number, we now want to move all the file contents of the newly created directory to the one we are in

    mv rss-bridge-2021-04-25/* .
    rm -rf rss-bridge-2021-04-25 2021-04-25.zip
    

    Now all we need to do is grant read/write permissions and reload the web server.

    chown -R www-data:www-data /var/www/rss-bridge
    systemctl reload nginx
    

    That's it, you should now have a working rss-bridge installed. But you should definately get an SSL certifcate installed which is done briefly here.

    • handskemager.xyz
    • Bitcoin: bc1qhfjgwjzksf2auqjefwpvq20wvyugq3lhqgkxvu
    • Monero: 88cPx6Gzv5RWRRJLstUt6hACF1BRKPp1RMka1ukyu2iuHT7iqzkNfMogYq3YdDAC8AAYRqmqQMkCgBXiwdD5Dvqw3LsPGLU
    ]]>
    Rsync: Upload and Sync Files and Websites https://diyhosting.bhh.sh/rsync.html https://diyhosting.bhh.sh/rsync.html Sat, 03 Jul 2021 08:58:29 -0400

    Rsync: Upload and Sync Files and Websites

    rsync is a simple way to copy files and folders between your local computer and server.

    It not only makes file-transfer easy, but it allows you to build and maintain your website offline, then easily upload it to the proper directory on your server so you don't need to constantly be logged into your server to modify your site.

    Installing rsync

    Run the following on your server and on your local machine.

    apt install rsync

    Uploading files with rsync

    From your local machine you can upload files to your server like this:

    rsync -ruvzP /path/to/file root@example.org:/path/on/the/server

    You will be prompted for the root password and then uploading will commence.

    If you omit root@, rsync will not attempt to log in as root, but whatever your local username is.

    Options to rsync

    In this command, we give several options to rsync:

    • -r – run recurssively (include directories)
    • -u – update files (do not reupload files that are not changed since last upload)
    • -v – visual, show files uploaded
    • -z – compress files for upload
    • -P – if uploading a large file and upload breaks, pick up where we left off rather than reuploading the entire file

    Avoid using the commonly used -a option when uploading. It changes can transfer your local machine's user and group permissions to your server, which might cause breakage.

    Scriptability

    It's a good idea to build your website offline, then make an rsync script or bash alias like the one above to upload the edited files when you have made updates.

    Password-less authentication

    To avoid having to manually input your password each upload, you can set up SSH keys to securely idenitify yourself and computer as a trusted.

    Picky trailing slashes

    rsync is very particular about trailing slashes. This is useful, but can be confusing to some new users. Suppose we run the following wanting to mirror our offline copy of our website in the directory we use on our server (/var/www/websitefiles/):

    rsync -ruvzP ~/websitefiles/ root@example.org:/var/www/websitefiles/

    This will not actually do quite what we want. It will take our local websitefiles directory and put it inside websitefiles on the remote machine, ending up with: /var/www/websitefiles/websitefiles.

    Instead, remove the trailing slash from the remote server location:

    rsync -ruvzP ~/websitefiles/ root@example.org:/var/www/websitefiles

    websitefiles/ has been replaced with websitefiles, and this will do what we want.

    Downloading files with rsync

    You may just as easily download files and directories from your server with rsync:

    rsync -urvzP root@example.org:/path/to/file /path/to/file

    Contribution

    • el3ctr0lyte: github, XMR: 86DBJdiG83ZDea6kJgsbVN5tMae5ScfuhJ3PihEMTHatCrGEw2gctyUB92V2fz4R4YhwRaQeAGL5M4gPRXvVvtkULJi4ayk
    • Substantial revisions by Luke
    ]]>
    Setup a Pleroma Server https://diyhosting.bhh.sh/pleroma.html https://diyhosting.bhh.sh/pleroma.html Fri, 02 Jul 2021 09:14:32 -0400

    Setup a Pleroma Server

    Hopefully by now you won't have to be sold on the invasive practices that social media companies conduct. Websites such as Facebook and Twitter aquire so much data on users that they often know more about you than you know about yourself. The simple solution to this is to not use social media. However, that just isn't an option for most people. So the next best thing is to setup a self-hosted and federalised social media site so that you have full control over your data. I've previously made a video showing all the steps in depth if you want to check it out. If you run into any issues I suggest you look at the video.

    You'll need a server or VPS. Nearly any Operating system is supported but for this tutorial I'm gonna presume you're using a Debian-based OS. You'll also need a domain name pointing to your server's IP address which is explained in this tutorial.

    Installation

    Setting Up and Configuring

    First things first you'll need to make sure that you've hardened you SSH so that password authentication is disabled and you'll also want to setup Fail2Ban. There's a great tutorial on how to do this which can be read here.

    Next we'll install the required packages:

    apt install -y curl unzip libncurses5 postgresql postgresql-contrib nginx certbot libmagic-dev

    You can manually configure postgreSQL to suit your system better. Check out the documentation here and then run the below command:

    systemctl restart postgresql

    Installing the Pleroma App

    First as the root user

    Pleroma is not in the Debian app repositories, so we will install it manually. First create the Pleroma user by running the below command:

    useradd -m -s /bin/bash -d /opt/pleroma pleroma

    Then, still as root, we will create the required directories and give the Pleroma user ownership of them.

    mkdir -p /var/lib/pleroma/uploads
    chown -R pleroma /var/lib/pleroma
    mkdir -p /var/lib/pleroma/static
    chown -R pleroma /var/lib/pleroma
    mkdir -p /etc/pleroma
    chown -R pleroma /etc/pleroma

    Now, as the new Pleroma user

    Now run su -l pleroma to login as the Pleroma user. Now use the curl command below to download the Pleroma software and unzip it.

    curl 'https://git.pleroma.social/api/v4/projects/2/jobs/artifacts/stable/download?job=amd64' -o /tmp/pleroma.zip
    unzip /tmp/pleroma.zip -d /tmp/
    mv /tmp/release/* /opt/pleroma
    rmdir /tmp/release
    rm /tmp/pleroma.zip
    ./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql

    We need to briefly return to the root user so we can run the following command (via the postgres user) to set up the database. Type ctrl-d or run exit to return to the root user, then run:

    su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"

    Then return to the pleroma user with su -l pleroma and we will test to see that Pleroma can run:

    ./bin/pleroma_ctl migrate
    ./bin/pleroma daemon

    That will initialize Pleroma. It might take as long as a minute to get started, so wait a bit, then run the following:

    curl http://localhost:4000/api/v1/instance

    If everything is working, this command will give you a long line of messy output. If it is not, you will get a connection error message. Once it is working successfully, stop the Pleroma daemon and we will interface Pleroma with the web server.

    ./bin/pleroma stop

    Setup and Configure Nginx

    Return again to the root user. Let's copy Pleroma's Nginx configuration file from the template given in the installation and enable it:

    cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.conf
    ln -s /etc/nginx/sites-available/pleroma.conf /etc/nginx/sites-enabled/pleroma.conf

    Edit the etc/nginx/sites-available/pleroma.conf file and replace example.tld with your domain name.

    We now have to get a SSL certificate to enable encryption, since we have a model configuration that already includes SSL information, just check the brief the standalone certificate page to get the needed certificate. Once you've got your cert setup, copy over the Nginx configuration with the below command:

    Once everything, including your Cerbot certificate is ready, simply reload Nginx with this command:

    systemctl reload nginx

    Setting up the service

    Pleroma itself runs on a SystemD service similar to other things running on your server like Nginx. To start the service up run the below commands:

    cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service
    systemctl start pleroma
    systemctl enable pleroma

    If everything worked then when you go to your domain in the web browser you should see a bare-bones Pleroma instance.

    Creating an Admin User

    You'll be able to create new accounts on the Pleroma instance in the login section on the website but the easiest way to setup an admin account is with the CLI. Simply run the below command replaced with your username:

    su -l pleroma
    ./bin/pleroma_ctl user new username username@example.org --admin

    If you run into any issues then feel free to checkout the documentation or send me an email or message. My details are below.

    • biasedriot.co
    • youtube
    • Bitcoin: 1Dmn9jEtWAhdLk1HHWkUVNeDdAaBCwNajm
    • Monero: 84Y4FZiTbLeR5qc1fBrBhB1yq5agKtEdoixq2w1ysXJv486MiBCz3czGT15bqeXDPpdLoNyF93inxY3BCk6g8mrDMNKoArS
    ]]>
    Certbot on Standalone Domains and Subdomains https://diyhosting.bhh.sh/standalone.html https://diyhosting.bhh.sh/standalone.html Fri, 02 Jul 2021 09:14:29 -0400

    Certbot on Standalone Domains and Subdomains

    The command certbot --nginx will take an unencrypted website on an Nginx configuration file, get a certificate for it and change the configuration to use that certificate and thus HTTPS.

    Sometimes, however, you are given an Nginx configuration template that already has encryption/HTTPS, so running the automated certbot --nginx is not possible, as it will simply give an error saying that the certicate that Nginx is looking for doesn't already exist and thus the Nginx config is broken.

    So suppose you want to get a certificate for pleroma.example.org because you are installing Pleroma and the configuration file presupposes a certificate. In this case you would want to run this:

    systemctl stop nginx
    certbot certonly --standalone -d pleroma.example.org
    systemctl start nginx

    What we do here is temporarily turn of Nginx, then run a certonly subcommand that generates a certificate for the domain without changing or caring about the Nginx configuration. Then we reactivate Nginx, thus turning back on our webserver.

    The reason we deactivate Nginx is that it uses the ports that Certbot will want to bind to, and thus we must temporarily turn Nginx off to let Certbot use those ports. (What it actually does is spin up a dummy webserver that doesn't need to think about the Nginx configuration.)

    This is just a little note of something that might confuse people, but the three commands above should suffice. If your site is still managed by Nginx, it should still be able to renew with simple certbot renew --nginx without a problem.

    ]]>
    Using UFW as a Firewall https://diyhosting.bhh.sh/ufw.html https://diyhosting.bhh.sh/ufw.html Thu, 01 Jul 2021 16:58:11 -0400

    Using UFW as a Firewall

    Uncomplicated Firewall (UFW) is a front-facing program for the more involved iptables firewall program installed in most GNU/Linux distributions. We can use ufw to restrict machines on the internet to only access the services (SSH, websites etc) you want them to, but it can also be used to prevent programs on the computer itself from accesing parts of the internet it shouldn't.

    How to Get It

    Log into your server by pulling up a terminal and typing:

    ssh root@example.org

    This command will attempt to log into your server and run a remote shell. If you leave the settings default, it should prompt you for your password, and you can just copy or type in the password from Vultr's site.

    Some VPS providers automatically install ufw, but if you do not have it installed already, install it in the typical way:

    apt install ufw

    First-Time Setup

    You can check the status of ufw right now by running:

    ufw status

    Without any changes, it should report back Status: inactive. Let's set it up so that only connections to SSH (standardized at port 22) are allowed in, and then enable the firewall:

    ufw default deny incoming # block all incoming connections by default
    ufw allow in ssh # or: ufw allow in 22
    ufw enable

    With the firewall enabled and allowing only SSH in, all other ports are prortected from incoming requests. To view all your rules, run:

    ufw status verbose

    A firewall that allows to connect to SSH and their website may look like:

    Status: active
    Logging: on (low)
    Default: deny (incoming), allow (outgoing), deny (routed)
    New profiles: skip
    To                           Action      From
    --                           ------      ----
    22 (SSH)                     ALLOW IN    Anywhere
    80,443/tcp (WWW Full)        ALLOW IN    Anywhere
    22 (SSH (v6))                ALLOW IN    Anywhere (v6)
    80,443/tcp (WWW Full (v6))   ALLOW IN    Anywhere (v6)

    If you want to delete e.g. the 'WWW Full' rule, run:

    ufw delete allow in 'WWW Full'
    ufw reload

    Enabling Common Services

    You have blocked all incoming ports but SSH, which means no outsiders would be able to access other services, like an email server or your website. You should look at the ports your services are open on and enable them individually. Here is a list of a few common services:

    Opening Port Numbers

    Suppose you install a Gemini server, which must broadcast on port 1965. By default ufw blocks all incoming connections on all ports, so whenever you install a new service like this you will have to tell ufw to enable the desired port:

    ufw allow 1985

    Websites: HTTP and HTTPS

    HTTP uses port 80 and HTTPS uses port 443. We can enable them like this:

    ufw allow 80
    ufw allow 443

    But ufw additionally knows the typical ports of common serives, so you can also run this:

    ufw allow http
    ufw allow https

    And that will do the same thing. There are also other abbreviations for common port lists:

    ufw allow in 'WWW Full'

    To see these other "apps" that ufw knows by default, run ufw app list

    Email: IMAP, POP3, and SMTP

    ufw allow in IMAPS
    ufw allow in POP3
    ufw allow in SMTP
    ufw allow in 'Postfix SMTPS'
    ufw allow in 'Mail Submission'

    Fine-Tuning Rules

    Instead of denying all ports by default, you may want to deny (ignores incoming requests) or reject (explicitly tells requests they're not allowed):

    ufw default allow in
    ufw deny in PORT
    ufw reject in PORT
    ufw reload

    You can add rules to comments to remember what they are there for:

    ufw allow in PORT comment 'Secret SSH'
    ufw reload
    ufw status verbose

    Output:

    To                         Action      From
    --                         ------      ----
    PORT                       ALLOW IN    Anywhere                   # Secret SSH
    PORT (v6)                  ALLOW IN    Anywhere (v6)              # Secret SSH

    To deny outgoing ports:

    ufw deny out PORT

    Ratelimiting is useful to protect against brute-force login attacks, like in SSH. Only IPv4 is supported for now. Enable it by running:

    ufw limit PORT/tcp

    To blocklist IP addresses:

    ufw deny from IP_ADDRESS

    To read more what you can do with ufw, run:

    man ufw

    Recovering SSH

    If you have accidentally firewalled yourself from logging on your computer, you can recover access by using your VPS's virtual console. On Vultr, this is on your VPS's menu. To the right of the server name, It is the leftmost icon that looks like a monitor.

    View Console

    Log in through there, and disable ufw by typing:

    ufw disable

    Further Reading

    Contributor - shunter.xyz
    ]]>
    Creating Your Own Chat Server With IRC https://diyhosting.bhh.sh/irc.html https://diyhosting.bhh.sh/irc.html Thu, 01 Jul 2021 16:28:32 -0400

    Creating Your Own Chat Server With IRC

    Creating your own chat server for you and your friends is easy, and you don't have to rely on a complicated system to get started. IRC is an old but gold protocol, and has clients for basically every operating system made since the 80s, with many powerful modern ones on Linux, Mac, and Windows.

    Having a chat server for you and your friends makes it impossible for a group of arbitrarily appointed moderators to deplatform you for wrong-think, and gives you greater freedom of communication.

    Installing an IRCd

    An IRCd is short for "IRC daemon", which just means an IRC server. The most easy IRCd to setup is Ergo.

    The first thing you need to do is create a new user for the server to be run by. This is good practice for installing software/servers manually, as it give you more fine-grained control over which permissions the application has.

    useradd -m ergo -s /bin/bash

    Next, we want to switch to our newly created ergo user and create the server directory.

    sudo -i -u ergo
    mkdir server

    You can find the latest release of Ergo on its GitHub latest release page.
    There are several platforms available, but you want to choose Linux, most likely linux-x86_64.
    Once you have selected the correct package, copy its URL and replace <release url> with the package URL (still as the ergo user):

    wget https://github.com/ergochat/ergo/releases/download/v2.7.0/ergo-2.7.0-linux-x86_64.tar.gz
    tar -xf ergo-2.7.0-linux-x86_64.tar.gz
    mv ergo-2.7.0-linux-x86_64/*
    rm -r ergo-2.7.0-linux-x86_64*

    Executing ls -l should now yield something like this:

    -rw-r--r-- 1 ergo ergo  118825 Jun  8 00:51 CHANGELOG.md
    -rw-r--r-- 1 ergo ergo    1983 May 31 01:48 README
    -rw-r--r-- 1 ergo ergo   41440 Jun  8 00:42 default.yaml
    drwxr-xr-x 2 ergo ergo    4096 Jul  1 09:01 docs
    -rwxr-xr-x 1 ergo ergo 9654272 Jun  8 00:53 ergo
    -rw-r--r-- 1 ergo ergo    1753 May 31 01:48 ergo.motd
    drwxr-xr-x 2 ergo ergo   12288 Jul  1 09:01 languages
    -rw-r--r-- 1 ergo ergo   39722 Jun  8 00:42 traditional.yaml

    If you see something similar to the above, that means Ergo is installed, although not quite ready to run yet.

    Configuring Ergo

    Now that Ergo is installed, you want to configure it to fit the needs of your group.
    The configuration in this section is tailored towards a small group of people, and less for a possibly large network, but it should work for any size of group.

    First thing, make sure you're still using the ergo user, and are in the ~/server directory.
    If you aren't, you can run the following to get back there:

    sudo -i -u ergo
    cd ~/server

    Next, generate certificate files for TLS:

    ./ergo mkcerts

    Ergo comes with a default configuration file with detailed documentation that can be used to guide you through the configuration process. This guide will help you setup the server for a typical use-case, but if you see any settings that you would like to change along the way, go ahead and change them, as long as you know what you're doing.

    To start configuring, we need to copy some files:

    cp default.yaml ircd.yaml
    cp ergo.motd ircd.motd

    The next steps involve editing the newly copied ircd.yaml file. If you do not know how to edit text files from the comment line, you can use nano, which is very simple, using arrow keys to navigate, CTRL+O to save, and CTRL+X to exit.
    Another option is vim, which is a much more powerful text editor, but has a learning curve. It is only recommended for this guide if you already know it.
    Lastly, you can copy the ircd.yaml file to a text editor on your computer and edit it with a GUI text editor of your choice. If that is what you choose to do, you may want to just download the file from Ergo's GitHub, edit it on your computer, clear the ircd.yaml file on the server, and then paste the contents from your computer into the blank file.
    No matter how you do it, the next steps assume you can edit the configuration file.

    Note:
    The options highlighted in this section are not a complete overview of all options. Instead, the options shown are the ones which are most relevant to a small network.
    You should read over the configuration file yourself if you are curious about everything you can change.

    Network and server names

    One of the first properties in the config file is network name. You can change this to whatever you like, as it will show up as the name when you connect to the server.

    # network configuration
    network:
        # name of the network
        name: "Land-Chat"

    Change the server name to your server's domain name.

    # server configuration
    server:
        # server name
        name: "example.org"

    Network password

    The next step is optional, depending on if you want your network password protected or not. The benefit of password protection is fairly obvious; nobody can connect to your network unless you gave them the password. If you're wanting to run a public network which anyone can join and create a channel, you want to skip this, but for personal setups, it is highly recommended.

    Generate a password to use by executing the following:

    ./ergo genpasswd

    It will ask you to enter a password and confirm it, then you will be given a hashed password.
    Copy this password, and paste it into the following field (also removing the # before the password: line):

    # password to login to the server, generated using `ergo genpasswd`:
    password: "<your hashed password>"

    Message of the day (MotD)

    Change the MotD (Message of the Day) file to the one you copied earlier:

    # motd filename
    # if you change the motd, you should move it to ircd.motd
    motd: ircd.motd

    Feel free to edit ircd.motd to your heart's content. Its contents will be sent to clients when they connect to the network.

    IP limits

    For security purposes, you might want to limit the amount of client connections per IP. For a private network, 4 is likely the maximum amount of connections you will have per IP, so that is a safe value.
    If your network is password protected, this is less of an issue, since the only people connecting will be people who have the password. The following is the default, but you can change it to be whichever value you like:

    # IP-based DoS protection
    ip-limits:
        # whether to limit the total number of concurrent connections per IP/CIDR
        count: true
        # maximum concurrent connections per IP/CIDR
        max-concurrent-connections: 16

    IP cloaking

    Traditionally, IRC networks expose users' IP addresses to everyone. This is not a good practice for privacy, however. With Ergo, IP cloaking is enable by default. You can enable or disable it if you like, and change how it looks to users.
    In this case, netname was changed to "chad".

    # IP cloaking hides users' IP addresses from other users and from channel admins
    # (but not from server admins), while still allowing channel admins to ban
    # offending IP addresses or networks. In place of hostnames derived from reverse
    # DNS, users see fake domain names like pwbs2ui4377257x8.irc. These names are
    # generated deterministically from the underlying IP address, but if the underlying
    # IP is not already known, it is infeasible to recover it from the cloaked name.
    # If you disable this, you should probably enable lookup-hostnames in its place.
    ip-cloaking:
        # whether to enable IP cloaking
        enabled: true
        # whether to use these cloak settings (specifically, `netname` and `num-bits`)
        # to produce unique hostnames for always-on clients. you can enable this even if
        # you disabled IP cloaking for normal clients above. if this is disabled,
        # always-on clients will all have an identical hostname (the server name).
        enabled-for-always-on: true
        # fake TLD at the end of the hostname, e.g., pwbs2ui4377257x8.irc
        # you may want to use your network name here
        netname: "chad"

    Password enforcement adjustments for HexChat (and possibly other clients)

    Ergo offers account registration to allow users to do things like use history and bouncer features, register channels, etc.
    In clients such as HexChat, server password may conflict with account passwords, so the following setting should be enable if you wish to use accounts with clients such as HexChat.
    Note that this could under some circumstances be considered a security hazard, as a user with an account does not need to know the server password to connect, although that user would have needed to register an account before the server had a password, and then a password would need to have been set after the fact, so this can be considered a very small concern if your setup always has had a password.
    Also keep in mind that this setting has no effect if your network does not even have a password at all.

    # some clients (notably Pidgin and Hexchat) offer only a single password field,
    # which makes it impossible to specify a separate server password (for the PASS
    # command) and SASL password. if this option is set to true, a client that
    # successfully authenticates with SASL will not be required to send
    # PASS as well, so it can be configured to authenticate with SASL only.
    skip-server-password: true

    Multiclient, always-on clients, history, etc

    Traditionally, IRC servers have no message history, and once you close your client, you cannot receive messages, and are not shown to be online at all. Ergo includes functionality to allow users to both receive history, and keep their clients "online" even after they have left. It also allows multiple clients to connect to the same account.
    If you are running a private network for friends, you should set always-on and auto-away to opt-out, to have all users with accounts to appear as if they are online at all times, and be able to receive messages when they are offline.
    For a public network, keep everything as their default values, since you probably do not want randoms having this by default.
    If for some reason you do not want any of these features at all, you can set enabled to false, but this is not recommended. Below are the recommended values for a private network (e.g. for friends) where users with accounts will be able to receive messages and history while they are offline.

    # multiclient controls whether Ergo allows multiple connections to
    # attach to the same client/nickname identity; this is part of the
    # functionality traditionally provided by a bouncer like ZNC
    multiclient:
        # when disabled, each connection must use a separate nickname (as is the
        # typical behavior of IRC servers). when enabled, a new connection that
        # has authenticated with SASL can associate itself with an existing
        # client
        enabled: true
        # if this is disabled, clients have to opt in to bouncer functionality
        # using nickserv or the cap system. if it's enabled, they can opt out
        # via nickserv
        allowed-by-default: true
        # whether to allow clients that remain on the server even
        # when they have no active connections. The possible values are:
        # "disabled", "opt-in", "opt-out", or "mandatory".
        always-on: "opt-out"
        # whether to mark always-on clients away when they have no active connections:
        auto-away: "opt-out"
        # QUIT always-on clients from the server if they go this long without connecting
        # (use 0 or omit for no expiration):
        #always-on-expiration: 90d

    VHosts

    IP cloaking was mentioned previously, and somewhat related to that, Ergo includes "vhost" functionality, which allows users to set a custom IP/host string. This is mostly for cosmetic value, and does not interfere with operators being able to see actual IP addresses for banning, but if you do not want it enable for some reason, you can disable it.

    # vhosts controls the assignment of vhosts (strings displayed in place of the user's
    # hostname/IP) by the HostServ service
    vhosts:
        # are vhosts enabled at all?
        enabled: true

    Channels

    Channels are where everyone on an IRC network talk. By default, anyone can create a channel, and anyone with an account can register one. The difference between a normal channel and a registered one is that the registered one will preserve the operator status of the person who created, whereas a normal channel's owner will lose operator status if they leave the channel or disconnect from the network.
    There are various settings for channels available, but the defaults are suitable for a private network with trust among users, or where you just want anyone to have the ability to create a channel. Below are the default values:

    # channel options
    channels:
        # modes that are set when new channels are created
        # +n is no-external-messages and +t is op-only-topic
        # see  /QUOTE HELP cmodes  for more channel modes
        default-modes: +nt
        # how many channels can a client be in at once?
        max-channels-per-client: 100
        # if this is true, new channels can only be created by operators with the
        # `chanreg` operator capability
        operator-only-creation: false
        # channel registration - requires an account
        registration:
            # can users register new channels?
            enabled: true
            # restrict new channel registrations to operators only?
            # (operators can then transfer channels to regular users using /CS TRANSFER)
            operator-only: false
            # how many channels can each account register?
            max-channels-per-account: 15

    Operators (administrators, etc)

    The IRC term for an administrator or another privileged user is "operator", or "oper" for short.
    Ergo's opers have different permissions that can be granted to them, and are defined in "classes", basically groups of permissions under a name. For example, "chat-moderator" and "server-admin" are defined in the default configuration:

    # operator classes
    oper-classes:
        # chat moderator: can ban/unban users from the server, join channels,
        # fix mode issues and sort out vhosts.
        "chat-moderator":
            # title shown in WHOIS
            title: Chat Moderator
            # capability names
            capabilities:
                - "kill"
                - "ban"
                - "nofakelag"
                - "roleplay"
                - "relaymsg"
                - "vhosts"
                - "sajoin"
                - "samode"
                - "snomasks"
        # server admin: has full control of the ircd, including nickname and
        # channel registrations
        "server-admin":
            # title shown in WHOIS
            title: Server Admin
            # oper class this extends from
            extends: "chat-moderator"
            # capability names
            capabilities:
                - "rehash"
                - "accreg"
                - "chanreg"
                - "history"
                - "defcon"
                - "massmessage"

    The above can be kept with their default values, but you are free to modify them or create any new classes that are appropriate for your setup.
    Next, let's actually create an operator account:

    # ircd operators
    opers:
        # default operator named 'gigachad'; log in with /OPER gigachad <password>
        "gigachad":
            # which capabilities this oper has access to
            class: "server-admin"
            # custom whois line
            whois-line: is the server administrator
            # custom hostname
            vhost: "gigachad"
            # normally, operator status is visible to unprivileged users in WHO and WHOIS
            # responses. this can be disabled with 'hidden'. ('hidden' also causes the
            # 'vhost' line above to be ignored.)
            hidden: false
            # modes are modes to auto-set upon opering-up. uncomment this to automatically
            # enable snomasks ("server notification masks" that alert you to server events;
            # see `/quote help snomasks` while opered-up for more information):
            #modes: +is acjknoqtuxv
            # operators can be authenticated either by password (with the /OPER command),
            # or by certificate fingerprint, or both. if a password hash is set, then a
            # password is required to oper up (e.g., /OPER dan mypassword). to generate
            # the hash, use `ergo genpasswd`.
            password: "<your oper password>"

    This is a modified version of the default oper entry. The account name is "gigachad", but you can change it to anything.
    Replace <your oper password> with a password generated by ./ergo genpasswd, and you will have a new oper account to use.
    Note that to log into an oper account, clients have to enter /OPER <oper name> <oper password> each time they log in. This can be automated by most clients by setting the command to be executed when the client logs in. In the case of HexChat, you can edit your network and add the command to the Connect commands tab of the menu.
    You can copy everything from "gigachad" to the end of the line, paste it again, and change the name to create another oper account. Another, less privileged example of an oper is shown as a comment below the above configuration snippet.

    Chat history

    Traditionally, IRC networks do not store, relay, or handle chat history in any way.
    On a privacy standpoint, this is a good thing, since chats are entirely ephemeral and handled by clients.
    On a practicality standpoint, this is a bad thing, since people have to keep a client connected 24/7 to see message history.
    For normalfriends, this can be a big problem, not only because having to stay online 24/7 is just annoying or infeasible, but also because they are likely used to chat platforms that handle history for them.
    With this in mind, enabling history is a good idea if you want to move friends over to IRC, and will make things a lot more pleasant for private networks.

    Ergo's history configuration group is very long, so it is encouraged to read over it yourself. This section will go over the most important pieces of that configuration group.

    History is not endless (unless you want it to be), and the amount that can be stored for channels is configurable:

    # how many channel-specific events (messages, joins, parts) should be tracked per channel?
    channel-length: 2048

    History is already enabled by default, but that just means it is being collected, not relayed by default. To relay history to clients when they connect, change the following to the amount of messages that you think is appropriate:

    # number of messages to automatically play back on channel join (0 to disable):
    autoreplay-on-join: 250

    History older than a certain time can be configured to be deleted or be inaccessible. The default cutoff time is 1 week, but this is configurable as well.

    
    # options to delete old messages, or prevent them from being retrieved
    restrictions:
        # if this is set, messages older than this cannot be retrieved by anyone
        # (and will eventually be deleted from persistent storage, if that's enabled)
        expire-time: 1w
    

    By default, Ergo only stores chat history in memory, so when the server restarts, all history is lost. If you wish to have chat history persist beyond restarts, you must store it in a MySQL database:

    # options to store history messages in a persistent database (currently only MySQL).
    # in order to enable any of this functionality, you must configure a MySQL server
    # in the `datastore.mysql` section.
    persistent:
        enabled: true
        # store unregistered channel messages in the persistent database?
        unregistered-channels: true

    # connection information for MySQL (currently only used for persistent history):
    mysql:
        enabled: false
        host: "localhost"
        port: 3306
        # if socket-path is set, it will be used instead of host:port
        #socket-path: "/var/run/mysqld/mysqld.sock"
        user: "ergo"
        password: "hunter2"
        history-database: "ergo_history"
        timeout: 3s
        max-conns: 4
        # this may be necessary to prevent middleware from closing your connections:
        #conn-max-lifetime: 180s

    For privacy reasons, you may want to allow users to delete their own messages in history, or export their messages to JSON:

    # options to control how messages are stored and deleted:
    retention:
        # allow users to delete their own messages from history?
        allow-individual-delete: true
        # if persistent history is enabled, create additional index tables,
        # allowing deletion of JSON export of an account's messages. this
        # may be needed for compliance with data privacy regulations.
        enable-account-indexing: true

    Spam reduction

    Most IRC networks have measures in place to reduce chat spam. By default, "fakelag" is enabled in Ergo, and that can deal with most aggregious chat spam.
    If you are running a private network where user trust is high, you can disable it so that there are no limits on the speed that messages can be sent.

    # fakelag: prevents clients from spamming commands too rapidly
    fakelag:
        # whether to enforce fakelag
        enabled: true
        # time unit for counting command rates
        window: 1s
        # clients can send this many commands without fakelag being imposed
        burst-limit: 5
        # once clients have exceeded their burst allowance, they can send only
        # this many commands per `window`:
        messages-per-window: 2
        # client status resets to the default state if they go this long without
          # sending any commands:
        cooldown: 2s

    Starting and using your server

    Now that Ergo is both installed and configured, you can actually start using it!

    Starting the server

    First thing, make sure you're still using the ergo user, and are in the ~/server directory.
    If you aren't, you can run the following to get back there:

    sudo -i -u ergo
    cd server

    Starting the server is done in one command:

    ./ergo run

    It will stay online until you close the terminal, or press CTRL+C. Don't worry, the next section goes over how to make it run like a normal server with a SystemD service.
    If you have not already, make sure the port 6697 is not blocked on your server. If you are using UFW as your firewall, you need to run ufw enable 6697 (not as the ergo user, of course).
    If you make and configuration changes while the server is running, you can apply them without restarting by typing /rehash as an operator.

    Connecting to the server

    To use IRC, you of course need an IRC client. There are many choices available, but the most widely used for Windows and Linux is HexChat. On Mac, you have a slightly nicer option with Textual, although you have to compile it from source if you want to use it for free.
    A more user-friendly and modern client choice is TheLounge, which is explained in the last section of this guide, if you want to look into it.

    Connecting with HexChat is very easy. When you start it, you will see something like this:

    HexChat network select

    From there, you should click + Add and name the server whatever you like (so you can find it on the server list).
    Once you have created a new server and named it, select it and click Edit.... A menu will show up like the one below. Change the domain to whatever domain your server is running on, and make sure to put in your server password if you set one.

    HexChat network edit menu

    Once you're done editing the network, click (X) Close, select your network from the network list, and click Connect.
    If all is well, you should be connected!

    HexChat connection complete

    The process is very similar on Textual.
    Create a new network and connect to it. Note that it will ask if you want to connect even though the certificate is unsigned. This is due to the self-signed certificates generated for the server, and is not a problem or security vulnerability, it is just a little annoying.

    Textual network edit menu

    Surviving restarts with a SystemD service

    In the beginning of the last section, Ergo was started by simply running ./ergo run, but this is only suitable for testing. To have a proper server setup, you need to run it as a service. This can be achieved via a SystemD service.

    Before creating your service file, make sure you are in ~/server as the ergo user.
    Once you have done that, create a file called start.sh with the following content:

    #!/bin/bash
    ./ergo run

    Save the file, then mark it as executable:

    chmod +x start.sh

    Now, create a file called ergo.service with the following content:

    [Unit]
    Description=Ergo IRC server
    After=network.target
    # If you are using MySQL for history storage, comment out the above line
    # and uncomment these two instead (you must independently install and configure
    # MySQL for your system):
    # Wants=mysql.service
    # After=network.target mysql.service
    [Service]
    Type=simple
    User=ergo
    WorkingDirectory=/home/ergo/server
    ExecStart=/home/ergo/server/start.sh
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    LimitNOFILE=1048576
    # Uncomment this for a hidden service:
    # PrivateNetwork=true
    [Install]
    WantedBy=multi-user.target

    You now have your service file, but it is not installed yet. To install it, switch to your normal user, and execute the following lines to install, enable, and start the SystemD service:

    ln -s /home/ergo/server/ergo.service /etc/systemd/system/ergo.service
    systemctl enable ergo
    systemctl start ergo

    Ergo is now installed and running as a service, and will automatically start when the system boots.

    Registering accounts and channels

    Account and channel registration were mentioned multiple times in this guide, and are indeed very important parts of the modern IRC ecosystem. You can connect to most IRC networks and talk without creating an account, but you will not be able to reserve your nickname or register channels, so it is important to register an account.

    Registering an account with NickServ

    First, make sure you are connected to your IRC network. Once you are, type /nickserv help to make sure NickServ (the registration system) is working propertly.
    If all is well, type the following, replacing <your password> with the password you want to use:

    /nickserv register <your password>

    At this point, you are now registered!
    The final step is to configure authentication with your client.

    In HexChat, all that needs to be done is changing Login method to SASL (username + password), and entering your NickServ password that you used earlier into the password field:

    HexChat SASL in network edit menu

    In Textual, open up your network in the menu, and click Identity under Server Properties. Enter your password in Personal Password, and check Wait for identification before joining channels.

    Textual identity menu

    You will now be logged into your account when you connect to your network.

    Registering channels with ChanServ

    Once you have an account registered, you can register channels with ChanServ.
    To do so, join the channel you want to register, then type the following, replacing <your channel> with the name of the channel you want to register:

    /chanserv register #<your channel>

    You are now the channel owner, and are free to appoint operators, administrators, etc for it. When you go offline, you won't lose ownership, and you cannot be removed as the owner unless you unregister the channel later.

    Moderation

    Like any chat, there will come a point where you need to use moderation tools to keep things under control. Many IRC setup guides do not go over moderation, so it can be stressful when operators need to actually use moderation tools.
    The main difference between IRC and other chat systems in terms of moderation is the difference between channel bans and network bans. Channel ban keeps a person out of channel a channel, whereas a network ban keeps a person out of the entire network.

    Understanding masks

    Bans are applied "masks", which are formatted pieces of text that contain a user's nick (username), their realname value, and their IP address or host.
    This is what a mask looks like: nick!~nick-dude@127.0.0.1.
    In bans, asterisks can be used as wildcards, which is useful for banning IP address ranges, patterns of nicknames, or whatever else you can think of.
    A ban on the nick person, for example, would look like this: person!*@*.
    A ban on anyone with the IP address 127.0.0.1 would look like this: *!*@127.0.0.1

    Discovering real IPs

    Even if IP cloaking is enabled on your network, you can still obtain real IP addresses/hosts if you are an operator. See the Operators part of the configuration section of this guide on how to become an operator.
    To find out a user's real IP, simply type /whois along with the user's nick, and you will see information about the user, along with their real IP address/host.
    /whois is not a command that is exclusive to operators, but it does not reveal as much information to non-operators.

    Banning someone from the network

    Any netword-wide moderation action requires being an operator. See the Operators part of the configuration section of this guide on how to become an operator.
    Banning someone from the network is achieved with the /kline command. To see more info on the command, type /helpop kline.

    To ban a nick from the network:

    /kline andkill <nick>!*@*

    To ban an IP address or host from the network:

    /kline andkill *!*@<IP or mask>

    To unban a mask, you can use the /unkline command with the mask you want to unban.

    Banning someone from a channel

    Channel owners, administrators, and operators can ban people from channels. This is not the same as banning someone from the network, since it only has an effect on one channel. Additionally, a channel operator is not the same as a network operator.

    To ban someone in a channel, type the following in that channel, replacing <mask> with the user's mask:

    /mode +b <mask>

    Note that this will only ban the user, not kick them immediately. You will want to run /kick along with the user's nick to also kick them.
    To unban a user, run the command above, but replace the + with a -.
    You can see who is banned in a channel by typing /banlist.

    Muting people in a channel

    By default, anyone can speak in an IRC channel. To change this, you must be a channel owner, administrator, or operator.
    Channels, along with users, have modes, which modify their behavior. There is a special mode for channels called m (moderated) which requires users to be privileged in some way to talk.
    To set a channel as moderated, type the following in the channel:

    /mode +m

    Now, users must be an owner, administrator, operator, or be voiced to talk in the channel This be reversed by typing the command above, but changing the + to a -.
    To voice a user, run the following, replacing <nick> with the user's nick:

    /mode +v <nick>

    Unvoice the user by typing the above command, but replacing the + with a -.

    Appointing channel administrators and operators

    Assuming you a channel owner, you can appoint both administrators and operators. If you are only an operator, you may only appoint operators.
    The difference between administrator and operator is mainly that administrators cannot have their privileges taken away by operators, only owners. To appoint an administrator, type the following, replacing <nick> with the user's nick:

    /mode +a <nick>

    To appoint an operator, type the following, replacing <nick> with the user's nick:

    /mode +o <nick>

    You can also use /op and /deop on most clients to appoint and remove an operator.
    To remove administrator or operator status, run either of the above commands, but replace the + with a -.

    Bringing modern-day features to IRC with TheLounge

    A large downside to IRC as a protocol is just how old it is, and the limitations that exist because of it. Other old protocols such as HTTP were built to be content-agnostic and versitile, but IRC was built with a very specific set of features, so it has not held up so well to contemporary chat systems.
    A notable thing that IRC as a protocol is missing is file uploads, and other fancy features that many other chats have.
    With that said, these problems can be fixed by clients, although many clients are still very primitive.

    TheLounge is a modern self-hosted IRC web client that tries to make IRC as user-friendly as possible. It can be the answer to many of the complaints that normalfriends may have about IRC. It runs on anything with a web browser, can be "installed" since it is a PWA (Progressive Web App), and is optimized for both desktops and mobile devices. It keeps you logged in even when you are gone, and even supports file uploads and embeds.
    Effectively, it brings IRC up to the standard of most other chat systems.

    If you would like to setup an instance of TheLounge for you and your friends, you can take a look at their installation guide.
    It is a self-hosted web app, so you can run it for multiple people, not just yourself.


    Written by Termer

    ]]>
    Setting up Gitea https://diyhosting.bhh.sh/gitea.html https://diyhosting.bhh.sh/gitea.html Thu, 01 Jul 2021 16:14:22 -0400

    Setting up Gitea

    Gitea allows you to self-host your git repositories similar to bare repositories, but comes with additional features that you might know from GitHub, such as issues, pull requests or multiple users. Its advantage over GitLab—another Free Software GitHub clone—is that it is much more lightweight and easier to setup.

    Head over to gitea.com to see what it looks like in practice.

    Although Gitea is lighter than Gitlab, if you have a VPS with only 512MB of RAM, you will probably have to upgrade. Gitea is more memory-intensive than having just a bare git repository.

    Installing Gitea

    First install a few dependencies:

    apt install curl sqlite3

    Unfortunately, Gitea itself is not in the official Debian repos, so we will add a third-party repository for it.

    Add the repo's gpg key to apt's trusted keys:

    curl -sL -o /etc/apt/trusted.gpg.d/morph027-gitea.asc https://packaging.gitlab.io/gitea/gpg.key

    Then add the actual repository to apt:

    echo "deb [arch=amd64] https://packaging.gitlab.io/gitea gitea main" > /etc/apt/sources.list.d/morph027-gitea.list

    Now we can install Gitea:

    apt update
    apt install gitea

    Since apt automatically enables and starts the Gitea service, it should already be running on port 3000 on your server!

    Setting up a Nginx reverse proxy

    You should know how to generate SSL certificates and use Nginx by now. Add this to your Nginx config to proxy requests made to your git subdomain to Gitea running on port 3000:

    
    server {
    	listen 443 ssl;
    	listen [::]:443 ssl;
            ssl_certificate /etc/ssl/nginx/git.example.org.crt;
            ssl_certificate_key /etc/ssl/nginx/git.example.org.key;
            server_name git.example.org;
    	location / {
    		proxy_pass http://localhost:3000/; # The / is important!
    		proxy_redirect off;
    		proxy_set_header Host $host;
    		proxy_set_header X-Real-IP $remote_addr;
    		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    		proxy_set_header X-Forwarded-Proto $scheme;
    	}
    }
            

    And reload Nginx:

    systemctl reload nginx

    Setting up Gitea

    If everything worked fine you should now see a setup screen when you go to your configured domain in the browser. The options should be pretty self-explanatory, it is only important to select SQLite3 and to replace the base url and SSH server domain with your own.

    Database Type:
    SQLite3
    SSH Server Domain:
    git.example.org
    Gitea Base URL:
    git.example.org

    These and other settings can be changed in a configuration file later so don't worry about making wrong decisions right now.

    After clicking the install button you should now be able to log into your Gitea instance with the account you just created! Explore the settings for more things to do, such as setting up your SSH keys.

    If Gitea does not load fully and has random errors, it is possible that you need to increase your available memory on your VPS. This can usually be done on your VPS-provider's website without too much trouble.

    A few extras

    Automatically create a new repo on push

    This is an incredicly useful feature for me. Open up /etc/gitea/app.ini and add DEFAULT_PUSH_CREATE_PRIVATE = true to the repository section like so:


    If you now add a remote to a repository like this

    git remote add origin 'ssh://gitea@git.example.org/username/coolproject.git'

    and push, Gitea will automatically create a private coolproject repository in your account!

    Change tab-width

    By default Gitea displays tabs 8 spaces wide, however I prefer 4 spaces. We can change this!

    mkdir -p /var/lib/gitea/custom/templates/custom/

    And write this into /var/lib/gitea/custom/templates/custom/header.tmpl:

    <style>
    .tab-size-8 {
    	tab-size: 4 !important;
    	-moz-tab-size: 4 !important;
    }
    </style>

    Contribution

    ]]>
    Hosting Your Own Git Repositories https://diyhosting.bhh.sh/git.html https://diyhosting.bhh.sh/git.html Thu, 01 Jul 2021 07:19:51 -0400

    Hosting Your Own Git Repositories

    Once you have your own VPS or other Internet-available server, you can start hosting your own git repositories. The goal of this tutorial is for you to go from

    git clone github.com/...

    to

    git clone YourLandChadDomainName.xyz/...

    so you can cultivate your own homegrown, grass-fed code, rather than relying on a centralized proprietary service like GitHub.

    Installing git

    You most likely already have it installed on your server, but if not, run:

    apt install git

    We don't need any additional software, git itself ships with everything needed to host a remote repository!

    Creating bare repositories

    For each repository you want to host, you will need to manually create what's called a "bare" repository on your server. These hold all the commits and any other git data needed for your repository, but without an expanded "index" in which you can just browse all the files of a certain commit in the file system.

    These repositories need to be owned by the git user, and you should probably pick a directory where you will store them all. One sane choice is under /srv/git/, and we will use this as the example directory for the rest of the tutorial, but any other path will do as well.

    Become the git user and create the directory

    If you're logged in to your server as root and have git installed, you can become the git user by executing

    su git

    Now navigate to/create your desired directory, for example

    cd /srv
    mkdir git

    Create the repo

    Now you can create the bare repository with

    git init --bare my-repo.git

    By convention, bare repository names end with ".git".

    Repeat the above command for any other repositories you want to host.

    Syncing local repositories with your server

    Set up SSH login for the git user

    You will need to be able to login remotely via ssh as the git user we've used before. To do this, you will either need to set up a password for the git user by running passwd git, or copy your public SSH key from your local machine to /home/git/.ssh/authorized_keys. See the SSH keys instructional for details (just log in as git instead of root).

    Syncing a new repository with your server

    If you've just created a new repository on your local machine, you will need to tell git where the remote repository is to be able to sync with it (using commands like git push or git pull). We do this by defining a "remote" for your repository.

    A remote is just a named URL remembered in your repo's configuration. So we need a name and a URL. By convention, the "main" remote is called "origin". The URL has the format user@host:path, where:

    • user is git, the git user we've already worked with before.
    • host is your domain name. Alternatively you could even use your server's raw IP address.
    • path is the absolute path to the repository on the server, in our example /srv/git/my-repo.git

    So, to create a new remote, run:

    git remote add origin git@yourdomain.xyz:/srv/git/my-repo.git

    Now you'll be able to run git push origin master to push your commits or git pull origin to pull from the remote.

    Syncing an existing repository

    If you've already set up your local repository to sync with a service like GitHub it probably already has a remote called "origin". You can see your repo's remotes with:

    git remote -v

    You can follow the above instructions, substituting an arbitrary other name other than "origin" to create a differently named remote, e.g.

    git remote add vps git@...

    Now you'll be able to push/pull with git push vps master and git pull vps, respectively.

    Or, to completely sever ties with your centralized git provider, first remove the original origin with: git remote remove origin and then follow the instructions as above.

    Contribution

    ]]>
    Requiring Passwords for Webpages (HTTP Authentication) https://diyhosting.bhh.sh/auth.html https://diyhosting.bhh.sh/auth.html Thu, 01 Jul 2021 07:19:27 -0400

    Requiring Passwords for Webpages

    access control with nginx

    HTTP basic authentication will allow you to secure parts (or all) of your website with a username and password without the trouble of PHP or Javascript. This will work with any Nginx server.

    Installation

    We will be using the command htpasswd to make username and password pairs.

    apt install apache2-utils

    Now think of a username and password and remember them.

    htpasswd -c /etc/nginx/myusers username

    Type out your password twice to confirm. You can do this as many times as you'd like.

    Check out user name password pairs (the password will be securely hashed):

    cat /etc/nginx/myusers

    Nginx Config and Auth Basic

    From here, we are going to edit our websites config file in /etc/nginx/sites-enabled. Have in mind which folder you'd like to secure. Add something like this:

    server {
        #...
        location /secret-folder  {
            auth_basic "What's the Password?" ;
            auth_basic_user_file /etc/nginx/myusers ;
        }
        #...
    }

    If you'd like to do the opposite, such as making the entire site private except for a public section, do this:

    server {
        #...
        auth_basic "What's the Password?" ;
        auth_basic_user_file /etc/nginx/myusers ;
        location /public/ {
            #...
            auth_basic off ;
        }
        #...
    }

    IP Addresses

    If passwords aren't enough we can ban an ip or accept one.

    location /api {
        #...
        allow 192.168.1.23:8080 ;
        deny 127.0.0.1 ;
    }

    If you want to check both a username and password with an ip address, use the satisfy directive.

    location /api {
        #...
        satify all ;
        allow 192.168.1.23:8080 ;
        deny 127.0.0.1 ;
        auth_basic "What's the Password?" ;
        auth_basic_user_file /etc/nginx/myusers ;
    }

    Complete Example

    http {
        server {
            listen 80;
            root /var/www/website ;
            #...
            location /secret-folder {
                satisfy all ;
                allow 192.168.1.3/24;
                deny 127.0.0.1 ;
                auth_basic "What's the Password?" ;
                auth_basic_user_file /etc/nginx/myusers ;
            }
        }
    }

    Now check your configuration with nginx -t

    Reload nginx and you're good to go!

    Contributor - tomfasano.xyz
    ]]>
    Cronjobs https://diyhosting.bhh.sh/cron.html https://diyhosting.bhh.sh/cron.html Thu, 01 Jul 2021 07:19:04 -0400

    Using Cronjobs to run scheduled tasks

    Cron is a service that lets you run scheduled tasks. These tasks are called cronjobs. If you have already followed the initial course you will have already used cron when you set up certbot.

    What tasks would I want to schedule?

    You can schedule anything! Some examples of what you might have done already include:

    • updatedb to update your locate database
    • certbot to update renewing of your https certs
    Some tasks that you might want to schedule may include:
    • Package updates - if you really just want to leave your server alone you can automated updating packages on your server
    • Backups - you may want to backup certain files every day and some every week, this is possible with cron

    And many more, anything you can do can be turned into a cronjob.

    Basic Cronjobs

    This the preferred method for personal tasks and scripts, it's also the easiest to get started with. Run the command crontab -e to access your users crontab

    Once you have figured out the command you want to run you need to figure out how often you want to run it and when. I am going to schedule my system updates once a week on at 3:30 AM on a Monday.

    We now have to convert this time (Every Monday at 3:30 AM) into a cron time. Cron uses a simple but effective way of scheduling when to run things.

    Crontab expressions look like this * * * * * command-to-run The five elements before the command tell when the command is supposed to be run automatically.

    So for our Monday at 3:30AM job we would do the following:

     .---------------- minute (0 - 59)
     | .------------- hour (0 - 23)
     | | .---------- day of month (1 - 31)
     | | | .------- month (1 - 12
     | | | | .---- day of week (0 - 6)
     | | | | |
     * * * * *
    30 3 * * 1 apt -y update && apt -y upgrade

    Some notes

    • On the day of the week option, Sunday is 0 and counting up from there, Saturday will be 6.
    • * designates "everything". Our command above has a * in the day of month and month columns. This means it will run regardless of the day of the month or month.
    • The hour option uses 24 hour time. 3 = 3AM, while use 15 for 3PM.

    More examples

    Let's add another job, our backup job (for the purposes of this our backup command is just called backup) We want to run backup Every evening at 11PM, once we work out the timings for this we can add the to the same file as the above by running crontab -e This would mean our full crontab would look like this:

    0 23 * * * backup

    Consecutive times

    Suppose we want a command to run every weekday. We know we can put 1 (Monday), but we can also use 1-5 to signify from day 1 (Monday) to day 5 (Friday).

    0 6 * * 1-5 echo "Wakey, wakey, wagie!" >> /home/wagie/alarm

    The above echo command runs every Monday through Friday at 6:00AM.

    Non-consecutive times

    We can also randomly specify non-consecutive arguments with a comma. Suppose you have a script you want to run at the midday of the 1st, 15th, and 20th day of every month. You can specify that my putting 1,15,20 for the day of the month argument:

    0 12 1,15,20 * * /usr/bin/pay_bills_script

    "Every X minutes/days/months"

    We can also easily run a command very several minutes or months, without specifying the specific times:

    */15 * * * * updatedb

    This cronjob will run the updatedb command every 15 minutes.

    Beware of this Rookie Mistake Though...

    Suppose you want to run a script once every other month. You might be tempted write this:

    * * * */2 *

    That might feel right, but this script will be running once every minute during that every other month. You should specify the first two arguments, because with * it will be running every minute and hour!

    0 0 1 */2 *

    This makes the command run only at 0:00 (12:00AM) on the first day of every two months, which is what we really want.

    Consult the website crontab.guru for an intuitive and interactive tester of cronjobs.

    User vs. Root Cronjobs

    It is important to note that user accounts all have different cronjobs. If you have a user account chad and edit his crontab with crontab -e, the commands you add will be run as the chad user, not root or anyone else.

    Bear in mind that if you need root access to run a particular command, you will usually want to add it as root.

    System-wide cron directories

    crontab -e is the typical interface for adding cronjobs, but it's important to at least know that system-wide jobs are often stored in the file directory. Some programs which need cronjobs will automatically install them in the following way.

    Run the command ls /etc/cron* you should see a list of directories and there contents. The directories should be something like the below

    • /etc/cron.d This is a crontab like the ones that you create with crontab -e
    • /etc/cron.hourly
    • /etc/cron.daily
    • /etc/cron.weekly
    • /etc/cron.monthly

    The directories cron.{hourly,daily,weekly,monthly} are where you can put scripts to run at those times. You don't put normal cron entries here. I prefer to use these directories for system wide jobs that don't relate to an individual user.

    Contribution

    ]]>
    Mirror your site over tor https://diyhosting.bhh.sh/tor.html https://diyhosting.bhh.sh/tor.html Thu, 01 Jul 2021 07:15:39 -0400

    Mirror Your Site Over Tor

    Tor logo

    Now that you have a website, why not offer it on a private alternative such as the onion network?

    Setting up Tor

    Installing Tor

    Firstly we need to add the tor repo's to have the latest up to date version or tor.

    apt install -y apt-transport-https gpg
    echo "deb https://deb.torproject.org/torproject.org buster main
    deb-src https://deb.torproject.org/torproject.org buster main" > /etc/apt/sources.list.d/tor.list

    Then we need to add the gpg keys to our keyring

    curl -s https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import
    gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | apt-key add -

    Now update and install tor

    apt update
    apt install tor deb.torproject.org-keyring

    Enabling Tor

    Then edit the file /etc/tor/torrc, uncommenting the following lines:

    HiddenServiceDir /var/lib/tor/hidden_service/
    HiddenServicePort 80 127.0.0.1:80

    Now start and enable tor at boot

     systemctl enable --now tor 

    If the next command outputs active in green you're golden!

     systemctl status tor

    Now you're server is on the dark web. The following command will give you your onion address:

     cat /var/lib/tor/hidden_service/hostname

    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 up until the server block of code. Instead, paste this:

            server {
                listen 127.0.0.1:80 ;
                root /var/www/landchad ;
                index index.html ;
                server_name your-onion-address.onion ;
            }

    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.

    Update regularly!

    Make sure to update Tor on a regular basis by running:

    apt update
    apt install tor

    Contributor - tomfasano.xyz

    ]]>
    Cryptocurrency Tutorials Completed https://diyhosting.bhh.sh/index.html#crypto https://diyhosting.bhh.sh/index.html#crypto Tue, 29 Jun 2021 08:10:31 -0400 There is now a set of basic tutorials on cryptocurrency wallets and concepts up. The goal here is to allow people to receive tips for sites using all free and open source and peer-to-peer technology.

    More tutorials on crypto management and exchanging may be added later, but these focus simply on basic concepts and setting up wallets. They include:

    ]]>
    Welcome to diyhosting.bhh.sh! https://diyhosting.bhh.sh https://diyhosting.bhh.sh Mon, 28 Jun 2021 08:21:44 -0400 Welcome to diyhosting.bhh.sh!

    This website is for step-by-step tutorials that allow people to host and maintain their own website and other web services on the cheap or free.

    There is already a full basic tutorial on website creation on the site here. Following the tutorials can take as little as an hour, but will help you set up a VPS, and NginX server and encrypt your new webpage with Certbot.

    Next I plan adding general info on HTML and CSS and how to manage a website.

    More stuff like running your own email server and more will be added shortly as more articles are finalized.

    ]]>