sabato 4 aprile 2020

[Linux] Generazione chiave privata e pubblica per l'accesso via SSH

Un'alternativa per l'accesso ad un computer remoto può essere ricorrere alla generazione di chiavi SSH.

(L'utilizzo può essere ad esempio quando si sta creando uno script e sul listato non si vogliono riportare password in chiaro)

Per la creazione delle suddette chiavi si procede nel seguente modo:

- Digitare dal terminale dell'host che deve accedere alla risorsa remota il seguente comando:
  
$ > ssh-keygen -t rsa

- Una volta eseguito, chiederà dove salvare la chiave privata, tipo:

$ >  Generating public/private rsa key pair.
 

       Enter file in which to save the key (/home/.ssh/id_rsa):

(se non si vuole cambiare percorso di salvataggio e nome chiave premere 'Invio')

- Verrà chiesto di inserire la parola di scambio, tipo

$ > Enter passphrase (empty for no passphrase):
 (se non si hanno particolari necessità premere 'Invio' per non inserirla)

- Ora verrà richiesto di confermare la parola di scambio inserita precedentemente (se si è premuto 'Invio' premerlo di nuovo per lasciare il campo vuoto)

$ > Enter same passphrase again:

- Verranno generate due chiavi, una privata ed una pubblica, come da messaggio:

$> Your identification has been saved in /root/.ssh/id_rsa.
      Your public key has been saved in /root/.ssh/id_rsa.pub


- Ora bisogna andare sull'host remoto e copiare la chiave pubblica 'id_rsa.pub' generata 

$ > cp id_rsa.pub /home/utente/.ssh

- Riavviare il server SSH sull'host di destinazione e connettersi dall'host di origine:

$ > ssh 'nomeutente'@'ip-host-remoto' o 'nome-macchina'

- Si avrà accesso all'host remoto senza inserire nessuna password

[Linux] Script creazione e copia file archivio dati in remoto


Il panorama è il seguente :

1) Server dati di produzione (Server sorgente : Srv-Prod - Red Hat Linux):

2) Server di repository (Server di destinazione : Srv-Repo - Red Hat Linux):

Per evitare di non riempire il disco del Srv-Prod, lo script una volta effettuato l'archivio in locale, lo copia sul Srv-Repo preposto a contenere gli archivi della settimana (cartelle: lunedì, martedì, mercoledì etc.) e del primo giorno del mese (cartella: mensile) per poi rimuoverlo dal server sorgente.

A grandi linee si comporta come di seguito:

- Crea un archivio giornaliero di una specifica cartella in locale

- Imposta l'archivio creato in sola lettura (al fine che non venga manomesso accidentalmente)

- Copia il file di archivio giornaliero dal Srv-prod alla cartella remota giornaliera del Srv-Repo
 
- Ogni primo del mese fa una copia dell'archivio sulla cartella remota mensile

- Se sono presenti files nella cartella giornaliera e mensile che hanno più di 90 giorni li elimina

- Rimuove l'archivio dal server sorgente

- Visualizza il contenuto della cartella giornaliera e ogni primo del mese la cartella mensile

- Crea un file di log 

All'interno del codice ho inserito dei controlli in quanto lo script potrebbe essere eseguito più di una volta al giorno (prima di procedere ad effettuare modifiche, installazioni, aggiornamenti etc sul server di produzione è sempre bene effettuare un backup dei dati)

- I controlli e le operazioni che vengono effettuate se lo script dovesse essere avviato più volte nello stesso giorno sono:

- Creazione del file di backup dell'archivio ( .bak)

- Creazione di un backup del file di backup ( .old)

- Creazione di un backup del file precedente (.old~)

Riassumendo in un semplice schema:

Archivio.tar.gz  =>  Archivio.bak => Archivio.old => Archivio.old~

N.B. Al fine di evitare l'inserimento di password in chiaro sul listato ho creato ed usato chiavi SSH per trasferire i files tra i due server

N.B. 2 Per visualizzare in maniera corretta il file di log usare il comando 'cat': cat file_di_log.txt

Lo script è il seguente:

#!/bin/bash

# Inizio script

clear
echo -e "\n"
echo -e "\e[1;31;42m Script starting...\e[0m"

# Configurazione parametri per la creazione del file di log giornaliero

A=$(date +%Y)
S=$(date +%m)
G=$(date +%d)
log_file=/var/log/logscript/log_file-$A-$S-$G.txt
exec > >(tee -a ${log_file} )
exec 2> >(tee -a ${log_file} >&2)


# Dichiarazione variabili

RESULT=$(date +%A)
FORMAT=$(date +%F)
DIR_BACK=/home/client_1/Backup/
DIR_REMOTE=/home/Repository/Backup/$RESULT
DIR_MONTH=/home/Repository/Backup/mensile
Y=$(date +%Y)
M=$(date +%m)
D=$(date +%d)

# Crea il file di archivio in locale

echo -e "\n"
echo -e "\e[34mCreo il file di archivio della cartella\e[0m $DIR_BACK\e[34m...\e[0m"
tar -zcf Archivio_Dati-$FORMAT.tar.gz --absolute-names --warning=no-file-changed $DIR_BACK
sleep 3

# Imposto il file dell'archivio in sola lettura

echo -e "\n"
echo -e "\e[33mImposto il file di archivio in sola lettura...\e[0m"
chmod 0444 Archivio_Dati-$FORMAT.tar.gz
sleep 3


# Se è presente sulla cartella remota un file di backup dell'archivio crea un secondo backup e controlla il giorno della settimana in modo da copiare l'archivio nella relativa cartella settimanale 

echo -e "\n"
if [[ $RESULT == "lunedì" ]] || [[ $RESULT == "martedì" ]]  || [[  $RESULT == "mercoledì" ]]  || [[  $RESULT == "giovedì" ]]  || [[  $RESULT == "venerdì" ]]  || [[  $RESULT == "sabato" ]]  || [[  $RESULT == "domenica" ]] ; then
if ssh root@Srv-Repo "[[ -f '$DIR_REMOTE/Archivio_Dati-$FORMAT.bak' ]]"; then
ssh root@Srv-Repo "cd $DIR_REMOTE; cp -b Archivio_Dati-$FORMAT.bak Archivio_Dati-$FORMAT.old; exit"
fi

# Effettua una copia di backup dell'archivio se presente nella cartella settimanale

echo -e "\e[35mCreo una copia di backup dell'archivio sul repository remoto nella cartella giornaliera di\e[0m $RESULT\e[35m....\e[0m"
if  ssh root@Srv-Repo "[[ -f '$DIR_REMOTE/Archivio_Dati-$FORMAT.tar.gz' ]]"; then
ssh root@Srv-Repo "cd $DIR_REMOTE; cp Archivio_Dati-$FORMAT.tar.gz Archivio_Dati-$FORMAT.bak;  exit" 
fi
fi

# Copia l'archivio sulla cartella remota settimanale del repository

echo -e "\n"
echo -e "\e[35mCopio il nuovo archivio sul repository remoto nella cartella giornaliera di\e[0m $RESULT\e[35m...\e[0m"
scp -r -q Archivio_Dati-$FORMAT.tar.gz  root@Srv-Repo:$DIR_REMOTE
sleep 3

# Se è presente sulla cartella remota un file di backup dell'archivio  mensile crea un secondo backup

echo -e "\n"
echo -e "\e[36mCreo una copia di backup del file archivio nel repository cartella mensile...\e[0m"
if [[ $D == "01" ]] ; then
if ssh root@Srv-Repo "[[ -f '$DIR_MONTH/Archivio_Dati-$Y-$M-$D.bak' ]]"; then
ssh root@Srv-Repo "cd $DIR_MONTH; cp -b Archivio_Dati-$Y-$M-$D.bak Archivio_Dati-$Y-$M-$D.old; exit"
fi

# Controlla che sia il primo del mese e copia l'archivio nella cartella mensile remota del repository

echo -e "\n"
echo -e "\e[36mControllo che sia il primo del mese e copio il file di archivio nel repository cartella mensile...\e[0m"
if  ssh root@Srv-Repo "[[ -f '$DIR_MONTH/Archivio_Dati-$Y-$M-$D.tar.gz' ]]"; then
ssh root@Srv-Repo "cd $DIR_MONTH; cp Archivio_Dati-$Y-$M-$D.tar.gz Archivio_Dati-$Y-$M-$D.bak; exit"
fi   
fi
scp -r -q Archivio_Dati-$Y-$M-$D.tar.gz   root@Srv-Repo:$DIR_MONTH   
sleep 3

# Controlla se ci sono files nelle cartelle giornaliera e mensile che hanno più di 90 giorni e li elimina

echo -e "\n"
echo -e "\e[33mVerifico nella cartella\e[0m $RESULT\e[33m se ci sono files che hanno più di 90 giorni e li elimino...\e[0m"
ssh root@Srv-Repo "cd $DIR_REMOTE; find -type f -iname '*.*' -mtime +90 -delete; exit";
if [[ $D == "01" ]] ; then
echo -e "\n"
echo -e "\e[33mVerifico nella cartella\e[0m mensile\e[33m se ci sono files che hanno più di 90 giorni e li elimino...\e[0m"
ssh root@Srv-Repo "cd $DIR_MONTH; find -type f -iname '*.*' -mtime +90 -delete; exit";
echo -e "\n"
fi

# Rimuove il file del'archivio locale

echo -e "\n"
echo -e "\e[32mRimuovo il file di archivio dal computer locale...\e[0m"
rm -f Archivio_Dati-$Y-$M-$D.tar.gz
sleep 3

# Visualizza il contenuto della cartella settimanale del repository

echo -e "\n"
echo -e "\e[1;41mDentro alla cartelle\e[33m $DIR_REMOTE \e[0m\e[1;41mci sono i seguenti files...\e[0m"
echo -e "\n"
ssh root@Srv-Repo ls -l --block-size=M  /home/Repository/Backup/$RESULT

# Ogni primo del mese visualizza il contenuto della cartella mensile del repository
 
if [[ $D == "01" ]] ; then
echo -e "\n"
echo -e "\e[1;41mDentro alla cartelle\e[33m $DIR_MONTH \e[0m\e[1;41mci sono i seguenti files...\e[0m"
echo -e "\n"
ssh root@Srv-Repo ls -l --block-size=M  $DIR_MONTH
fi

# Fine script

echo -e "\n"
echo -e "\e[33mCreazione del file di log in\e[34m /var/log/logscript/\e[0mlog_file-$A-$S-$G.txt"
sleep 5
echo -e "\n"
echo -e "\e[1;31;42m Script finished. \e[0m"
echo -e "\n"