>  cvidon@student.42.fr

#       Born2Reboot

#INDEX
------
##  Help
##  Misc
##  Server
###     VM
###     Install
###     Partitioning
###     Comfort
###     Sudoers
###     UFW
###     SSH
###     SSH Connection
###     Password Policy
###     Update Passwords
###     Groups and Users
###     Crontab Monitoring
##  LLMP
###     Lighttpd
###     MariaDB
###     PHP
###     WP
###     IPFS

##  Help

> definition
> precision.
<variable_placeholder>
->Select/Click -able
# root
$ commandline
- remove text
+ insert text
> change text
https://www.external_link

##  Misc

* Errors:

Fix the startup error '*ERROR* Failed to send host log message.':
    $ sudo /etc/default/grub
    - GRUB_CMDLINE_LINUX_DEFAULT=""
    + GRUB_CMDLINE_LINUX_DEFAULT="quiet nomodeset"
    $ sudo update-grub

* Services:

List running services:
    $ sudo systemctl status
List services and their status:
    $ sudo service --status-all
List all services status:
    $ sudo systemctl

* Misc:

Check updates:
    $ apt update
    $ apt upgrade
    $ apt full-upgrade
    $ apt autoremove
    $ apt autoclean

Network ports usage documentation:
    $ vi /etc/services

Check who is logged in and what they are doing:
    $ w

Cycle console ttys:
    Alt + Left/Right
    Ctrl + Alt + <f1_to_f6>

Change hostname:
    $ sudo hostnamectl set-hostname <new_name>
    $ sudo vi /etc/hosts
    > 127.0.1.1   <new_name>
    $ sudo reboot
Check hostname:
    $ hostnamectl

##  Server

###     VM

Download VirtualBox
Download Debian latest stable release:
https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/

 VirtualBox ->New
 Name: debian-server
 Machine Folder: somewhere
 Version: Debian (64-bit)
 ->Continue
    1024 MB
 ->Continue
    8 GB
    VDI (VirtualBox Disk Image)
    Dynamically allocated
 ->Create

 VirtualBox ->Settings ->Storage
 Controller: IDE ->💿 Empty
 Optical Drive: ->💿
    debian-11.1.0-amd64-netinst.iso
 ->OK

 VirtualBox ->Start

Be able to use CMD-TAB switch between host and VM windows:
 VirtualBox ->Input ->Keyboard/Keyboard Settings
 Auto Capture Keyboard OFF

Screen size:
 VirtualBox ->View ->Virtual Screen: 200%

###     Install

 ->Install
 Hostname: cvidon42
 Domain name:
 Root password: toor
 Full name for the new user: clement
 Username for your account: cvidon
 Choose a password for the new user: resu
 Select your time zone: Central

###     Partitioning

-----[MANDATORY]-----

 Partitioning method: …encrypted LVM
 Partitioning scheme: Separate /home partition
 Encryption passphrase: ksid
 Amount of volume group to use for guided partitioning: max
 Finish partitioning:
 ->#1 ->4.0 GB ->ext4 /home
 ->#2 ->3.0 GB ->ext4 /
 ->#3 ->1.0 GB ->swap swap

-----[BONUS]------

Partitioning method: Manual
 ->SCSI1 (0,0,0) (sda) - 8.6 GB ATA VBOX HARDDISK

Create /boot primary partition:
> Bootable partition that it contains the operating system.
 ->FREE SPACE ->Create a new partition
 New partition size: 500M
 ->Primary ->Beginning
 Mount point: /boot
 ->Done setting up the partition

Set the rest as logical partition:
> Portion of a computer's hardware that is set aside and virtualised
> as an additional computer.
 ->FREE SPACE ->Create a new partition
 New partition size: max ->Logical
 Mount point: Do not mount it ->Done setting up the partition

Encrypt it:
 ->Configure encrypted volumes ->Create encrypted volumes
 -> 2nd partition (the bigger one) ->Continue
 ->Finish
 Encryption passphrase: ksid

Create the logical partitions:
 ->Configure the Logical Volume Manager ->Create volume group
 Volume group name: LVMGroup
 -> 1st partition (the bigger one) ->Done setting up the partition

 ->Create logical volume ->LVMGroup
 Logical volume name: root
 Logical volume size: 2G

 ->Create logical volume ->LVMGroup
 Logical volume name: swap
 Logical volume size: 1024M

 ->Create logical volume ->LVMGroup
 Logical volume name: home
 Logical volume size: 1G

 ->Create logical volume ->LVMGroup
 Logical volume name: var
 Logical volume size: 1G

 ->Create logical volume ->LVMGroup
 Logical volume name: srv
 Logical volume size: 1G

 ->Create logical volume ->LVMGroup
 Logical volume name: tmp
 Logical volume size: 1G

 ->Create logical volume ->LVMGroup
 Logical volume name: var-log
 Logical volume size: 1056M

 ->Finish

 ->#1 ->Use as:… ->Ext4 ->Mount point ->home
 ->#1 ->Use as:… ->Ext4 ->Mount point ->/
 ->#1 ->Use as:… ->Ext4 ->Mount point ->srv
 ->#1 ->Use as:… ->swap ->swap
 ->#1 ->Use as:… ->Ext4 ->Mount point ->tmp
 ->#1 ->Use as:… ->Ext4 ->Mount point ->var
 ->#1 ->Use as:… ->Ext4 ->Moun… ->Enter Manually->/var/log

 ->Finish…

------------------

 Scan extra installation media: No
 Choose software to install: uncheck all
 Device for boot loader installation: /dev/sda …

Log in as 'root'.
Check partitioning:
    # lsblk

* Partitions and hard disks:
> /dev/hda is the 'master IDE' (Integrated Drive Electronics)
> drive on the primary 'IDE controller'. Partitions of this disk are
> named hda1, hda2. A 'second IDE' device would be named hdb.  (The
> motherboard has two IDE connectors on which we plug the cables which
> can each accommodate 2 peripherals.
    IDE connector 0 -> master: /dev/hda -> slave: /dev/hdb
    IDE connector 1 -> master: /dev/hdc -> slave: /dev/hdd
> 'hda1' to 'hda4' will be primary partitions.
> 'hda5' to 'hda…' will be logical partitions (of an extended partition).
> An extended partition is a primary partition which itself
> contains another partition table.
http://stephane.boireau.free.fr/informatique/samba/samba/partitions_et_disques_durs.htm

> SCSI disks (Small Computer System Interface) will be same as above
> with a 's' dev/sda.
> The '/dev' contains all the peripherals (devices).

###     Comfort

Login as root.

Set time:
    # dpkg-reconfigure tzdata
Font size:
    # dpkg-reconfigure console-setup
Caps lock to Ctrl:
    # vi /etc/default/keyboard
    - XKBOPTIONS=""
    + XKBOPTIONS="ctrl:nocaps"
Apply now:
    # setupcon
Survive reboot:
    # dpkg-reconfigure keyboard-configuration

Check updates:
    # apt update
Install most useful packages:
    # apt install zsh vim tmux
    # apt install git wget curl
    # apt install man-db manpages-dev
    # apt install sudo

Set default editor:
    # update-alternatives --set editor /usr/bin/vim.basic

Add 'cvidon' to 'sudo' group:
    # usermod -aG sudo cvidon
    # groups cvidon
Login as 'cvidon':
    # su - cvidon

Change default Shell:
    $ chsh -s /bin/zsh
    $ zsh
    $ zsh
> And (q).

Import mini-conf:
    $ mkdir ~/Documents
    $ cd !$
    $ git clone https://github.com/clem9nt/mini-conf
    $ bash mini-conf/installer.sh
    $ source ~/.zshrc

###     Sudoers

Configure 'sudoers' group via 'mysudoers':
    $ sudo visudo -f /etc/sudoers.d/mysudoers
    + Defaults  secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
    + Defaults  passwd_tries=3
    + Defaults  badpass_message="Wrong password.  This incident will be reported."
    + Defaults  iolog_dir=/var/log/sudo/%{user}
    + Defaults  log_input,log_output
    + Defaults  requiretty

> Writing to sudoers.d/mysudoers instead of 'sudoers' is safer
> because 'sudoers' is under control of the distribution package
> manager and an upgrade could overwrite it.

> secure_path prevent any script to be executed with sudo unless
> it matches the secure path.
> requiretty prevents sudo from being used from daemons or
> other detached processes (cronjobs, web server plugins).

###     UFW

Install package:
    $ sudo apt update
    $ sudo apt install ufw
Enable UFW:
    $ sudo ufw enable

> UFW unit status is shown as active (exited) because it is a 'oneshot
> service'. Oneshot services are expected to take action and exit
> immediately, thus they are not really services, no running processes
> remain.

Disable UFW dupplicate logging /var/log/{kern.log,syslog} and reduce
it to /var/log/ufw.log:
    $ sudo vi /etc/rsyslog.d/20-ufw.conf
    > & stop

###     SSH

> SSH (Secure Shell or Secure Socket Shell), allows to securely
> connect to a remote computer or a server by using a text based
> interface. OpenSSH is an open source implementation of the
> protocol, it works with a client (SSH) and a server (sshd).

Install package:
    $ sudo apt update
    $ sudo apt install openssh-server
Check that SSH is active and enabled:
    $ sudo service ssh status

Change default port:
    $ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
    $ sudo vi /etc/ssh/sshd_config
    > Port 4242
    > PermitRootLogin no

Set a firewall exceptions to port 4242:
    $ sudo ufw allow 4242/tcp
Check firewall exceptions:
    $ sudo ufw status

Restart the service:
    $ sudo service ssh restart

###     SSH Connection

Port forwarding:
MyVM ->Settings ->Network
 Attached to: NAT
 ->Advanced ->Port Forwarding
 ->(+) Name:SSH| Host Port:4242| Guest Port:4242

Check port 4242 tcp connection:
    $ sudo ss -nat | grep 4242

Connect to guest from host:
    $ ssh -p 4242 cvidon@127.0.0.1

> A good practice is to disable password and only allow connections
> that come with a trusted public key.

SFTP (Secure File Transfer Protocol):

Connect to guest from host:
    $ sftp -P 4242 cvidon@127.0.0.1
Put, get, rm a file:
    sftp> put <file>
    sftp> get <file>
    sftp> rm  <file>

###     Password Policy

Install package:
    $ sudo apt install libpam-pwquality

> pam_pwquality provides common functions for password quality
> checking, scoring them on their apparent randomness.

Configure password policy:
    $ sudo cp /etc/pam.d/common-password /etc/pam.d/common-password.bak
    $ sudo vi /etc/pam.d/common-password

At the end of the line matching 'requisite  pam_pwquality.so' after
'retry=3' and space separated, add:
    > minlen=10
      ocredit=-1 lcredit=-1 ucredit=-1 dcredit=-1
      maxrepeat=3
      reject_username
      difok=7
      enforce_for_root

> Strong password policy:
> - 10 chars long minimum.
> - At least 1 special char, 1 lower case, 1 upper case, 1 number.
> - Not more than 3 consecutive identical chars.
> - Doesn't include username.
> - Doesn't include more than 7 chars from the former password
> (can't apply to root because its former password aren't preserved)
> - Previous rules apply to all users and root.

Configure password expiration:
    $ sudo cp /etc/login.defs /etc/login.defs.bak
    $ sudo vi /etc/login.defs
    > PASS_MAX_DAYS 30
    > PASS_MIN_DAYS 2
    > PASS_WARN_AGE 7
> Expire every 30 days.
> At least 2 days between two password modifications.
> Notify 7 days before a password expiration.

Apply this parameters to existing users:
PASS_MIN_DAYS 2:
    $ sudo chage --mindays 2 <user>
PASS_MAX_DAYS 30:
    $ sudo chage --maxday 30 <user>
PASS_WARN_AGE 7:
    $ sudo chage --warndays 7 <user>

Check password policy:
    $ chage -l <user>

###     Update Passwords

Change LUKS passphrase:
Find UUID of the drive:
    $ cat /etc/crypttab
Find ID of the drive:
    $ sudo blkid | grep <some_UUID_chars> | cut -d : -f 1
Add a passphrase:
    $ sudo cryptsetup luksAddKey <ID>
Remove a passphrase:
    $ sudo cryptsetup luksRemoveKey <ID>
> Be careful to keep at least one passphrase before removing the
> last one.

> LUKS (Linux Unified Key Setup) is a disk encryption standard.

Change users password:
    $ sudo passwd <user>

###     Groups and Users

> $ usermod modifies or changes any attributes of an 'already
> existing' user.  (unlike adduser used to 'create' an user account)
> -G specifies the list of supplementary groups,-a to 'append'
> instead of 'replaces' the user's group with the supplementary ones.

> $ getent get a databases text file entries (ie. group
> database's entries for user and sudo).

List users:
    $ cut -d: -f1 /etc/passwd

Create 'user42' group:
    $ sudo groupadd user42
Check group creation:
    $ sudo getent group user42

Set a 'clem' to a 'user42':
    $ sudo usermod -aG user42 clem
Check clem's groups:
    $ sudo groups clem

> /etc/passwd columns:
> username:password:uid:gid:comment:home_directory:shell_used
> An 'x' in the password column means that the password is encrypted
> and to be found in '/etc/shadow'.

Delete <group>:
    $ delgroup <group>
Delete <user> (and all its files):
    $ deluser --remove-all-files <user>

###     Crontab Monitoring

Install package:
    $ sudo apt update
    $ sudo apt install net-tools

Create 'monitoring.sh':
    $ sudo vi /usr/local/sbin/monitoring.sh
    + #!/bin/bash
    + arc=$(uname -a)
    + pcpu=$(grep "physical id" /proc/cpuinfo | sort | uniq | wc -l)
    + vcpu=$(grep "^processor" /proc/cpuinfo | wc -l)
    + fram=$(free -m | grep Mem: | awk '{print $2}')
    + uram=$(free -m | grep Mem: | awk '{print $3}')
    + pram=$(free    | grep Mem: | awk '{printf("%.2f"), $3/$2*100}')
    + fdisk=$(df -Bg | grep '^/dev/' | grep -v '/boot$' | awk '{ft += $2} END {print ft}')
    + udisk=$(df -Bm | grep '^/dev/' | grep -v '/boot$' | awk '{ut += $3} END {print ut}')
    + pdisk=$(df -Bm | grep '^/dev/' | grep -v '/boot$' | awk '{ut += $3} {ft+= $2} END {printf("%d"), ut/ft*100}')
    + cpul=$(top -bn1 | grep '^%Cpu' | cut -c 9- | xargs | awk '{printf("%.1f%%"), $1 + $3}')
    + lb=$(who -b | awk '$1 == "system" {print $3 " " $4}')
    + lvmt=$(lsblk -o TYPE | grep "lvm" | wc -l)
    + lvmu=$(if [ $lvmt -eq 0 ]; then echo no; else echo yes; fi)
    +
    + # net-tools required:
    + ctcp=$(cat /proc/net/tcp | wc -l | awk '{print $1-1}' | tr '' ' ')
    + ulog=$(users | wc -w)
    + ip=$(hostname -I)
    + mac=$(ip link show | awk '$1 == "link/ether" {print $2}')
    +
    + # journalctl can run because the script exec from sudo cron
    + cmds=$(journalctl _COMM=sudo | grep COMMAND | wc -l)
    +
    + echo "  #Architecture: $arc
    +     #CPU physical: $pcpu
    +     #vCPU: $vcpu
    +     #Memory Usage: $uram/${fram}MB ($pram%)
    +     #Disk Usage: $udisk/${fdisk}Gb ($pdisk%)
    +     #CPU load: $cpul
    +     #Last boot: $lb
    +     #LVM use: $lvmu
    +     #Connexions TCP : $ctcp ESTABLISHED
    +     #User log: $ulog
    +     #Network: IP $ip ($mac)
    +     #Sudo: $cmds cmd"

Check script output:
    $ bash /usr/local/sbin/monitoring.sh
Configure a root cronjob that run the script every 10min:
    $ sudo crontab -u root -e
    + */10 * * * * bash /usr/local/sbin/monitoring.sh | wall
https://crontab.guru/#*/10_*_*_*_*/

Configure a cronjob:
Check service status:
    $ sudo systemctl status cron
Check script executions:
    $ sudo grep -a "monitoring.sh" /var/log/syslog

##  LLMP

> LLMP Stack: Linux Lighttpd MySQL and PHP.

###     Lighttpd

Install package:
    $ sudo apt install lighttpd
Check that Lighty is active and enabled:
    $ sudo systemctl status lighttpd

> Lighttpd (pronounced lighty) is a fast, secure, flexible and
> open source web server optimized for high performance environments.
> Suited to handle loads of traffic with minimal memory consumption.

Set a firewall exceptions to port 80:
    $ sudo ufw allow 80/tcp
Check firewall exceptions:
    $ sudo ufw status

Check Lighttpd welcome page from the host web browser:

Port forwarding:
MyVM ->Settings ->Network
 Attached to: NAT
 ->Advanced ->Port Forwarding
 ->(+) Name:WWW| Host Port:80| Guest Port:80

Check that port 80 is open:
    $ sudo ss -nat | grep 80

Visit Lighttpd welcome page at the address 127.0.0.1
from the host web browser.

###     MariaDB

Install package:
    $ sudo apt install mariadb-server
Check that MariaDB is active and enabled:
    $ sudo systemctl status mariadb

> MariaDB is a DBMS (Relational Database Management System) that
> is a fork and an alternative to MySQL (that uses some proprietary
> code).  https://kinsta.com/blog/mariadb-vs-mysql/

Configure MariaDB security settings:
    $ sudo mysql_secure_installation
 Enter current password for root (enter for none): enter
 Switch to unix_socket authentication? n
> 'unix_socket' auth. plugin is a passwordless security mechanism.
 Set root password? n
 Remove anonymous users? Y
 Disallow root login remotely? Y
 Remove test database and access to it? Y
 Reload privilege tables now? Y

Log in to MariaDB console:
    $ sudo mysql
> Same as '$ sudo mariadb'.

Create 'clem-db' new database:
    mysql> CREATE DATABASE clem_db;

Create 'clem' database user identified by 'melc' password:
    mysql> CREATE USER clem@localhost IDENTIFIED BY 'melc';
Give full privileges on 'clem_db' to 'clem':
    mysql> GRANT ALL ON clem_db.* TO clem@localhost WITH GRANT OPTION;

Makes those changes take effect (without reload/restart MariaDB):
    mysql> FLUSH PRIVILEGES;

Check all users and host name where they are allowed to login:
    mysql> SELECT host, user FROM mysql.user;
Exit MariaDB shell: exit

Log into MariaDB server with the new user:
    $ sudo mysql -u clem -p

Check which databases user has access to:
    mysql> SHOW DATABASES;
Exit MariaDB shell: exit

###     PHP

Install packages:
    $ sudo apt install php-cgi php-mysql

> php-mysql package provides SQL modules for PHP.

> CGI (Common Gateway Interface) is a protocol used by most Web
> servers to capture and communicate session information to and from
> server-side processes. It connects the front and the back end to
> make web pages dynamic and interactive.
http://www.uvm.edu/~hag/naweb96/zshoecraft.html

> PHP CGI is the legacy way of running applications, it goes with very
> poor performance for busier websites: each time we load a page,
> PHP needs read php.ini, set its settings, loads all its extensions,
> and finally start work parsing the script.
> - One key advantage to using the CGI version is that PHP reads its
>   settings every time you load a page.  With PHP running as a module,
>   any changes you make in the php.ini file do not kick in until we
>   restart our web server, so the CGI version is preferable if we testing
>   new settings and want to see instant responses.
> - Another benefit of CGI is that it keeps the code execution
>   separate from the web server, increasing the security.

> PHP-FPM (FastCGI Process Manager) is an alternative that allows
> a website to handle strenuous loads. Modern, optimized, robust for
> busier websites and low resources consumption but lower security
> than CGI and require more complicated configuration than CGI.
https://www.basezap.com/difference-php-cgi-php-fpm/

Enable FastCGI Lighttpd modules:
    $ sudo lighty-enable-mod fastcgi
    $ sudo lighty-enable-mod fastcgi-php
Restart server:
    $ sudo service lighttpd force-reload

###     WP

Download WP to /var/www/html:
    $ sudo wget http://wordpress.org/latest.tar.gz
Extract and install content:
    $ sudo tar xzvf latest.tar.gz
    $ sudo cp -r wordpress/* /var/www/html
Cleanup:
    $ sudo rm -rf latest.tar.gz wordpress

Reference 'clem_db' and 'clem' into WP config:
    $ sudo cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php
    $ sudo vi /var/www/html/wp-config.php
    > define( 'DB_NAME', 'clem_db' );
    > define( 'DB_USER', 'clem' );
    > define( 'DB_PASSWORD', 'melc' );

Visit localhost from the host web browser to see the WP default page.

###     IPFS

Download GO:
    $ curl -O https://dl.google.com/go/go1.17.5.linux-amd64.tar.gz
Check the hash:
    $ sha256sum go1.17.5.linux-amd64.tar.gz
    https://go.dev/dl/

Install:
    $ sudo tar -C /usr/local -xzf go1.17.5.linux-amd64.tar.gz

Update zsh env:
    $ echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee -a ~/.zprofile
    $ echo 'export GOPATH="$HOME/go"' | sudo tee -a ~/.zprofile
    $ echo 'PATH="$GOPATH/bin:$PATH"' | sudo tee -a ~/.zprofile
Source zprofile:
    $ source ~/.zprofile

Check installation:
    $ go version

Download IPFS:
    $ go install github.com/ipfs/ipfs-update@latest
Check updates:
    $ ipfs-update versions
Update to the latest version:
    $ ipfs-update install v?.??.?

Increase maximum buffer size (from 300k to to 2500k):
    $ sudo sysctl -w net.core.rmem_max=2500000
Initialize IPFS:
    $ ipfs init --profile server

Change IPFS repo size (default 10GB):
    $ ipfs config Datastore.StorageMax 50MB

Create a service to make sure IPFS is running all the time:
    $ sudo vi /etc/systemd/system/ipfs.service
    > [Unit]
    > Description=IPFS Daemon
    > [Service]
    > Type=simple
    > ExecStart=/home/cvidon/go/bin/ipfs daemon --enable-gc
    > Group=cvidon
    > Restart=always
    > Environment="IPFS_PATH=/home/cvidon/.ipfs"
    > [Install]
    > WantedBy=multi-user.target

Start and enable IPFS service:
    $ sudo systemctl daemon-reload
    $ sudo systemctl enable ipfs
    $ sudo systemctl start ipfs
Check that IPFS is active and enabled:
    $ sudo systemctl status ipfs

Set a firewall exceptions to port 4001:
    $ sudo ufw allow 4001/tcp
Check firewall exceptions:
    $ sudo ufw status

Port forwarding:
MyVM ->Settings ->Network
 Attached to: NAT
 ->Advanced ->Port Forwarding
 ->(+) Name:IPFS| Host Port:4001| Guest Port:4001

Check port 4001 tcp connection:
    $ sudo ss -nat | grep 4001

https://docs.ipfs.io/how-to/observe-peers/
See whose peer we are directly connected to:
    $ ipfs swarm peers
Print bandwidth information.
    $ ipfs stats bw