Skip to content

Initial server setup

Spin up a server instance on Linode and SSH in using newly-created root login credentials.

Users

Initially logged in as a root user - therefore need to add a non-root user & also add this new account to the sudo group

user setup

sudo adduser <username> && sudo usermod -aG sudo <username>

Software updates

Update package list and ensure all are the latest versions

software update

sudo apt update && sudo apt upgrade -y

Next switch on unattended upgrades to ensure the server remains up to date

software update

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades

Network time protocol

It is particularly important to do this for Authelia given the use of time-based one-time 2FA passcodes

Set timezone, install ntp service, activate ntp, check settings

sudo timedatectl set-timezone Europe/London
sudo apt install systemd-timesyncd
read -p "Wait 2 sec then press [ENTER] to enable ntp" # short pause to allow service to start
sudo timedatectl set-ntp true
read -p "Wait 2 sec then press [ENTER] to check ntp configured OK" # short pause to allow service to start
timedatectl

Host details

Set base configuration for the server:

Set hostname

sudo hostnamectl set-hostname <hostname>

Add to hosts

sudo nano /etc/hosts
add a line with IP FQDN hostname - e.g. 1.2.3.4 server.domain.com server

SSH setup

Create public/private key pair on local machine

ssh-kegen

Copy public key across to the server

ssh-copy-id -i ~/.ssh/id_rsa.pub <username>@<linodeIP>

Disable password login

sudo nano /etc/ssh/sshd_config
Change the following parameters:
PermitRootLogin no
PermitRootLogin prohibit-password
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
AllowUsers <username1> <username2>

Restart SSH daemon

sudo systemctl restart sshd

Check first!

Open new tab and check can still login OK before closing this connection!

Firewall

Uncomplicated firewall (ufw) - https://en.wikipedia.org/wiki/Uncomplicated_Firewall

Install & enable uncomplicated firewall

sudo apt-get install ufw -y
sudo systemctl enable ufw --now
sudo ufw allow ssh
sudo ufw default allow outgoing
sudo ufw default deny incoming
sudo ufw show added #(1)
sudo ufw enable
sudo ufw status numbered
sudo ufw logging on #(2)
  1. [to confirm ssh added]
  2. [see /var/log/ufw.log]

To see a list of ports currently listening for open connections

sudo ss -atpu
ufw-setup.sh - [DOWNLOAD]
#!/bin/bash
# ufw setup script
# Written by AJR 2022

function pause_continue {
    # create user prompt with autocontinue and use $'STRING\n' to create new line
    read -p $'Press [ENTER] to continue (will continue automatically in 5s)\n' -t 5
}

# output to log file (appended) as well as screen
echo "Script started: $(date)" > ufw_setup.log
echo "-->> Setting up uncomplicated firewall (ufw)" | tee -a ufw_setup.log;

echo "-->> Install ufw" | tee -a ufw_setup.log; pause_continue
sudo apt-get install ufw -y | tee -a ufw_setup.log

echo "-->> Enable and start ufw" | tee -a ufw_setup.log; pause_continue
sudo ufw enable ufw | tee -a ufw_setup.log

echo "-->> Add rule to allow SSH (22)" | tee -a ufw_setup.log; pause_continue
sudo ufw allow ssh | tee -a ufw_setup.log

echo "-->> Add rule to allow http (80) and https (443)" | tee -a ufw_setup.log; pause_continue
sudo ufw allow 'WWW Full' | tee -a ufw_setup.log

echo "-->> Add rule to allow outgoing traffic" | tee -a ufw_setup.log; pause_continue
sudo ufw default allow outgoing | tee -a ufw_setup.log

echo "-->> Add rule to deny incoming traffic by default (apart from on previous ports)" | tee -a ufw_setup.log; pause_continue
sudo ufw default deny incoming | tee -a ufw_setup.log

echo "-->> Show added rules - CONFIRM SSH IS SHOWING" | tee -a ufw_setup.log; pause_continue
sudo ufw show added | tee -a ufw_setup.log

echo "-->> Reload ufw now new rules added" | tee -a ufw_setup.log; pause_continue
sudo ufw reload | tee -a ufw_setup.log

echo "-->> Show numbered status of opened ports" | tee -a ufw_setup.log; pause_continue
sudo ufw status numbered | tee -a ufw_setup.log

echo "-->> Switch on ufw logging" | tee -a ufw_setup.log; pause_continue
sudo ufw logging on | tee -a ufw_setup.log

echo "-->> Show all ports opened on system" | tee -a ufw_setup.log; pause_continue
sudo ss -atpu | tee -a ufw_setup.log

echo "-->> ufw setup complete - see $PWD/ufw_setup.log for log file"
echo "Script completed: $(date)" >> ufw_setup.log

Issue with Docker overruling ufw settings for opening ports

Docker maintains its own iptables chain which means that any ports opened externally in Docker will automatically be allowed regardless of ufw settings (see this Stack Overflow article).

Given we are going to set up a reverse proxy manager the easier option is to only internally 'expose' ports when setting up a container rather than 'open' them. This means they will be available internally on the Docker network and the reverse proxy will be able to point to them OK but they won't be open to external access.

To delete an existing rule enter the existing rule with delete before it

sudo ufw delete allow 9443

Optional items

Configure bash

History

The history command in bash shows previously run commands.
These can then be run with !<number>.
The following enhances the stored list by adding commands run in other windows and adding date/time to the list.

Alter ~/.bashrc

echo 'PROMPT_COMMAND="history -a; history -c; history -r;"' >> ~/.bashrc
echo 'HISTTIMEFORMAT="<%Y-%m-%y @ %T> "' >> ~/.bashrc

neofetch

neofetch is a command-line system information tool written in bash that displays information about your operating system, software and hardware in an aesthetic and visually pleasing way - https://github.com/dylanaraps/neofetch

Install neofetch and run on terminal session startup

sudo apt install neofetch -y
echo "neofetch" >> ~/.bashrc
Run neofetch once to create a config file then edit this as required - e.g. to add disk usage, rename IPv4/v6, etc.
nano ~/.config/neofetch/config.conf

~/.config/neofetch/config.conf
# See this wiki page for more info:
# https://github.com/dylanaraps/neofetch/wiki/Customizing-Info
print_info() {
    info title
    info underline

    info "OS" distro
    info "Host" model
    info "Kernel" kernel
    info "Uptime" uptime
    info "Packages" packages
    info "Shell" shell
    info "Resolution" resolution
    info "DE" de
    info "WM" wm
    info "WM Theme" wm_theme
    info "Theme" theme
    info "Icons" icons
    info "Terminal" term
    info "Terminal Font" term_font
    info "CPU" cpu
    info "GPU" gpu
    info "Memory" memory

    # info "GPU Driver" gpu_driver  # Linux/macOS only
    # info "CPU Usage" cpu_usage
    info "Disk" disk
    # info "Battery" battery
    # info "Font" font
    # info "Song" song
    # [[ "$player" ]] && prin "Music Player" "$player"
    info "IP v4" local_ip
    info "IP v6" public_ip
    # info "Users" users
    # info "Locale" locale  # This only works on glibc systems.

    info cols
}

# Title


# Hide/Show Fully qualified domain name.
#
# Default:  'off'
# Values:   'on', 'off'
# Flag:     --title_fqdn
title_fqdn="off"


# Kernel


# Shorten the output of the kernel function.
#
# Default:  'on'
# Values:   'on', 'off'
# Flag:     --kernel_shorthand
# Supports: Everything except *BSDs (except PacBSD and PC-BSD)
#
# Example:
# on:  '4.8.9-1-ARCH'
# off: 'Linux 4.8.9-1-ARCH'
kernel_shorthand="on"


# Distro


# Shorten the output of the distro function
#
# Default:  'off'
# Values:   'on', 'tiny', 'off'
# Flag:     --distro_shorthand
# Supports: Everything except Windows and Haiku
distro_shorthand="off"

# Show/Hide OS Architecture.
# Show 'x86_64', 'x86' and etc in 'Distro:' output.
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --os_arch
#
# Example:
# on:  'Arch Linux x86_64'
# off: 'Arch Linux'
os_arch="on"


# Uptime


# Shorten the output of the uptime function
#
# Default: 'on'
# Values:  'on', 'tiny', 'off'
# Flag:    --uptime_shorthand
#
# Example:
# on:   '2 days, 10 hours, 3 mins'
# tiny: '2d 10h 3m'
# off:  '2 days, 10 hours, 3 minutes'
uptime_shorthand="on"


# Memory


# Show memory pecentage in output.
#
# Default: 'off'
# Values:  'on', 'off'
# Flag:    --memory_percent
#
# Example:
# on:   '1801MiB / 7881MiB (22%)'
# off:  '1801MiB / 7881MiB'
memory_percent="on"

# Change memory output unit.
#
# Default: 'mib'
# Values:  'kib', 'mib', 'gib'
# Flag:    --memory_unit
#
# Example:
# kib  '1020928KiB / 7117824KiB'
# mib  '1042MiB / 6951MiB'
# gib: ' 0.98GiB / 6.79GiB'
memory_unit="mib"


# Packages


# Show/Hide Package Manager names.
#
# Default: 'tiny'
# Values:  'on', 'tiny' 'off'
# Flag:    --package_managers
#
# Example:
# on:   '998 (pacman), 8 (flatpak), 4 (snap)'
# tiny: '908 (pacman, flatpak, snap)'
# off:  '908'
package_managers="on"


# Shell


# Show the path to $SHELL
#
# Default: 'off'
# Values:  'on', 'off'
# Flag:    --shell_path
#
# Example:
# on:  '/bin/bash'
# off: 'bash'
shell_path="off"

# Show $SHELL version
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --shell_version
#
# Example:
# on:  'bash 4.4.5'
# off: 'bash'
shell_version="on"


# CPU


# CPU speed type
#
# Default: 'bios_limit'
# Values: 'scaling_cur_freq', 'scaling_min_freq', 'scaling_max_freq', 'bios_limit'.
# Flag:    --speed_type
# Supports: Linux with 'cpufreq'
# NOTE: Any file in '/sys/devices/system/cpu/cpu0/cpufreq' can be used as a value.
speed_type="bios_limit"

# CPU speed shorthand
#
# Default: 'off'
# Values: 'on', 'off'.
# Flag:    --speed_shorthand
# NOTE: This flag is not supported in systems with CPU speed less than 1 GHz
#
# Example:
# on:    'i7-6500U (4) @ 3.1GHz'
# off:   'i7-6500U (4) @ 3.100GHz'
speed_shorthand="off"

# Enable/Disable CPU brand in output.
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --cpu_brand
#
# Example:
# on:   'Intel i7-6500U'
# off:  'i7-6500U (4)'
cpu_brand="on"

# CPU Speed
# Hide/Show CPU speed.
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --cpu_speed
#
# Example:
# on:  'Intel i7-6500U (4) @ 3.1GHz'
# off: 'Intel i7-6500U (4)'
cpu_speed="on"

# CPU Cores
# Display CPU cores in output
#
# Default: 'logical'
# Values:  'logical', 'physical', 'off'
# Flag:    --cpu_cores
# Support: 'physical' doesn't work on BSD.
#
# Example:
# logical:  'Intel i7-6500U (4) @ 3.1GHz' (All virtual cores)
# physical: 'Intel i7-6500U (2) @ 3.1GHz' (All physical cores)
# off:      'Intel i7-6500U @ 3.1GHz'
cpu_cores="logical"

# CPU Temperature
# Hide/Show CPU temperature.
# Note the temperature is added to the regular CPU function.
#
# Default: 'off'
# Values:  'C', 'F', 'off'
# Flag:    --cpu_temp
# Supports: Linux, BSD
# NOTE: For FreeBSD and NetBSD-based systems, you'll need to enable
#       coretemp kernel module. This only supports newer Intel processors.
#
# Example:
# C:   'Intel i7-6500U (4) @ 3.1GHz [27.2°C]'
# F:   'Intel i7-6500U (4) @ 3.1GHz [82.0°F]'
# off: 'Intel i7-6500U (4) @ 3.1GHz'
cpu_temp="off"


# GPU


# Enable/Disable GPU Brand
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --gpu_brand
#
# Example:
# on:  'AMD HD 7950'
# off: 'HD 7950'
gpu_brand="on"

# Which GPU to display
#
# Default: 'all'
# Values:  'all', 'dedicated', 'integrated'
# Flag:    --gpu_type
# Supports: Linux
#
# Example:
# all:
#   GPU1: AMD HD 7950
#   GPU2: Intel Integrated Graphics
#
# dedicated:
#   GPU1: AMD HD 7950
#
# integrated:
#   GPU1: Intel Integrated Graphics
gpu_type="all"


# Resolution


# Display refresh rate next to each monitor
# Default: 'off'
# Values:  'on', 'off'
# Flag:    --refresh_rate
# Supports: Doesn't work on Windows.
#
# Example:
# on:  '1920x1080 @ 60Hz'
# off: '1920x1080'
refresh_rate="off"


# Gtk Theme / Icons / Font


# Shorten output of GTK Theme / Icons / Font
#
# Default: 'off'
# Values:  'on', 'off'
# Flag:    --gtk_shorthand
#
# Example:
# on:  'Numix, Adwaita'
# off: 'Numix [GTK2], Adwaita [GTK3]'
gtk_shorthand="off"


# Enable/Disable gtk2 Theme / Icons / Font
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --gtk2
#
# Example:
# on:  'Numix [GTK2], Adwaita [GTK3]'
# off: 'Adwaita [GTK3]'
gtk2="on"

# Enable/Disable gtk3 Theme / Icons / Font
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --gtk3
#
# Example:
# on:  'Numix [GTK2], Adwaita [GTK3]'
# off: 'Numix [GTK2]'
gtk3="on"


# IP Address


# Website to ping for the public IP
#
# Default: 'http://ident.me'
# Values:  'url'
# Flag:    --ip_host
public_ip_host="http://ident.me"

# Public IP timeout.
#
# Default: '2'
# Values:  'int'
# Flag:    --ip_timeout
public_ip_timeout=2


# Desktop Environment


# Show Desktop Environment version
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --de_version
de_version="on"


# Disk


# Which disks to display.
# The values can be any /dev/sdXX, mount point or directory.
# NOTE: By default we only show the disk info for '/'.
#
# Default: '/'
# Values:  '/', '/dev/sdXX', '/path/to/drive'.
# Flag:    --disk_show
#
# Example:
# disk_show=('/' '/dev/sdb1'):
#      'Disk (/): 74G / 118G (66%)'
#      'Disk (/mnt/Videos): 823G / 893G (93%)'
#
# disk_show=('/'):
#      'Disk (/): 74G / 118G (66%)'
#
disk_show=('/')

# Disk subtitle.
# What to append to the Disk subtitle.
#
# Default: 'mount'
# Values:  'mount', 'name', 'dir', 'none'
# Flag:    --disk_subtitle
#
# Example:
# name:   'Disk (/dev/sda1): 74G / 118G (66%)'
#         'Disk (/dev/sdb2): 74G / 118G (66%)'
#
# mount:  'Disk (/): 74G / 118G (66%)'
#         'Disk (/mnt/Local Disk): 74G / 118G (66%)'
#         'Disk (/mnt/Videos): 74G / 118G (66%)'
#
# dir:    'Disk (/): 74G / 118G (66%)'
#         'Disk (Local Disk): 74G / 118G (66%)'
#         'Disk (Videos): 74G / 118G (66%)'
#
# none:   'Disk: 74G / 118G (66%)'
#         'Disk: 74G / 118G (66%)'
#         'Disk: 74G / 118G (66%)'
disk_subtitle="none"

# Disk percent.
# Show/Hide disk percent.
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --disk_percent
#
# Example:
# on:  'Disk (/): 74G / 118G (66%)'
# off: 'Disk (/): 74G / 118G'
disk_percent="on"


# Song


# Manually specify a music player.
#
# Default: 'auto'
# Values:  'auto', 'player-name'
# Flag:    --music_player
#
# Available values for 'player-name':
#
# amarok
# audacious
# banshee
# bluemindo
# clementine
# cmus
# deadbeef
# deepin-music
# dragon
# elisa
# exaile
# gnome-music
# gmusicbrowser
# gogglesmm
# guayadeque
# io.elementary.music
# iTunes
# juk
# lollypop
# mocp
# mopidy
# mpd
# muine
# netease-cloud-music
# olivia
# playerctl
# pogo
# pragha
# qmmp
# quodlibet
# rhythmbox
# sayonara
# smplayer
# spotify
# strawberry
# tauonmb
# tomahawk
# vlc
# xmms2d
# xnoise
# yarock
music_player="auto"

# Format to display song information.
#
# Default: '%artist% - %album% - %title%'
# Values:  '%artist%', '%album%', '%title%'
# Flag:    --song_format
#
# Example:
# default: 'Song: Jet - Get Born - Sgt Major'
song_format="%artist% - %album% - %title%"

# Print the Artist, Album and Title on separate lines
#
# Default: 'off'
# Values:  'on', 'off'
# Flag:    --song_shorthand
#
# Example:
# on:  'Artist: The Fratellis'
#      'Album: Costello Music'
#      'Song: Chelsea Dagger'
#
# off: 'Song: The Fratellis - Costello Music - Chelsea Dagger'
song_shorthand="off"

# 'mpc' arguments (specify a host, password etc).
#
# Default:  ''
# Example: mpc_args=(-h HOST -P PASSWORD)
mpc_args=()


# Text Colors


# Text Colors
#
# Default:  'distro'
# Values:   'distro', 'num' 'num' 'num' 'num' 'num' 'num'
# Flag:     --colors
#
# Each number represents a different part of the text in
# this order: 'title', '@', 'underline', 'subtitle', 'colon', 'info'
#
# Example:
# colors=(distro)      - Text is colored based on Distro colors.
# colors=(4 6 1 8 8 6) - Text is colored in the order above.
colors=(distro)


# Text Options


# Toggle bold text
#
# Default:  'on'
# Values:   'on', 'off'
# Flag:     --bold
bold="on"

# Enable/Disable Underline
#
# Default:  'on'
# Values:   'on', 'off'
# Flag:     --underline
underline_enabled="on"

# Underline character
#
# Default:  '-'
# Values:   'string'
# Flag:     --underline_char
underline_char="-"


# Info Separator
# Replace the default separator with the specified string.
#
# Default:  ':'
# Flag:     --separator
#
# Example:
# separator="->":   'Shell-> bash'
# separator=" =":   'WM = dwm'
separator=":"


# Color Blocks


# Color block range
# The range of colors to print.
#
# Default:  '0', '15'
# Values:   'num'
# Flag:     --block_range
#
# Example:
#
# Display colors 0-7 in the blocks.  (8 colors)
# neofetch --block_range 0 7
#
# Display colors 0-15 in the blocks. (16 colors)
# neofetch --block_range 0 15
block_range=(0 15)

# Toggle color blocks
#
# Default:  'on'
# Values:   'on', 'off'
# Flag:     --color_blocks
color_blocks="on"

# Color block width in spaces
#
# Default:  '3'
# Values:   'num'
# Flag:     --block_width
block_width=3

# Color block height in lines
#
# Default:  '1'
# Values:   'num'
# Flag:     --block_height
block_height=1

# Color Alignment
#
# Default: 'auto'
# Values: 'auto', 'num'
# Flag: --col_offset
#
# Number specifies how far from the left side of the terminal (in spaces) to
# begin printing the columns, in case you want to e.g. center them under your
# text.
# Example:
# col_offset="auto" - Default behavior of neofetch
# col_offset=7      - Leave 7 spaces then print the colors
col_offset="auto"

# Progress Bars


# Bar characters
#
# Default:  '-', '='
# Values:   'string', 'string'
# Flag:     --bar_char
#
# Example:
# neofetch --bar_char 'elapsed' 'total'
# neofetch --bar_char '-' '='
bar_char_elapsed="-"
bar_char_total="="

# Toggle Bar border
#
# Default:  'on'
# Values:   'on', 'off'
# Flag:     --bar_border
bar_border="on"

# Progress bar length in spaces
# Number of chars long to make the progress bars.
#
# Default:  '15'
# Values:   'num'
# Flag:     --bar_length
bar_length=15

# Progress bar colors
# When set to distro, uses your distro's logo colors.
#
# Default:  'distro', 'distro'
# Values:   'distro', 'num'
# Flag:     --bar_colors
#
# Example:
# neofetch --bar_colors 3 4
# neofetch --bar_colors distro 5
bar_color_elapsed="distro"
bar_color_total="distro"


# Info display
# Display a bar with the info.
#
# Default: 'off'
# Values:  'bar', 'infobar', 'barinfo', 'off'
# Flags:   --cpu_display
#          --memory_display
#          --battery_display
#          --disk_display
#
# Example:
# bar:     '[---=======]'
# infobar: 'info [---=======]'
# barinfo: '[---=======] info'
# off:     'info'
cpu_display="off"
memory_display="off"
battery_display="off"
disk_display="barinfo"


# Backend Settings


# Image backend.
#
# Default:  'ascii'
# Values:   'ascii', 'caca', 'chafa', 'jp2a', 'iterm2', 'off',
#           'pot', 'termpix', 'pixterm', 'tycat', 'w3m', 'kitty'
# Flag:     --backend
image_backend="ascii"

# Image Source
#
# Which image or ascii file to display.
#
# Default:  'auto'
# Values:   'auto', 'ascii', 'wallpaper', '/path/to/img', '/path/to/ascii', '/path/to/dir/'
#           'command output (neofetch --ascii "$(fortune | cowsay -W 30)")'
# Flag:     --source
#
# NOTE: 'auto' will pick the best image source for whatever image backend is used.
#       In ascii mode, distro ascii art will be used and in an image mode, your
#       wallpaper will be used.
image_source="auto"


# Ascii Options


# Ascii distro
# Which distro's ascii art to display.
#
# Default: 'auto'
# Values:  'auto', 'distro_name'
# Flag:    --ascii_distro
# NOTE: AIX, Alpine, Anarchy, Android, Antergos, antiX, "AOSC OS",
#       "AOSC OS/Retro", Apricity, ArcoLinux, ArchBox, ARCHlabs,
#       ArchStrike, XFerience, ArchMerge, Arch, Artix, Arya, Bedrock,
#       Bitrig, BlackArch, BLAG, BlankOn, BlueLight, bonsai, BSD,
#       BunsenLabs, Calculate, Carbs, CentOS, Chakra, ChaletOS,
#       Chapeau, Chrom*, Cleanjaro, ClearOS, Clear_Linux, Clover,
#       Condres, Container_Linux, CRUX, Cucumber, Debian, Deepin,
#       DesaOS, Devuan, DracOS, DarkOs, DragonFly, Drauger, Elementary,
#       EndeavourOS, Endless, EuroLinux, Exherbo, Fedora, Feren, FreeBSD,
#       FreeMiNT, Frugalware, Funtoo, GalliumOS, Garuda, Gentoo, Pentoo,
#       gNewSense, GNOME, GNU, GoboLinux, Grombyang, Guix, Haiku, Huayra,
#       Hyperbola, janus, Kali, KaOS, KDE_neon, Kibojoe, Kogaion,
#       Korora, KSLinux, Kubuntu, LEDE, LFS, Linux_Lite,
#       LMDE, Lubuntu, Lunar, macos, Mageia, MagpieOS, Mandriva,
#       Manjaro, Maui, Mer, Minix, LinuxMint, MX_Linux, Namib,
#       Neptune, NetBSD, Netrunner, Nitrux, NixOS, Nurunner,
#       NuTyX, OBRevenge, OpenBSD, openEuler, OpenIndiana, openmamba,
#       OpenMandriva, OpenStage, OpenWrt, osmc, Oracle, OS Elbrus, PacBSD,
#       Parabola, Pardus, Parrot, Parsix, TrueOS, PCLinuxOS, Peppermint,
#       popos, Porteus, PostMarketOS, Proxmox, Puppy, PureOS, Qubes, Radix,
#       Raspbian, Reborn_OS, Redstar, Redcore, Redhat, Refracted_Devuan,
#       Regata, Rosa, sabotage, Sabayon, Sailfish, SalentOS, Scientific,
#       Septor, SereneLinux, SharkLinux, Siduction, Slackware, SliTaz,
#       SmartOS, Solus, Source_Mage, Sparky, Star, SteamOS, SunOS,
#       openSUSE_Leap, openSUSE_Tumbleweed, openSUSE, SwagArch, Tails,
#       Trisquel, Ubuntu-Budgie, Ubuntu-GNOME, Ubuntu-MATE, Ubuntu-Studio,
#       Ubuntu, Venom, Void, Obarun, windows10, Windows7, Xubuntu, Zorin,
#       and IRIX have ascii logos
# NOTE: Arch, Ubuntu, Redhat, and Dragonfly have 'old' logo variants.
#       Use '{distro name}_old' to use the old logos.
# NOTE: Ubuntu has flavor variants.
#       Change this to Lubuntu, Kubuntu, Xubuntu, Ubuntu-GNOME,
#       Ubuntu-Studio, Ubuntu-Mate  or Ubuntu-Budgie to use the flavors.
# NOTE: Arcolinux, Dragonfly, Fedora, Alpine, Arch, Ubuntu,
#       CRUX, Debian, Gentoo, FreeBSD, Mac, NixOS, OpenBSD, android,
#       Antrix, CentOS, Cleanjaro, ElementaryOS, GUIX, Hyperbola,
#       Manjaro, MXLinux, NetBSD, Parabola, POP_OS, PureOS,
#       Slackware, SunOS, LinuxLite, OpenSUSE, Raspbian,
#       postmarketOS, and Void have a smaller logo variant.
#       Use '{distro name}_small' to use the small variants.
ascii_distro="auto"

# Ascii Colors
#
# Default:  'distro'
# Values:   'distro', 'num' 'num' 'num' 'num' 'num' 'num'
# Flag:     --ascii_colors
#
# Example:
# ascii_colors=(distro)      - Ascii is colored based on Distro colors.
# ascii_colors=(4 6 1 8 8 6) - Ascii is colored using these colors.
ascii_colors=(distro)

# Bold ascii logo
# Whether or not to bold the ascii logo.
#
# Default: 'on'
# Values:  'on', 'off'
# Flag:    --ascii_bold
ascii_bold="on"


# Image Options


# Image loop
# Setting this to on will make neofetch redraw the image constantly until
# Ctrl+C is pressed. This fixes display issues in some terminal emulators.
#
# Default:  'off'
# Values:   'on', 'off'
# Flag:     --loop
image_loop="off"

# Thumbnail directory
#
# Default: '~/.cache/thumbnails/neofetch'
# Values:  'dir'
thumbnail_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/thumbnails/neofetch"

# Crop mode
#
# Default:  'normal'
# Values:   'normal', 'fit', 'fill'
# Flag:     --crop_mode
#
# See this wiki page to learn about the fit and fill options.
# https://github.com/dylanaraps/neofetch/wiki/What-is-Waifu-Crop%3F
crop_mode="normal"

# Crop offset
# Note: Only affects 'normal' crop mode.
#
# Default:  'center'
# Values:   'northwest', 'north', 'northeast', 'west', 'center'
#           'east', 'southwest', 'south', 'southeast'
# Flag:     --crop_offset
crop_offset="center"

# Image size
# The image is half the terminal width by default.
#
# Default: 'auto'
# Values:  'auto', '00px', '00%', 'none'
# Flags:   --image_size
#          --size
image_size="auto"

# Gap between image and text
#
# Default: '3'
# Values:  'num', '-num'
# Flag:    --gap
gap=3

# Image offsets
# Only works with the w3m backend.
#
# Default: '0'
# Values:  'px'
# Flags:   --xoffset
#          --yoffset
yoffset=0
xoffset=0

# Image background color
# Only works with the w3m backend.
#
# Default: ''
# Values:  'color', 'blue'
# Flag:    --bg_color
background_color=


# Misc Options

# Stdout mode
# Turn off all colors and disables image backend (ASCII/Image).
# Useful for piping into another command.
# Default: 'off'
# Values: 'on', 'off'
stdout="off"

https://bashrcgenerator.com/ - useful generator

oh-my-posh

Command line prettifier - handy for git directories - https://ohmyposh.dev/

Install neofetch and run on terminal session startup

sudo wget https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/posh-linux-amd64 -O /usr/local/bin/oh-my-posh
sudo chmod +x /usr/local/bin/oh-my-posh
mkdir ~/.poshthemes
wget https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest/download/themes.zip -O ~/.poshthemes/themes.zip
unzip ~/.poshthemes/themes.zip -d ~/.poshthemes
chmod u+rw ~/.poshthemes/*.omp.*
rm ~/.poshthemes/themes.zip

Ensure a Nerd Font [https://www.nerdfonts.com/] such as Caskaydia Cove NF is installed and selected in the terminal program
Use eval "$(oh-my-posh init bash --config ~/.poshthemes/[theme_name].omp.json)" to switch theme

Monitoring applications

Setup disk monitoring

Given potential disk space limits on a VPS it is important to be made aware of any impending issues of running out of space (the first symptom is often Authelia stopping working as redis is no longer able to log entries).

To do this the following are required:

  1. A mail sending program (msmtp has been chosen here)
  2. A script that will use the df command to check free space and send an email if the limit has been reached
  3. A crontab entry to regularly run the above script

Install msmtp and edit config

sudo apt install msmtp -y
sudo nano /etc/msmtprc
Sample /etc/msmtprc configuration file
# Store this file in /etc/msmtprc

# Set default values for all following accounts.
defaults
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile ~/.msmtp.log

# one.com
account onecom
host send.one.com
from webmaster@alanjrobertson.co.uk
auth on
user webmaster@alanjrobertson.co.uk
password 

# Set a default account
account default : onecom
Sample ~/scripts/diskmonitor.sh script
#!/bin/bash

# Purpose: Monitor Linux disk space and send an email alert to $ADMIN if $ALERT level reached
# Original script: https://www.cyberciti.biz/tips/shell-script-to-watch-the-disk-space.html
# Edited by: Alan J Robertson

ALERT=75 # alert level
TONAME="Alan Robertson"
TOEMAIL="ajr@alanjrobertson.co.uk"
FROMNAME="Linode Server"
FROMEMAIL="webmaster@alanjrobertson.co.uk"
LOGFILE="/home/alan/scripts/diskmonitor.log"
COMPOSEFILE="/home/alan/scripts/diskmonitor_stream.yml"

printf "diskmonitor.sh run on $(date) - " >> $LOGFILE

if [ "$1" == "weekly" ]; then 
  # weekly update email option selected
  printf "weekly email option selected" >> $LOGFILE
  printf "To: $TONAME <$TOEMAIL>\nFrom: $FROMNAME <$FROMEMAIL>\nSubject: Disk monitor weekly update\n\n" > /tmp/weeklyemail.msg
  cat $LOGFILE >> /tmp/weeklyemail.msg
  printf "\n[Sent: $(date)]" >> /tmp/weeklyemail.msg
  cat /tmp/weeklyemail.msg | msmtp -d -t > /tmp/email.out ; rm /tmp/weeklyemail.msg
  rm $LOGFILE; echo "Logfile reset [$(date)]" >> $LOGFILE
  docker stop dozzle-from-file-diskmonitor
  docker rm dozzle-from-file-diskmonitor
  docker compose -f $COMPOSEFILE up --detach  
else
  # routine daily check
  df -H /dev/sda | grep sda | awk '{ print $5 " " $1 }' | while read -r output;
  do
    usep=$(echo "$output" | awk '{ print $1}' | cut -d'%' -f1 )
    echo "currently used percentage = $usep% (warning limit set to $ALERT%)." >> $LOGFILE
    partition=$(echo "$output" | awk '{ print $2 }' )
    if [ $usep -ge $ALERT ]; then
      echo "Warning email sent $(date) as running out of space on $partition ($usep%)" >> $LOGFILE
      printf "To: $TONAME <$TOEMAIL>\nFrom: $FROMNAME <$FROMEMAIL>\nSubject: Disk space warning\n\nAlert: Running out of disk space on Linode server - $usep%% used (warning limit set to $ALERT%%).\n[Sent: $(date)]" | msmtp -d -t
    fi
  done
fi

Remember to chmod +x the new script file after creation!

Sample crontab entry to run at 5am daily and then weekly at 3am on a Monday morning for log email/cleanup

0 5 * * * /home/alan/scripts/diskmonitor.sh
0 3 * * 1 /home/alan/scripts/diskmonitor.sh weekly

btop

Terminal-based system resource overview app - https://github.com/aristocratos/btop (formerly bpytop)

Install pre-requisites

sudo apt install bzip2 make

Go to https://github.com/aristocratos/btop/releases/latest to check the latest release, right-click and copy the URL then replace [filename] below.

Download, untar and install

wget [latest x64 version for Linode, armv7l for Pi]
tar -xjf [filename].tgz
cd btop
./install.sh

ctop

Similar to htop but based on viewing container activity instead - https://github.com/bcicen/ctop

Go to https://github.com/bcicen/ctop/releases/latest to check the latest release, right-click and copy the URL then change URL below.

Download, untar and install

sudo wget https://github.com/bcicen/ctop/releases/download/v0.7.7/ctop-0.7.7-linux-amd64 \
-O /usr/local/bin/ctop \
&& sudo chmod +x /usr/local/bin/ctop

Once installed type ctop to run, then press H to open help menu and see available commands (e.g., to change sort order).

Setup fail2ban

fail2ban options

Logfiles for access attempts can be viewed as follows:

sudo lastb -adF -20 #will show last 20 entries
Given the multiple attempts normally seen on cloud-hosted private virtual servers is worth considering fail2ban to ban IPs that make repeated attempts.
Installation instructions are as follows:
sudo apt install fail2ban -y
cd /etc/fail2ban
sudo cp fail2ban.conf fail2ban.local #good practice although unlikely will need to edit
sudo cp jail.conf jail.local
sudo nano jail.local
Then make the following changes:

  • uncomment bantime.increment (line 49)
  • uncomment ignoreip (line 92) and add the main IPs you will connect from
  • add enabled = true for jails you want to activate (see JAILS section - normally want sshd, starting at line 279)
  • restart the service: sudo systemctl restart fail2ban
  • check active jails (specific jails can only be activated once relevant service installed - eg nginx) sudo fail2ban-client status
  • view overall status of a jail (e.g., SSH) sudo fail2ban-client status sshd
  • to view the service logs: sudo cat /var/log/fail2ban.log or sudo tail -f /var/log/fail2ban.log
  • to view the authorisation logs: sudo cat /var/log/auth.log or sudo tail -f /var/log/auth.log

Work in progress - would probably only need to monitor the Authelia logs? https://www.reddit.com/r/selfhosted/comments/srrg7n/fail2ban_and_docker/