Static IP address in Linux (Debian)

You can give your Debian installation a static IP address by following these steps:

1. Determine your network interface name: Use the following command to determine the name of your network interface:

ip addr

This will display information about all of your network interfaces. Look for the interface that you want to configure with a fixed IP address. The interface name will be listed on the left-hand side of the output (e.g. eth0, enp0s3, etc.)

2. Edit the network configuration file: Use a text editor to edit the /etc/network/interfaces file. For example, you can use the nano editor by running the following command:

sudo nano /etc/network/interfaces

3. Configure the network interface: Add the following lines to the file, replacing the interface name and IP address with your own values:

auto <interface-name>
iface <interface-name> inet static
address <ip-address>
netmask <subnet-mask>
gateway <default-gateway>
dns-nameservers <dns-server-ip-address>

For example, if your network interface name is “eth0” and you want to set the IP address to “192.168.0.10”, the subnet mask to “255.255.255.0”, the default gateway to “192.168.0.1”, and the DNS server to “8.8.8.8”, the configuration would look like this:

auto eth0
iface eth0 inet static
address 192.168.0.10
netmask 255.255.255.0
gateway 192.168.0.1
dns-nameservers 8.8.8.8

4. Save and close the file: Press Ctrl+O to save the file, and then press Ctrl+X to close the editor.

5. Restart the networking service: Use the following command to restart the networking service and apply the changes:

sudo systemctl restart networking

After you’ve completed these steps, your Debian installation should have a fixed IP address. You can verify the configuration by using the “ip addr” command again and looking for the interface that you configured.

More info here: https://wiki.debian.org/NetworkConfiguration
Thanks to https://fosstodon.org/@HankB for the tips and better choice of words!

Loading

[MASTODON 4.2.10] How to update Mastodon to a new version

Updated on 26-08-2024. For the old version, click here.

Contents:
1. UPDATE
2. RUBY VERSION ISSUES
3. RUBY GEM ISSUES
4. CHARLOC_HOLMES GEM ISSUES

So a new release came out and it is important to get this update as soon as possible! This manual is a transcript of the way that I have updated my Mastodon instance. Please make sure you make proper backups and use your brain while updating things.

A guide to making a Mastodon backup can be found here.

Linux flavour: Debian
Update from: 4.2.xx

  1. Log into your server
  2. su - mastodon
  3. cd /home/mastodon/live
  4. git fetch --tags
  5. git checkout [type the most recent version here, starting with the letter v. For example; v4.2.5
    git checkout v4.2.10
  6. If you get a ruby version error, please see bottom of this article for a fix! bundle install
  7. yarn install
  8. RAILS_ENV=production bundle exec rails db:migrate
    
    #NOTE: You might get a ruby error which then suggests you to enter the command "bundle install". Do that and then run the RAILS command again.
  9. RAILS_ENV=production bundle exec rails assets:precompile
  10. exit

OPTIONAL:
After updating, you might get a notification to update the browserlist database. You can do that with the following command:

npx update-browserslist-db@latest

Okay, you can now choose to either reboot or restart the services.

REBOOT:

  1. This command may vary, depending on your Linux flavour.
    systemctl reboot

RESTART:

  1. This command may vary, depending on your Linux flavour.
    systemctl restart mastodon-sidekiq
    systemctl reload mastodon-web
    
    

    Optional:

    systemctl restart mastodon-streaming

RUBY VERSION ISSUES

My system was unable to find the required v3.2.3 of Ruby and I have fixed this by doing the following steps:

  1. Please make sure that your path is correct.
    git -C ~/.rbenv/plugins/ruby-build pull
  2. rbenv install 3.2.3
    
    

    *WAIT TILL DONE* (it may take a little while)

  3. To check all the installed versions type:
    rbenv versions
  4. To set v3.2.3 as the global version, type:
    rbenv global 3.2.3
  5. To double-check the active, installed version, type:
    rbenv versions
  6. Done!

This manual is a transcript of the way that I have updated my Mastodon instance. Please make sure you make proper backups and use your brain while updating things.

Sources: https://richstone.io/where-is-ruby-3-0-0-on-rbenv/

RUBY GEM ISSUES

After entering…

RAILS_ENV=production bundle exec rails db:migrate

…you might get a ruby gem error like:

Could not find rexml-3.3.5, strscan-3.1.0 in locally installed gems
Run `bundle install` to install missing gems.

Enter the command “bundle install” and after that run the RAILS command again.

CHARLOCK_HOLMES ISSUES

The charlock_holmes gem may fail to build on some systems with recent versions of gcc. If you run into such an issue, try

BUNDLE_BUILD__CHARLOCK_HOLMES="--with-cxxflags=-std=c++17" bundle install.

Loading

Update in the script to block bots, spiders and indexers

Original post: https://3xn.nl/projects/2023/09/20/crude-solution-to-ban-bots-by-their-user-agent/

I’ve very much simplified the script that instantly redirects unwanted traffic away from the server. Currently, I am using a very cheap VPS to receive all that traffic.

Here ya go:

<?php

// CC-BY-NC (2023)

// Author: FoxSan - fox@cytag.nl

// This is a functional but dirty hack to block bots, spiders and indexers by looking at the HTTP USER AGENT.
// Traffic that meets the conditions is being yeeted away to any place of your choice.

//////////////////////////////////////////////////////////////
// Emergency bypass
// goto end;
//////////////////////////////////////////////////////////////

// attempt to basically just yeet all bots to another website

$targetURL = "https://DOMAIN.TLD/SUB/";

// Function to check if the user agent appears to be a bot or spider

function isBot()

{

    $user_agent = $_SERVER['HTTP_USER_AGENT'];

$bot_keywords = ['bytespider', 'amazonbot', 'MJ12bot', 'YandexBot', 'SemrushBot', 'dotbot', 'AspiegelBot', 'DataForSeoBot', 'DotBot', 'Pinterestbot', 'PetalBot', 'HeadlessChrome', 'GPTBot', 'Sogou', 'ALittle Client', 'fidget-spinner-bot', 'intelx.io_bot', 'Mediatoolkitbot', 'BLEXBot', 'AhrefsBot'];

    foreach ($bot_keywords as $keyword) {

        if (stripos($user_agent, $keyword) !== false) {

            return true;

        }
    }

    return false;

}

// Check if the visitor is a bot or spider

if (isBot()) {

// yeet

header("Location: $targetURL");

    // Exit to prevent further processing

    exit;

}

end:

// If the visitor is not a bot, spider, or crawler, continue with your website code.

//////////////////////////////////////////////////////////////////////

?>

Loading

More tweaks for the .htaccess file!

Here’s a list of stuff that I have in my .htaccess files on various websites.

I want to work on my website, but any other visitor should be booted to another website so I can work in peace. Sidenote: It's forever since I last used this, so it might work. Or not.

---

# YOUR IP address goes here:
RewriteCond %{REMOTE_ADDR} !^000\.000\.000\.000$
# And provides you access to:
RewriteCond %{REQUEST_URI} !^https://DOMAIN.TLD$ [NC]
# Fine, go have all the media as well
RewriteCond %{REQUEST_URI} !\.(jpg|jpeg|png|gif|svg|swf|css|ico|js)$ [NC]
# Any other visitor can go visit the following website:
RewriteRule .* https://DOMAIN.TLD/ [R=302,L]

# Hey, no viewing access to this file
<FilesMatch "^.ht">
Order deny,allow
Deny from all
</FilesMatch>

# Disable Server Signature
ServerSignature Off

# SSL all the things!
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

# No WWW
RewriteCond %{HTTP_HOST} ^www\.DOMAIN\.TLD$
RewriteRule ^/?$ "https\:\/\/DOMAIN\.TLD\/" [R=301,L]

# Do we like Symlinks? Yeah we do.
Options +FollowSymlinks

# No open directories or directory listings. What is this... 1998?
Options All -Indexes
IndexIgnore *

# Rewrite rules to block out some common exploits.
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule .* index.php [F]

# PHP doohickies
php_flag register_globals off 
php_flag safe_mode off 
php_flag allow_url_fopen off 
php_flag display_errors off 
php_value session.save_path '/tmp' 
php_value disable_functions "exec,passthru,shell_exec,system,curl_multi_exec,show_source,eval"

# File Injection Protection, or a code-condom. What.
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC]
RewriteRule .* - [F]

# /proc/self/environ? Go away!
RewriteCond %{QUERY_STRING} proc/self/environ [NC,OR]

# Disallow Access To Sensitive Files. Enter your own file names.
RewriteRule ^(htaccess.txt|configuration.php(-dist)?|joomla.xml|README.txt|web.config.txt|CONTRIBUTING.md|phpunit.xml.dist|plugin_googlemap2_proxy.php)$ - [F]

# Don't allow any pages to be framed - Defends against CSRF
<IfModule mod_headers.c>
Header set X-Frame-Options SAMEORIGIN
</IfModule>

# Disallow Php Easter Eggs
RewriteCond %{QUERY_STRING} \=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12} [NC]
RewriteRule .* index.php [F]

# Libwww-perl Access Block
RewriteCond %{HTTP_USER_AGENT} libwww-perl.* 
RewriteRule .* ? [F,L]

# Uh. I forgot.
<IfModule mod_autoindex.c>
IndexIgnore *
</IfModule>

# NO SNIFFYWIFFY OwO
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
</IfModule>

# NEEDS TESTING
# Turn on IE8-IE9 XSS prevention tools
#Header set X-XSS-Protection "1; mode=block"

# NEEDS TESTING TOO
# Only allow JavaScript from the same domain to be run.
# Don't allow inline JavaScript to run.
#Header set X-Content-Security-Policy "allow 'self';"

# Example if you don't like Russia and Turkey (Optional A1 is to block anonymous proxies)
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^(RU|TR)$
RewriteRule .* https://DOMAIN.TLD/directorywithindexdothtml/ [R=302,L]

# Caching stuff
<FilesMatch "\.(ico|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "public, max-age=3600"
</FilesMatch>

# Compress text, html, javascript, css, xml!
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/xml text/css text/plain
AddOutputFilterByType DEFLATE image/svg+xml application/xhtml+xml application/xml
AddOutputFilterByType DEFLATE application/rdf+xml application/rss+xml application/atom+xml
AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript application/json
AddOutputFilterByType DEFLATE application/x-font-ttf application/x-font-otf
AddOutputFilterByType DEFLATE font/truetype font/opentype
</IfModule>

# Joomla! core SEF Section.
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

# PHP TWEAKS 
php_value upload_max_filesize 200M
php_value post_max_size 200M
php_value max_input_vars 2000
php_value max_execution_time 120
php_value memory_limit 1024M

## BEGIN EXPIRES CACHING 
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType text/cache-manifest "access plus 0 seconds"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/rss+xml "access plus 1 hour"
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType image/x-icon "access plus 1 week"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
ExpiresByType text/x-component "access plus 1 month"
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType application/x-font-woff "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
<IfModule mod_headers.c>
Header append Cache-Control "public"
</IfModule>
</IfModule>
## END EXPIRES CACHING

Loading

Increasing the character limit on Mastodon 4.1.x and 4.2.x

There is a very small difference between the two Git branches, so pay attention.

su - mastodon

Edit if your Mastodon instance is v4.1.x

nano live/app/javascript/mastodon/features/compose/components/compose_form.js

Edit if your Mastodon instance is v4.2.x

nano live/app/javascript/mastodon/features/compose/components/compose_form.jsx

In this file, you will find the number “500” twice. Replace that number with your desired character limit and save the file.

nano live/app/validators/status_length_validator.rb

In this file, you will find the number “500” once. Replace that number with your desired character limit and save the file.

nano live/app/serializers/rest/instance_serializer.rb

FIND the line that reads:

:languages, :registrations,

ADD the following to that line:

:max_toot_chars

Pay attention if a comma is used at the end or not.

Scroll down to the end of the file until you reach the “private” section.

ADD

def max_toot_chars 
[the number of your desired character limit without the brackets]
end

EXAMPLE

def max_toot_chars 
5000
end

Go back to the live directory and enter the following commands, one by one:

RAILS_ENV=production bundle exec rails assets:precompile
exit
systemctl restart mastodon-sidekiq
systemctl reload mastodon-web
[OPTIONAL] systemctl restart mastodon-streaming

Done.

Loading

CloudPanel website causing “Too many redirects”

I have installed CloudPanel and the new website caused a “Too many redirects” bug. This is because my SSL certificates are controlled by a proxy and this can cause some confusion between the systems. Also, because CloudPanel installs its own certificates.

This application can also install a Let’s Encrypt certificate, but this works only in more conventional systems. Mine is going through a DNS to a Proxy that listens to a certain IP address and that proxy redirects the request to a Virtual Machine on one of my servers.

So, here is my, probably unconventional method of disabling the SSL certificates on my CloudPanel installation:

  1. Open the CloudPanel controlpanel.
  2. Select the website you want to edit
  3. Choose the Vhost tab
  4. Change the following code into the new code:
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
{{ssl_certificate_key}}
{{ssl_certificate}}
server_name subdomain.3xn.nl;
{{root}}

{{nginx_access_log}}
{{nginx_error_log}}

if ($scheme != "https") {
rewrite ^ https://$host$uri permanent;
}
server {
listen 80;
listen [::]:80;
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# {{ssl_certificate_key}}
# {{ssl_certificate}}
server_name subdomain.3xn.nl;
{{root}}

{{nginx_access_log}}
{{nginx_error_log}}

# if ($scheme != "https") {
# rewrite ^ https://$host$uri permanent;
# }

Done! Your website should now say “Hello world :-)”

You can see that I have disabled the listen to port 443, the certificate keys, the forced https and the path to the keys. I chose to switch off the forced HTTP, because my proxy is already taking care of that.

This post is subject to change, but this helps you along your way!

Loading

How to update Mastodon to a new version

EXPIRED: NEW GUIDE AVAILABLE HERE

Updating Mastodon and creating backups are important steps to ensure the security and stability of your instance. Here’s a comprehensive tutorial on how to update Mastodon, including making backups of the database and assets:


Note 1: Always perform updates on a test/staging instance before applying them to your live instance. This tutorial assumes you have some basic command line and server administration knowledge.

Note 2: If you made alterations to your files and want to update to a new branch, like v4.2.0, don’t forget to stash your files first. DO THIS AT YOUR OWN RISK.

cd /home/mastodon/live
git stash

You will not have an error message any more when entering:
I currently do not know how to put the stashed files back, this will be found out later.

git checkout v4.2.0

Note 3: If you switch to a new branch and version, like 4.2.0, you might run into an error stating the following:

rbenv: version '3.2.2' is not installed (set by /home/mastodon/live/.ruby-version)

Take the following steps to solve this problem:
(Type the version you need where it says x.x.x)

rbenv install x.x.x

If that fails, try the following command:

brew update && brew upgrade ruby-build

Followed by:
(Type the version you need where it says x.x.x)

rbenv install x.x.x

OPTIONAL: If bundler or rails fails to work, try the following commands:

gem install bundler

gem install rails

Click here for the backup steps. It basically comes down to a Database dump, a settings file backup and a Redis dump. If you wish to backup your assets like images and stuff (User-uploaded files), backup the folder named “public/system”. Keep in mind that this folder can be rather large. Actually, it can become rather massive.

After a good 90 minutes, I gave up on trying to show you how large the asset folder is. So beware if you are going to make a backup of it. Perhaps you can just skip the cache folder?

You can always check the folder size by using NCDU, for which you can find the manual here. Also, installations may vary, but this is an example of my instance.


Upgrade procedure.

  1. su - mastodon
  2. cd /home/mastodon/live
  3. git fetch --tags
  4. git checkout [type the most recent version here, starting with the letter v. For example; v4.0.1
    
    Command example: git checkout v4.0.1
  5. bundle install
  6. yarn install
  7. RAILS_ENV=production bundle exec rails db:migrate
  8. RAILS_ENV=production bundle exec rails assets:precompile
  9. exit
  10. reboot now

And that should be it!

If you don’t want to restart your server, use the following commands instead of “reboot now”:

  1. exit
  2. systemctl restart mastodon-sidekiq
  3. systemctl reload mastodon-web

    The reload operation is a zero-downtime restart, also called a “phased restart”. As such, Mastodon upgrades usually do not require any advance notice to users about planned downtime. In rare cases, you can use the restart operation instead, but there will be a (short) felt interruption of service for your users.

  4. The streaming API server is also updated and requires a restart; doing so will result in all connected clients being disconnected, which can increase the load on your server:
systemctl restart mastodon-streaming

Done!

PS: When I updated my instance from 4.1.9 to 4.2.0, a lot of warnings flew by, and this is, in my experience, not a problem as the instance is working perfectly.

Loading

A working Apache2 server with PHP7.4

I was in need of a server solution that could be quickly deployed as a VM.

      1. Install Debian 11 as a VM with web- and SSH server
      2. Create a USER next to your root account during the installation
      3. Find the IP address of the new installation. The easiest is if you have NoVNC running. Log in as USER and type
        ip a
      4. Time to so the sudo thing
        su

        log in as root

        apt-get update && apt-get install -y sudo
        usermod -aG sudo USER
        exit
        exit

        log back in as USER

      5. Okay, let’s install some more stuff but first we do an update
        sudo apt-get update && sudo apt-get upgrade -y

        Now we want some essentials

        sudo apt-get install -y dirmngr gnupg2 nano wget gpg curl fail2ban ufw software-properties-common

        Preparing the PHP install

        wget -q https://packages.sury.org/php/apt.gpg -O- | sudo apt-key add -
        echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
        sudo apt-get update
        sudo apt-get install -y php7.4 libapache2-mod-php7.4 php7.4-mysql php7.4-curl php7.4-gd php7.4-mbstring php7.4-xml php7.4-xmlrpc php7.4-zip

        And restart the Apache2 Webserver

        sudo systemctl restart apache2
      6. Alright, that’s done. Next step is to test things.
        sudo nano /var/www/html/test.php

        Enter this into the php file and press Control X and type Y to save and exit.

        <?php
        // Show all PHP information
        phpinfo();
        ?>
      7. Go to the IP address of the server you just created and type
        HTTP://IP ADDRESS/test.php
        

        If you see a PHP page with all sorts of data, you’re good. If not, go fix. Don’t ask me, I’m not there yet!

Loading

Adding and removing a user in PLIK

ADD A USER
Open the UNraid console and enter

./plikd --config ./plikd.cfg user create --login USERNAME --name Admin --admin

The result should be as follows:

Generated password for user controller is yH7ggwod473A3xM5BdI8wEz2FM7bcqF1

REMOVE A USER

Find the user:

./plikd user list

You should see:

local:USERNAME Admin

To remove user, enter:

./plikd --config ./plikd.cfg user delete --login USERNAME Admin

Loading