Table of Contents

General info on Debian


Initial steps

Watchlist for backup

/etc/nginx/sites-available/* 
/var/www/*
/etc/transmission-daemon/  
/opt/scripts/ 

update-motd

/etc/update-motd.d/

crontab

sudo crontab -l 
sudo -u www-data crontab -l 
crontab -l 

MariaDB per DATABASE

Backup MariaDB DATABASE

/usr/bin/mysqldump --single-transaction -h localhost -u root -p[database_passwd] [database_name] > /..(path)../.backup/[database_name]-sqlbkp_`date +"%Y%m%d"`.bak

Backup using rsync command

Backup Nginx configuration files
sudo rsync -avh --progress /etc/nginx/sites-available/ /home/meson/.backup/nginx/nginx_config_`date +"%Y%m"`/ 
Backup HTML source files
sudo rsync -avh --progress /var/www/ /home/meson/.backup/html/html_backup_`date +"%Y%m"`/

Remote backup for webpages

Rsync with [TARGET] using rsync from [SOURCE]

sudo -u www-data rsync -azP --exclude '.ssh' -e 'ssh -p [port_number]' --rsync-path="sudo rsync" /var/www/ [user]@[TARGET]:"/[TARGET PATH]../../"

Put [SOURCE] public key in [TARGET] user's authorized_keys


Configure log files

Edit /etc/nginx/nginx.conf

        access_log /var/log/nginx/_access.log;
        error_log /var/log/nginx/_error.log;

Purge log files

Cleaning compressed log files
sudo find /var/log -name '*.gz' -exec rm {} \;

Set hostnames

sudo hostname HOSTiD 
sudo hostnamectl HOSTiD 

Edit /etc/hostname with full domain name

hostid.mydomain.com

Enable SSH

Genesis step for all Linux works.


Generate Public/Private key pair

  ssh-keygen -t rsa -b 4096 
  ssh-keygen -t dsa
  ssh-keygen -t ecdsa -b 521
  ssh-keygen -t ed25519
  touch $home/.ssh/authorized_keys 
  chmod 600 $home/.ssh/authorized_keys 

Append public keys for SSH client.

β€”

SSH Key to ED25519

ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519 -C "john@example.com"

β€”

Enable colorful terminal

Comment out force_color_prompt=yes in ~/.bashrc

  vi ~/.bashrc 
  source ./.bashrc 

Time stamp prompt

Edit ~/.bashrc and change PS1 line

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]: \[\033[01;33m\]\D{%T}\[\033[00m\] \[\033[01;37m\]\w\$\[\033[00m\] '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h: \D{%T} \w\$ '
fi

Save and load .bashrc

source ~/.bashrc 

User aliases command

If you don't have .bash_aliases in your home directory.

touch .bash_aliases    

Edit .bash_aliases. Example: Backup Nginx configuration files with date stamp.

alias backup_nginx='sudo rsync -avh --progress /etc/nginx/ /home/user/storage/Nginx.Config//nginx_config_`date +"%Y%m%d"`/'

Configure Dynamic DNS

Google Domains with ddclient

Dynamic DNS records are configured in Google Domains, then update IP using ddclient.Set Up Dynamic DNS in Google Domains. Keep generated credentials to use in ddclient.

  sudo apt-get install ddclient 

ddclient and related packages are installed and will pop up the screen to ask a few parameters. Just do it as you wish and exit quickly. This is not your big deal.
Edit /etc/ddclient.conf

  protocol=dyndns2
  ssl=yes
  use=web
  server=domains.google.com
  login=generated_username
  password=generated_password
  your_resource.your_domain.tld 

If this configuration is not work when you run ddclient -noquiet with some WARNINGs because ddclient does not support Google Domains directly. Then change configuration file as followings:

Google Domain protocol is updated, so use it directly.

  protocol=googledomains
  use=web                # this is essential.
  ssl=yes
  login=generated_username
  password=generated_password
  your_resource.your_domain.tld 

Edit sudo crontab -e to run periodically or register as daemon to run start.


Cloudflare with ddclient

Assume you already installed ddclient before this. β€” Google Domains with ddclient

It require a package libjson-any-perl

  sudo apt-get install libjson-any-perl

edit /etc/ddclient.conf

 ssl=yes
 use=web
 protocol=cloudflare, 				\
 zone=yourhost.com,				\
 login=my-cloudflare-login@email.com,		\
 password=cloudflare-API-global-token		\
 ddns.yourhost.com,

login is email address for Cloudflare and password is API key string. Cloudflareβ„’ with ddclient uses JSON format.

  sudo ddclient -verbos -noquiet 

Run with -verbos and -noquiet option to see the progress. Messages, if any, error(s) show up. add work in crontab with root permission

  sudo crontab -e 
30 */2 * * * /usr/sbin/ddclient -quiet 

This crontab runs at minute 30 past every 2nd hour.


FreeDNS with ddclient

Edit /etc/ddclient.conf

 ssl=yes
 use=web 
 protocol=freedns
 login=login_id
 password='account_password'
 ddns.yourhost.com

Add crontab schedule,

  sudo crontab -e 

NO-IP with ddclient

  protocol=dyndns2
  server=dynupdate.no-ip.com
  login=your_login_id
  password=your_password
  your_domain.com

Google Domains with API

Create Synthetic record with Dynamic DNS option and keep generated credentials

#!/bin/bash
 
### Google Domains provides an API to update a DNS "Syntheitc record". This script
### updates a record with the script-runner's public IP, as resolved using a DNS
### lookup.
###
### Google Dynamic DNS: https://support.google.com/domains/answer/6147083
### Synthetic Records: https://support.google.com/domains/answer/6069273
 
USERNAME="generated_id"
PASSWORD="generated_password"
HOSTNAME="yoursubdomain.yourdomain.here"
 
# Resolve current public IP
IP=$( dig +short myip.opendns.com @resolver1.opendns.com )
# Update Google DNS Record
URL="https://${USERNAME}:${PASSWORD}@domains.google.com/nic/update?hostname=${HOSTNAME}&myip=${IP}"
curl -s $URL

Cloudflare with API

Getting user's data from Cloudfalreβ„’ Before, you set up the dynamic DNS from Cloudfalreβ„’, you need to set A record with your desired domain name. If you want to use DDNS.DOMAIN.COM as your dynamic DNS. Put A record in DOMAIN.COM section.

curl -X GET 'https://api.cloudflare.com/client/v4/zones/7140bd43dh357d0e8ee2ea786cef70ae/dns_records' \
    -H 'X-Auth-Email: 'YOU@DOMAIN.COM \
    -H 'X-Auth-Key: '8afbeYOUR0API0KEY0INdCLOUDFLARE0 \
    -H 'Content-Type: application/json'

Check your Global API key for X-Auth-Key from My Profiles and Zone ID can be found in your DOMAIN.COM page.

This will shows bunch of strings and just copy them or your can make text file appending Β» ~/cloudflare.json

To find data you want, you need to arrange using Online JSON parser or your editor. Find out id value for specific domains. Here assume id for ddns.DOMAIN.COM under DOMAIN.COM is 372e679540…86b9e0b59 Make shell script.

#!/bin/sh
 NEW_IP=`curl ifconfig.me/ip`
 CURRENT_IP=`cat /var/tmp/current_ip.dat`
 
  if [ "$NEW_IP" = "$CURRENT_IP" ]
  then
      echo "No Change in IP Adddress"
  else
   curl -X PUT 'https://api.cloudflare.com/client/v4/zones/7140bd43dh357d0e8ee2ea786cef70ae/dns_records/372e679540...86b9e0b59' \
    -H 'X-Auth-Email: 'YOU@DOMAIN.COM \
    -H 'X-Auth-Key: '8afbeYOUR0API0KEY0INdCLOUDFLARE0 \
    -H 'Content-Type: application/json' \
    --data '{
        "type": "A",
        "name": "ddns.domain.com",
        "content": '\"$NEW_IP\"',
        "proxied": true
    }'
   echo $NEW_IP > /var/tmp/current_ip.dat
 fi

grant execute permission

  sudo chmod +x ./ddns.sh

and touch file to record current IP address.

  sudo touch /var/tmp/current_ip.dat

ifconfig.me/ip is API to retrieve external IP for Dynamic DNS. Alternatives are ifconfig.io/ip or api.ipify.org
If your script is /usr/bin/ddns.sh, edit crontab to update IP periodically.

  sudo crontab -e 
  *   */3   *   *   *   /usr/bin/ddns.sh 

Then the script runs every 3 hours.
JΓΊnes's configuration and scripts WebDAV β€” Updated on 2017/08/24 22:06


Disable unused settings

Disable suspend mode

Disable / Ignore suspend mode of laptop for lasting online even when LCD lid is closed.

Edit /etc/systemd/logind.conf

 #HandlePowerKey=poweroff  
 #HandleSuspendKey=suspend
 #HandleHibernateKey=hibernate
 #HandleLidSwitch=suspend

Comment out the items that you wish to edit. HandlePowerKey is for when pressing Power key. HandleSuspendKey is for suspend key (if exists). HandleHibernateKey is for hibernation key. And HandleLidSwitch is for lid panel.

 #HandlePowerKey=poweroff  
 #HandleSuspendKey=suspend
 #HandleHibernateKey=hibernate
 HandleLidSwitch=ignore

Disable Hardware Acceleration

/etc/X11/xorg.conf.d/disable-gpu.conf
 
Section "Extensions"
    Option "GLX" "Disable"
EndSection

Disable power wireless off

 sudo iwconfig wlan0 power off 

Disable Bluetooth service

vi /etc/bluetooth/main.conf

Edit the line with AutoEnable with false

AutoEnable = false

A more radical way is to either stop the bluetooth service

sudo systemctl stop bluetooth.service

Or even more radical is to disable it permanently

sudo systemctl disable bluetooth

Debugging service

  sudo service stop sshd   # ssd daemon for example 
  /usr/sbin/sshd -d       # need to specify full path 

Find problem from messages in debugging mode.


Configure locales

 sudo dpkg-reconfigure locales

Deselect unused locales and save them.


Install Services

Nextcloudβ„’

Nextcloud 101 β€” Nextcloud user's Guides


Upgrade & Maintenance

Major LTS upgrade

Upgrade from 18.04 LTS to 20.04 LTS (Focal Fossa)

Official Guide on upgrade How to upgrade from Ubuntu 18.04 LTS to 20.04 LTS today β€” Updated on 2020/07/11 03:40

Upgrade on the command line

Update all repository for packages, which already installed on the system.

 sudo apt update && sudo apt dist-upgrade -y && sudo apt autoremove 

Upgrade with major LTS with

 sudo do-release-upgrade -d 

Follow the procedures and finish.

Some third party entries in your sources.list were disabled. You can 
re-enable them after the upgrade with the 'software-properties' tool 
or your package manager. 

Fetch error during update

Error during update β€” Failed to fetch or something like that

sudo apt-get clean
sudo rm -vf /var/lib/apt/lists/*
sudo rm -vf /var/lib/apt/lists/partial/*
sudo apt-get update

Run update command several times until finishing fetches


Upgrade php 7.x

Append additional source for php7.x latest,

sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
wget -q https://packages.sury.org/php/apt.gpg -O- | sudo apt-key add -
echo "deb https://packages.sury.org/php/ `lsb_release -cs` main" | sudo tee /etc/apt/sources.list.d/php.list

Append Nginx mainline packages

sudo add-apt-repository ppa:ondrej/nginx-mainline

Update source lists

sudo apt-get update
Reading package lists... Done
E: The method driver /usr/lib/apt/methods/https could not be found.
N: Is the package apt-transport-https installed?
E: Failed to fetch https://packages.sury.org/php/dists/stretch/InRelease
E: Some index files failed to download. They have been ignored, or old ones used instead.

When it comes to this errors, install additional packages for update,

sudo apt-get install ca-certificates apt-transport-https

Install php with latest version

sudo apt-get install php7.2 php7.2-cli php7.2-common php7.2-opcache php7.2-curl php7.2-mbstring php7.2-mysql php7.2-zip php7.2-xml

To verify the installation is completed run the following command:

php -v

Install & upgrade Nginx

Install the prerequisites:

sudo apt install curl gnupg2 ca-certificates lsb-release

To set up the apt repository for stable nginx packages, run the following command:

echo "deb http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

If you would like to use mainline nginx packages, run the following command instead:

echo "deb http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

Next, import an official nginx signing key so apt could verify the packages authenticity:

curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -

Verify that you now have the proper key:

sudo apt-key fingerprint ABF5BD827BD9BF62

The output should contain the full fingerprint 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 as follows:

pub   rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
      573B FD6B 3D8F BC64 1079  A6AB ABF5 BD82 7BD9 BF62
uid   [ unknown] nginx signing key <signing-key@nginx.com>

To install nginx, run the following commands:

sudo apt update
sudo apt install nginx

Upgrade mariadb

Setting up MariaDB Repositories

Select Disto, Release and Version and follow the instruction

sudo apt-get install software-properties-common
sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] https://ftp.harukasan.org/mariadb/repo/10.5/ubuntu focal main'

Once the key is imported and the repository added you can install MariaDB 10.5 from the MariaDB repository with:

sudo apt update
sudo apt install mariadb-server

Check service is working correctly and installed version.

sudo mysql -uroot -p

Alternatively, edit /etc/apt/sources.list or add repository with command line.

# MariaDB 10.5 repository list - created 2020-08-31 04:34 UTC
# http://downloads.mariadb.org/mariadb/repositories/
deb [arch=amd64] https://ftp.harukasan.org/mariadb/repo/10.5/ubuntu focal main
deb-src https://ftp.harukasan.org/mariadb/repo/10.5/ubuntu focal main

If you need debug packages, add the debug component to your sources.list with:

sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] https://ftp.harukasan.org/mariadb/repo/10.5/ubuntu focal main/debug'

MariaDB debug packages will now show up when searching for 'mariadb' with apt and are distinguished by the `-dbgsym` suffix. Debug packages are generally only needed during development and usually should not be installed unless you know that you need them.


Basic commands 101

Rico's cheatsheets – first glimpse on Linux commands

rm

  rm -R			\\ Remove directory, Recursively
  rm -i			\\ Remove with confirmation 
  rm -f			\\ Force deletion of Files Directories 
  rm -v			\\ Show information of deletion process, Verbosely 

ufw (firewalls)

  sudo ufw app list		\\ show app list by firewall 
  sudo ufw allow OpenSSH	\\ allow OpenSSH 
  sudo ufw enable  
  sudo ufw status  

udevadm

To retrieve hardware information such as serial number of product,

  sudo udevadm info --query=all --name=/dev/sda

find string(s) in files

find /path/to/files/ -type f | xargs grep -n 'string_to_search'

[output to file]

visible in terminal visible in file
syntax stdout stderr stdout stderr existing file
> no yes yes no overwrite
Β» no yes yes no append
2> yes no no yes overwrite
2Β» yes no no yes append
&> no no yes yes overwrite
&Β» no no yes yes append
| tee yes yes yes no overwrite
| tee -a yes yes yes no append
|& tee yes yes yes yes overwrite
|& tee -a yes yes yes yes append
command > output.txt   

The standard output stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, it gets overwritten.

command >> output.txt

The standard output stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

command 2> output.txt

The standard error stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, it gets overwritten.

command 2>> output.txt

The standard error stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

command &> output.txt

Both the standard output and standard error stream will be redirected to the file only, nothing will be visible in the terminal. If the file already exists, it gets overwritten.

command &>> output.txt

Both the standard output and standard error stream will be redirected to the file only, nothing will be visible in the terminal. If the file already exists, the new data will get appended to the end of the file..

command | tee output.txt

The standard output stream will be copied to the file, it will still be visible in the terminal. If the file already exists, it gets overwritten.

command | tee -a output.txt

The standard output stream will be copied to the file, it will still be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

(*)

Bash has no shorthand syntax that allows piping only StdErr to a second command, which would be needed here in combination with tee again to complete the table. If you really need something like that, please look at β€œHow to pipe stderr, and not stdout?” on Stack Overflow for some ways how this can be done e.g. by swapping streams or using process substitution.

command |& tee output.txt

Both the standard output and standard error streams will be copied to the file while still being visible in the terminal. If the file already exists, it gets overwritten.

command |& tee -a output.txt

Both the standard output and standard error streams will be copied to the file while still being visible in the terminal. If the file already exists, the new data will get appended to the end of the file.