Comandi di base e configurazione iniziale

Questa guida assume che Linux (Ubuntu o Debian) sia disponibile come macchina remota (attraverso servizi come digital oceans, oppure aruba cloud) oppure che giri come macchina virtuale (VMware).

Nel caso di una macchina locale la modalità di rete utilizzata è NAT, con macchina host Windows 11.

La guida è compatibile anche se usi linux su Virtualbox, l'unica differenza è come fare il port forwarding

Port Forwarding

Recperare l'ip della macchina virtuale. Da dentro oracle linux eseguire il comando ip a. Nel mio caso l'ip della macchina è 192.168.86.128

Dalla interfaccia di WMware acedi alla voce di menu Edit / Virtual Network Editor

Clicca sul pulsante Change Settings

vmware change setings

Clicca sulla riga VMnet8 e poi su NAT settings

vmware nat setings

Cliccare sul tasto Add e impostare la regole seguendo come da immagine, modificando dove serve

vmware nat setings

L'immagine precedente imposta la reole per accedere alla macchina con ssh. Per accedere alla macchina posso usare il comando seguente, sostituendo il nome utente reale

ssh localhost@[nomeutente] -p 34522

VMWare Tools

Nel caso di VMWare è possibile installare i tools eseguendo i seguenti comandi

sudo apt install open-vm-tools open-vm-tools-desktop

Per controllare la versione dei tools installati

vmware-toolbox-cmd -v

Per rendere effettive le modifiche riavviare la macchina

sudo reboot

Comandi di sistema essenziali

Ecco i comandi che userai di più nella gestione quotidiana

# Aggiornare il sistema
sudo apt update
sudo apt upgrade

# Riavviare / spegnere
sudo reboot
sudo poweroff

# Informazioni sul sistema
uname -a
cat /etc/os-release
hostnamectl

# Gestione servizi (systemd)
sudo systemctl start   [servizio]
sudo systemctl stop    [servizio]
sudo systemctl restart [servizio]
sudo systemctl enable  [servizio]   # avvio automatico al boot
sudo systemctl disable [servizio]
sudo systemctl status  [servizio]

# Monitoraggio processi e risorse
top
htop          # più leggibile, installa con: sudo apt install htop
df -h         # spazio disco
free -h       # memoria RAM

Di seguito ti propongo una serie di programmi base di utilità generale

sudo apt install wget curl nano zip unzip htop dos2unix curl wget unzip p7zip

# per installare python 
sudo apt install python3 python3-pip

# per montare file system ntfs
sudo apt install ntfs-3g

Se stai usando un macchina cloud e devi creare il tuo utente puoi seguire questi comandi (da lanciare con root)


# aggiorna la macchina e poi installa sudo
apt update && apt install sudo

# Aggiungi l'utente scelto
adduser [nomeutente]

# aggiungi l'utente al gruppo sudo per eseguire comandi con sudo
usermod -aG sudo [nomeutente]

Impostare il timezone

Verifica che il tuo timezone sia corretto, e nel caso correggilo con i seguenti comandi

# Verificare
timedatectl

# Elencare i timezone disponibili (filtrando per Europa)
sudo timedatectl list-timezones | grep Europe

# Impostare Roma
sudo timedatectl set-timezone Europe/Rome

Gestione pachetti con APT

apt è il gestore di pacchetti di Ubuntu/Debian. Richiede privilegi di root sudo.

# Prima di installare o cercare pacchetti, aggiorna l'indice locale
sudo apt update

# per installare un programma
sudo apt install nome-pacchetto

# Per rimuove il pacchetto ma lascia i file di configurazione
sudo apt remove nome-pacchetto

# Per rimuove tutto, inclusa la configurazione:
sudo apt purge nome-pacchetto

# Dopo la rimozione, pulisce le dipendenze orfane:
sudo apt autoremove

Per vedere tutti i pacchetti installati:
sudo apt list --installed

Per filtrare per nome:
sudo apt list --installed | grep nome

Per cercare un pacchetto nei repository
sudo apt search nome-pacchetto

Per ottenere info di un pacchetto non ancora installato (dai repository):
sudo apt show nome-pacchetto

Per ottenere info di un pacchetto già installato:
sudo dpkg -s nome-pacchetto

Firewall (ufw)

ufw (Uncomplicated Firewall) è il frontend semplificato per iptables incluso in Ubuntu. Su Debian potrebbe non essere preinstallato.

# Verificare se ufw è installato
which ufw

# se non è installato lo puoi installare con 
sudo apt install ufw

# per vedere lo stato del firewall 
sudo ufw status
sudo ufw status verbose
sudo ufw status numbered

# per abilitare o isabilitare il firewall 
sudo ufw enable
sudo ufw disable

# l'impostazione di default è blocca tutto il traffico in entrata, permetti tutto in uscita:
sudo ufw default deny incoming
sudo ufw default allow outgoing

# per permettere connessioni in entrata posso usare diverse strategie
# posso usare il nome servizio
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https

# posso usare il numero porta, oppure porta e protoollo
sudo ufw allow 22
sudo ufw allow 8080
sudo ufw allow 443/tcp
sudo ufw allow 53/udp

# per bloccare connessioni 
sudo ufw deny 23
sudo ufw deny http
sudo ufw deny 8080/tcp

# per rimuovere una regola
sudo ufw delete allow 8080
sudo ufw delete allow http
sudo ufw delete deny 23

# In alternativa, elenca le regole numerate e rimuovi per numero:
sudo ufw status numbered
sudo ufw delete 3

Per fare reset (rimuove tutte le regole)
sudo ufw reset

SSH con autenticazione a chiave

Macchian remota cloud

L'autenticazione con chiave SSH è più sicura della password. Generi una coppia di chiavi sul tuo PC, copi la chiave pubblica sul server, e da quel momento ti connetti senza digitare la password.

Genera la coppia di chiavi (sul tuo PC)

# Sul tuo computer locale (Windows PowerShell / macOS / Linux)
ssh-keygen -t ed25519 -C 'mio-server-ubuntu'

# Ti chiede dove salvare (default: ~/.ssh/id_ed25519)
# e una passphrase opzionale (consigliata)

# Verrà creata:
#   ~/.ssh/id_ed25519       (chiave privata - non condividere mai!)
#   ~/.ssh/id_ed25519.pub   (chiave pubblica - questa va sul server)

Copiare la chiave pubblica sul server

# Metodo 1: ssh-copy-id (Linux/macOS)
ssh-copy-id -i ~/.ssh/id_ed25519.pub utente@ip-server

# Metodo 2: manuale (se ssh-copy-id non è disponibile)
# Sul server, crea la cartella .ssh e il file authorized_keys
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
# Incolla il contenuto del file id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys

Configura SSH sul server

sudo nano /etc/ssh/sshd_config

# Valori consigliati:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no    # disabilita login con password
PermitRootLogin no           # blocca login diretto come root

# Riavviare il servizio
sudo systemctl restart sshd

# Aprire la porta SSH nel firewall (se non già aperta)
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload

Crea il file config SSH locale (sul tuo PC). Il file ~/.ssh/config ti permette di definire alias e impostazioni per ogni server, evitando di digitare ogni volta ip, utente e chiave.

# ~/.ssh/config

Host ubuntu-cloud
    HostName 192.168.1.100
    User mario
    IdentityFile ~/.ssh/id_ed25519
    Port 22

Host debian-prod
    HostName 10.0.0.50
    User deploy
    IdentityFile ~/.ssh/id_ed25519_prod

Con questo file puoi connetterti semplicemente con ssh ubuntu-cloud

Macchina locale VMWare

Con VMware in modalità NAT e il port forwarding configurato, non ti connetti direttamente all'IP della VM ma all'IP dell'host Windows sulla porta mappata.

Nel mio caso specifico ho fatto port forwarding della porta 34522 dell'host, sulla porta 22 del guest. Quindi per colelgarmi alla machina posso fare come segue

# Da PowerShell o terminale Windows
ssh mario@127.0.0.1 -p 34522

# Oppure, se ti connetti da un altro PC sulla stessa rete
ssh mario@192.168.86.128 -p 34522

Se vuoi semplificare il comando, aggiungi una voce al file `~/.ssh/config` sul tuo PC Windows (`C:\Users\mario\.ssh\config`):

Host ubuntu-dev
    HostName 127.0.0.1
    User mario
    Port 34522

Da quel momento ti basta:

ssh ubuntu-dev

Git con GitHub e Bitbucket

Installazione e configurazione base

sudo apt install git openssh-client

# Configurazione globale
git config --global user.name 'NomeCognome'
git config --global user.email 'nome@esempio.it'

# Verificare
git config --list

Autenticazione con chiave SSH: Sia GitHub che Bitbucket supportano l'autenticazione tramite chiave SSH. Il processo è lo stesso per entrambi.

# Generare una chiave dedicata per GitHub
ssh-keygen -t ed25519 -C 'mario@esempio.it' -f ~/.ssh/id_github

# Generare una chiave dedicata per Bitbucket
ssh-keygen -t ed25519 -C 'mario@esempio.it' -f ~/.ssh/id_bitbucket

# Aggiungere le chiavi all'agente SSH
eval '$(ssh-agent -s)'
ssh-add ~/.ssh/id_github
ssh-add ~/.ssh/id_bitbucket

# Visualizzare la chiave pubblica da copiare su GitHub/Bitbucket
cat ~/.ssh/id_github.pub
cat ~/.ssh/id_bitbucket.pub

Copia il contenuto di ogni .pub nelle rispettive impostazioni SSH del tuo account:

  • GitHub → Settings → SSH Keys
  • Bitbucket → Personal settings → SSH keys

File config SSH per Git

# Aggiungere a ~/.ssh/config

Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_github

Host bitbucket.org
    HostName bitbucket.org
    User git
    IdentityFile ~/.ssh/id_bitbucket

Testa la connessione con

ssh -T git@github.com
ssh -T git@bitbucket.org

Cartelle condivise (VMware Shared Folders e Samba)

VMWare cartella condivisa

Come prima cosa impostare la cartella da condividere con VMware

Cartella shre vmware

Supponiamo di mondare la cartella condivisa d. Crea la cartella dentro /mnt

sudo mkdir -p /mnt/d
sudo chown $USER:$USER /mnt/d

Per montare la cartella host sulla cartella /mnt/d di linux lanciare il seguente comando da terminale

sudo vmhgfs-fuse .host:/ /mnt/d/ -o allow_other -o uid=1000

Oppure puoi montare tutto dentro la cartella /mnt

sudo vmhgfs-fuse .host:/ /mnt/ -o allow_other -o uid=1000

Per scoprire le cartelle condivise `.host:/` dentro usare

vmware-hgfsclient

Per montare all'avvio della macchina

# Use shared folders between VMWare guest and host
.host:/    /mnt/d/    fuse.vmhgfs-fuse    defaults,allow_other,uid=1000     0    0

Samba - condivisione cartelle con Windows

Samba permette di esporre cartelle Linux come share di rete accessibili da Windows. L'utente Samba avrà lo stesso nome dell'utente Linux (mario), con una password Samba separata.

Dato che uso NAT sulla macchiana virtuale devo fare il port forwarding di una porta della macchina windows sulla macchina linux

esempio 34545 -> 445

Procedo con l'installazione di samba

# Installare Samba
sudo apt install samba samba-common-bin

# Aprire il firewall
sudo ufw allow samba

Configura la share nel file smb.conf:

sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

sudo nano /etc/samba/smb.conf

[home-mario]
    comment = USB Shared Drive
    path = /mnt/d
    browseable = yes
    read only = no
    writable = yes
    create mask = 0777
    directory mask = 0777
    valid users = mario
    guest ok = no
    force user = mario
    force group = mario

Ora aggiungo la password all'utente samba

sudo smbpasswd -a mario

# Riavviare Samba
sudo systemctl restart smbd nmbd

Da Windows, apri Esplora File e digita nella barra degli indirizzi \\ip-del-server. Dato però che ho mappato la porta 34545 (host) sulla macchina 445 (linux) posso attaccare una directory di rete teporanea a windows specificando la porta di connessione.

net use T: \\127.0.0.1\home-mario   /TCPPORT:34545 /user:mario

# per togliere la cartella di rete
NET USE T: /DELETE

Inserisci come credenziali mario e la password impostata con smbpasswd. Poiché mario è proprietario della propria home, avrà già pieno accesso in lettura e scrittura senza bisogno di modificare permessi.

Stack LAMP

Apache

Installiamo Apache (httpd) e lo configuriamo per supportare WordPress, Laravel e phpMyAdmin.

Procediamo con l'installazione

# Installazione
sudo apt install apache2

# Abilitare e avviare
sudo systemctl enable --now apache2

Il file di configurazione di apache è /etc/apache2/apache2.conf

Inseriamo ServerName "localhost" sotto ServerRoot

sudo sed -i '/^#ServerRoot "\/etc\/apache2"/a ServerName localhost' /etc/apache2/apache2.conf

Inserisci index.php dentro file dir.conf

sudo sed -i 's/^DirectoryIndex.*/DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm/' /etc/apache2/mods-enabled/dir.conf

Nel file /etc/apache2/apache2.conf Assicurati di avere la direttiva come segue

sudo nano /etc/apache2/apache2.conf

<Directory /var/www/>
        ....
	AllowOverride All
        ....
</Directory>

Nel caso tu volessi utilizzare una porta diversa dalla 80 procedi a modificare il file /etc/apache2/ports.conf

sudo nano /etc/apache2/ports.conf

Listen 80   ->   Liste [portascelta]

Se attivo il firewall attiviare https e https

# se devo aprire una porta specifica
sudo ufw allow 8080

# se le porte sono quelle classiche 80/443
sudo ufw allow 'Apache Full'

# ricarico firewall
sudo ufw reload

Per rendere raggiungibile la directory /var/www/html modifichiamo il file 000-default.conf

sudo nano /etc/apache2/sites-available/000-default.conf

# se utilizzi una porta diversa dalla 80 modificare la porta
<VirtualHost *:80>

# aggiungere queste direttive
ServerName localhost
<Directory "/var/www/html">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
</Directory>

Abilitiamo e disabilitiamo alcuni moduli apache

# modulo multi processi
sudo a2dismod mpm_prefork
sudo a2enmod ssl headers mpm_event http2

Testiamo la configurazione e riavviamo apache

sudo apachectl configtest
sudo systemctl restart apache2

Per ogni sito crea un file di configurazione separato in /etc/apache2/sites-available

sudo nano /etc/apache2/sites-available/miosito.com.conf

# sostituisci $APACHE_PORT con la porta scelta
<VirtualHost *:$APACHE_PORT>
    ServerName miosito.com
    DocumentRoot /var/www/miosito.com

    <Directory /var/www/miosito.com>
        DirectoryIndex index.php index.html
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/miosito_error.log
    CustomLog ${APACHE_LOG_DIR}/miosito_access.log combined
</VirtualHost>

Per abilitare/disabilitare il sito appena aggiunto

# abilito sito creando link nella cartella /etc/apache2/sites-enabled/
sudo a2ensite miosito.com

# rimuovo il link e disabilito sito
sudo a2dissite miosito.com

Ora controlla che non ci siano errori e riavvia apache

sudo apache2ctl configtest
sudo systemctl restart apache2

Se sono in locale per comodità posso aggiungere il mio utente locale al gruppo www-data di apache

sudo usermod -aG www-data $USER

# riavvia macchina
sudo reboot

# controlla gruppi utente corrente
groups

D'ora in poi posso aggiornare i permessi della cartella /var/www nel seguente modo (di modo che possA modificare i files con il mio utente locale)

# Imposta permessi corretti
sudo chown www-data:www-data -R /var/www
sudo find /var/www -type d -exec chmod 775 {} \;
sudo find /var/www -type f -exec chmod 664 {} \;

Come utility creo uno script per aggiornare i permessi della cartella corrente, di modo che possa modificare senza problemi i files e cartelle con il mio utente locale

sudo nano /usr/local/bin/aggiorna_permessi_web.sh

#!/bin/bash

# Define user and group variables
WEB_USER="www-data"
WEB_GROUP="www-data"

# Script to update permissions recursively from current directory
# Usage: ./update_permissions.sh

# Check if running as root or with sudo
# if [ "$EUID" -ne 0 ]; then
#   echo "Please run as root or with sudo"
#   exit 1
# fi

# Set ownership recursively
echo "Updating ownership to $WEB_USER:$WEB_GROUP..."
sudo chown $WEB_USER:$WEB_GROUP -R .

# Set directory permissions (775)
echo "Setting directory permissions to 775..."
sudo find . -type d -exec chmod 775 {} \;

# Set file permissions (664)
echo "Setting file permissions to 664..."
sudo find . -type f -exec chmod 664 {} \;

echo "Permissions updated successfully!"

Rendi eseguibile lo script con

sudo chmod +x /usr/local/bin/aggiorna_permessi_web.sh

Per vedere i log di apache

sudo tail /var/log/apache2/error.log
sudo tail /var/log/php*-fpm.log

PHP 8.5

Usiamo il repository di Ondřej Surý per installare l'ultima versione di PHP 8.5

Per ubuntu lancia i seguenti comandi

sudo LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php # Press enter to confirm.
sudo apt update

Per Debian lancia i seguenti comandi

sudo apt-get update
sudo apt-get -y install lsb-release ca-certificates curl apt-transport-https

# Download and add the signing key
sudo curl -sSLo /tmp/debsuryorg-archive-keyring.deb https://packages.sury.org/debsuryorg-archive-keyring.deb
sudo dpkg -i /tmp/debsuryorg-archive-keyring.deb
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'

sudo apt-get update

Procediamo a installare php

sudo apt install imagemagick php8.5-{cli,fpm,common,bcmath,mysqli,bz2,curl,gd,gmp,intl,mbstring,readline,xml,xmlrpc,zip,imagick,intl,soap,xdebug}

Il file di configurazione di php dovrebbe essere /etc/php/8.5/fpm/php.ini

Aumenta i limiti di PHP per compatibilità con WordPress e upload di file grandi:

sudo nano /etc/php/8.5/fpm/php.ini

# Modificare questi valori:
max_execution_time = 300
max_input_time = 300
memory_limit = 512M
post_max_size = 1024M
upload_max_filesize = 1024M
date.timezone = Europe/Rome
short_open_tag = On

# per configurare cdebug aggiungi in fondo le seguenti righe
zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=localhost
xdebug.client_port=9003
xdebug.idekey=vscode
xdebug.log=/tmp/xdebug.log

Apri vscode e installa l'estensione PHP Debug. Inserisci un breakpoint nel codice e dal menu di sinistra clicca su "Run and Debug" e poi sul bottone "Liste for Xdebug". Prova a navigare la pagina con il browser, l'esecuzione si dovrebbe fermare sul breakpoint impostato

Abilitiamo alcuni moduli

sudo a2enmod ssl rewrite
sudo a2enmod proxy_fcgi setenvif 
sudo a2enconf php8.5-fpm 

Facciamo un veloce check e riavviamo

sudo apache2ctl configtest
sudo systemctl restart apache2 php8.5-fpm

Come debug aggiungiamo il file info.php alla cartella /var/www/html

echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php
sudo chown www-data:www-data /var/www/html/info.php

Verifica lo stato navigando su http://[server_ip]:[apache_porta]

per rimuovere una versione di php

# rimozione php 
sudo systemctl stop php*-fpm && sudo systemctl disable php*-fpm

# rimozione php e le dipendenze
sudo apt purge '^php8.4.*'
sudo apt clean && sudo apt autoclean && sudo apt autoremove

# rimozione file di config
sudo apt-get --purge remove php*
sudo rm -rf /etc/php/
sudo rm -rf /var/log/php*

# verifica che non ci siano più pacchetti installati
dpkg -l | grep php

# pulizia e riavvio apache2
sudo apt clean && sudo apt autoclean && sudo apt autoremove && sudo systemctl restart apache2

MariaDB

Lancia i seguenti comandi

sudo apt-get install apt-transport-https curl
sudo mkdir -p /etc/apt/keyrings
sudo curl -o /etc/apt/keyrings/mariadb-keyring.pgp 'https://mariadb.org/mariadb_release_signing_key.pgp'

Per Ubuntu 24.04 crea il file /etc/apt/sources.list.d/mariadb.sources con il seguente contenuto

sudo nano /etc/apt/sources.list.d/mariadb.sources

X-Repolib-Name: MariaDB
Types: deb
URIs: https://mirror.mva-n.net/mariadb/repo/12.2/ubuntu
Suites: noble
Components: main main/debug
Signed-By: /etc/apt/keyrings/mariadb-keyring.pgp

Per debian 13 crea invece il seguente file con il seguente contenuto

sudo nano /etc/apt/sources.list.d/mariadb.sources

X-Repolib-Name: MariaDB
Types: deb
URIs: https://mirror.mva-n.net/mariadb/repo/12.2/debian
Suites: trixie
Components: main
Signed-By: /etc/apt/keyrings/mariadb-keyring.pgp

Dopodichè procedi con l'installazione vera e propria

sudo apt update
sudo apt install mariadb-server

Abilitiamo all'avvio mariadb e verifichiamo lo status

sudo systemctl enable mariadb && sudo systemctl status mariadb

Avviamo il wizard di configurazione

sudo mariadb-secure-installation

# Rispondere così:
# Enter current password for root: [invio - vuota di default]
# Switch to unix_socket auth: N
# Change root password: Y  → inserisci una password sicura
# Remove anonymous users: Y
# Disallow root login remotely: Y
# Remove test database: Y
# Reload privilege tables: Y

Per rimuovere completamente mariadb

sudo systemctl stop mariadb && sudo systemctl disable mariadb
sudo apt purge mariadb*
sudo rm -rf /var/lib/mysql && sudo rm -rf /etc/mysql
sudo deluser mysql && sudo delgroup mysql

# nel caso cancellare anche
sudo rm /etc/apt/sources.list.d/mariadb.sources

Per gestire il database ti riporto alcune query di utilità generale

# Accedere a MariaDB
mariadb -u root -p

-- Creare un database e un utente
CREATE DATABASE miosito CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mario'@'localhost' IDENTIFIED BY 'password-sicura';
GRANT ALL PRIVILEGES ON miosito.* TO 'mario'@'localhost';
FLUSH PRIVILEGES;
EXIT;

phpMyAdmin

Scarichiamo l'ultima versione di phpMyAdmin e rendiamo il sito disponibile sotto http://localhost:[PORTA]/pma.

Procediamo con l'installazione

# scarico sorgenti
cd /var/www/html 
sudo wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz
sudo tar xzf phpMyAdmin-latest-all-languages.tar.gz
sudo mv phpMyAdmin-*-all-languages pma
sudo rm phpMyAdmin-latest-all-languages.tar.gz

# modifica file config
cd pma 
sudo mv config.sample.inc.php config.inc.php
sudo sed -i "s/\(\$cfg\['blowfish_secret'\] = '\)[^']*\(';\)/\11234567890abcdef1234567890abcdef\2/" config.inc.php

# per entrare direttamente senza password
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'password di root';
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['AllowNoPassword'] = true;

# permission
cd /var/www/html/pma
sudo chown -R www-data:www-data .
sudo find . -type d -exec chmod 775 {} \;
sudo find . -type f -exec chmod 664 {} \;

Wordpress

Supponiamo di creare uno script che gestisce la creazione di istanze wordpress sotto la cartella /var/www/html. La porta utilizzata è quella locale di apache overo la 34580

sudo nano /usr/local/bin/wp-manager.sh
#!/bin/bash
# wp-manager.sh - Gestione istanze WordPress
#
# Uso:
#   wp-manager.sh create <nome> <db_name>
#   wp-manager.sh delete <nome> <db_name>
#   wp-manager.sh list

WEB_ROOT="/var/www/html"
APACHE_PORT="13380"
DB_ROOT_PASSWORD="root"
URL_PREFIX="http://localhost"

create_wp() {
    SITE=$1
    DB_NAME=$2

    if [ -z "$SITE" ] || [ -z "$DB_NAME" ]; then
        echo "Uso: wp-manager.sh create <nome> <db_name>"
        exit 1
    fi

    SITE_DIR="$WEB_ROOT/$SITE"

    if [ -d "$SITE_DIR" ]; then
        echo "Errore: la cartella $SITE_DIR esiste già."
        exit 1
    fi

    echo ">>> Creazione database..."
    sudo mariadb -u root -p"$DB_ROOT_PASSWORD" -e "
        DROP DATABASE IF EXISTS $DB_NAME;
        CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    "

    echo ">>> Download WordPress..."
    cd /var/www/html
  
    if [ -f "latest.tar.gz" ]; then
        read -p "Il file latest.tar.gz esiste già. Vuoi riscaricarlo? [s/N] " risposta
        if [ "$risposta" = "s" ] || [ "$risposta" = "S" ]; then
            sudo rm -f latest.tar.gz
            sudo wget -q https://wordpress.org/latest.tar.gz
        fi
    else
        sudo wget -q https://wordpress.org/latest.tar.gz
    fi
    sudo tar -xzf latest.tar.gz
    sudo mv wordpress "$SITE"
    

    echo ">>> Configurazione wp-config.php..."
    sudo cp "$SITE/wp-config-sample.php" "$SITE/wp-config.php"
    sudo sed -i "s/database_name_here/$DB_NAME/"     "$SITE/wp-config.php"
    sudo sed -i "s/username_here/root/"              "$SITE/wp-config.php"
    sudo sed -i "s/password_here/$DB_ROOT_PASSWORD/" "$SITE/wp-config.php"

    # sostituzioni chiavi salt
    # Scarica le nuove chiavi
    NEW_KEYS=$(curl -s https://api.wordpress.org/secret-key/1.1/salt)

    # Individua la prima e l'ultima riga del blocco da sostituire nel file
    FIRST_LINE=$(grep -n "define( 'AUTH_KEY'" $SITE/wp-config.php | head -1 | cut -d: -f1)
    LAST_LINE=$(grep -n "define( 'NONCE_SALT'" $SITE/wp-config.php | head -1 | cut -d: -f1)

    # Sostituisce il blocco con le nuove chiavi usando sed
    sudo sed -i "${FIRST_LINE},${LAST_LINE}d" $SITE/wp-config.php
    sudo sed -i "$((FIRST_LINE - 1))r /dev/stdin" $SITE/wp-config.php <<< "$NEW_KEYS"


    # === 2) Inserimento delle costanti dopo define( 'WP_DEBUG', false ); ===
    EXTRA_DEFINES="define( 'WP_POST_REVISIONS', 5 );\ndefine( 'WP_AUTO_UPDATE_CORE', false );\ndefine( 'ALLOW_UNFILTERED_UPLOADS', true );"
    sudo sed -i "/define( 'WP_DEBUG', false );/a ${EXTRA_DEFINES}" $SITE/wp-config.php


    echo ">>> Permessi..."
    sudo chown -R www-data:www-data "$SITE"
    sudo chmod -R 775 "$SITE"
    sudo find "$SITE" -type d -exec chmod g+s {} \;

    # echo ">>> Ricarica Apache..."
    # sudo systemctl reload httpd

    echo ""
    echo "=== WordPress installato! ==="
    echo "  Cartella : $SITE_DIR"
    echo "  Database : $DB_NAME"
    if [ "$APACHE_PORT" = "80" ]; then
        echo "  URL      : $URL_PREFIX/$SITE"
    else
        echo "  URL      : $URL_PREFIX:$APACHE_PORT/$SITE"
    fi
}

delete_wp() {
    SITE=$1
    DB_NAME=$2

    if [ -z "$SITE" ] || [ -z "$DB_NAME" ]; then
        echo "Uso: wp-manager.sh delete <nomecartellasito> <nomedb>"
        exit 1
    fi

    SITE_DIR="$WEB_ROOT/$SITE"

    read -p "Sei sicuro di voler eliminare '$SITE'? (s/N): " CONFIRM
    if [[ "$CONFIRM" != "s" && "$CONFIRM" != "S" ]]; then
        echo "Operazione annullata."
        exit 0
    fi

    echo ">>> Rimozione cartella..."
    sudo rm -rf "$SITE_DIR"

    echo ">>> Rimozione database..."
    sudo mariadb -u root -p"$DB_ROOT_PASSWORD" -e "
        DROP DATABASE IF EXISTS $DB_NAME;
    "

}

list_wp() {
    echo "=== Istanze WordPress in $WEB_ROOT ==="
    echo ""
    FOUND=0
    for DIR in "$WEB_ROOT"/*/; do
        if [ -f "${DIR}wp-config.php" ]; then
            FOUND=1
            NAME=$(basename "$DIR")
            DB=$(grep "DB_NAME" "${DIR}wp-config.php" | grep -o "'[^']*'" | sed -n '2p' | tr -d "'")
            echo "  [$NAME]"
            echo "    Cartella : $DIR"
            echo "    Database : $DB"
            if [ "$APACHE_PORT" = "80" ]; then
                echo "    URL      : $URL_PREFIX/$NAME"
            else
                echo "    URL      : $URL_PREFIX:$APACHE_PORT/$NAME"
            fi
            echo ""
        fi
    done
    if [ $FOUND -eq 0 ]; then
        echo "  Nessuna istanza trovata."
    fi
}

case "$1" in
    create) create_wp "$2" "$3" ;;
    delete) delete_wp "$2" "$3" ;;
    list)   list_wp ;;
    *)
        echo "Uso:"
        echo "  wp-manager.sh create <nome> <db_name>"
        echo "  wp-manager.sh delete <nome> <db_name>"
        echo "  wp-manager.sh list"
        ;;
esac

Per rendere eseguibile lo script

sudo chmod +x /usr/local/bin/wp-manager.sh

Esempi d'uso dello script

wp-manager.sh create miosito miosito_db
wp-manager.sh delete miosito miosito_db
wp-manager.sh list

Dopo create, apri il browser su http://127.0.0.1:[PORTA]/miosito per completare l'installazione di WordPress.

Certificati SSL/TLS per i siti Apache

Usiamo Certbot con Let's Encrypt per i siti raggiungibili da internet. Let's Encrypt fornisce certificati gratuiti e riconosciuti da tutti i browser.

# Installare Certbot
sudo apt install certbot python3-certbot-apache

# Ottenere e installare il certificato (modifica automaticamente il virtual host)
sudo certbot --apache

# Certbot chiederà:
# - indirizzo email per notifiche di scadenza
# - accettazione termini di servizio
# - se redirigere HTTP → HTTPS automaticamente (consigliato: sì)

Il certificato viene rinnovato automaticamente. Puoi testare il rinnovo con:

sudo certbot renew --dry-run

Per controllare il rinnovo

sudo systemctl status certbot.timer

Per Elencare i certificati Let's Encrypt gestiti da Certbot

sudo certbot certificates

Per rimuovere un certificato Let's Encrypt:

# Revocare e cancellare il certificato
sudo certbot delete

# Dopo la cancellazione, rimuovere il virtual host HTTPS se non più necessario
sudo rm /etc/httpd/conf.d/miosito-ssl.conf

Per rinnovare i certificati posso aggiungere anche un job in cron

# sudo crontab -e
0 12 * * * /usr/bin/certbot renew --quiet