> 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