====== 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. ----