====== General info on Debian ======
{{:playground:boo_the_bunny_36.png?nolink&250|}}
----
===== 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 {{mdi>debian?2x}} 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"
* ''-o'': Save the private-key using the new OpenSSH format
* ''-a'': KDF (Key Derivation Function) rounds. Higher numbers result in slower passphrase verification, increasing the resistance to brute-force password cracking should the private-key be stolen.
* ''-C'': An option to specify a comment
---
==== 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 [[https://google.com/domains|Google Domains]], then update IP using **ddclient**.[[https://support.google.com/domains/answer/6147083|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. --- [[:debian_common#google_domains_with_ddclient|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(tm) 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.
.Cloudflare API v1 not available any more
curl https://www.cloudflare.com/api_json.html \
-d 'a=rec_load_all' \
-d 'tkn=8afbeYOUR0API0KEY0INdCLOUDFLARE0' \
-d 'email=YOU@DOMAIN.COM' \
-d 'z=DOMAIN.COM'
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 [[https://www.cloudflare.com/a/profile|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 [[http://jsonviewer.stack.hu/|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.
.Cloudflare API v1 (not used any more)
#!/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 https://www.cloudflare.com/api_json.html \
-d 'a=rec_edit' \
-d 'tkn=8afbeYOUR0API0KEY0INdCLOUDFLARE0' \
-d 'email=YOU@DOMAIN.COM' \
-d 'z=DOMAIN.COM' \
-d 'id=rec_id_FROMABOVE' \
-d 'type=A' \
-d 'name=DDNS.DOMAIN.COM' \
-d 'ttl=1' \
-d "content=$NEW_IP"
echo $NEW_IP > /var/tmp/current_ip.dat
fi
#!/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. \\
[[https://meson.ml/2vJ5wOm|JΓΊnes's configuration and scripts]] {{fa>folder-open?color=#FFDF00}} 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β’ ====
[[os_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 [[https://meson.in/2ALsTwg|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
To install nginx, run the following commands:
sudo apt update
sudo apt install nginx
----
==== Upgrade mariadb ====
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 ====
{{fa>terminal?size=24&color=#AABBCC}} [[https://devhints.io/|Rico's cheatsheets]] -- first glimpse on {{fa>linux?color=#a80030}} **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.
----