FaciLinux

Guide Facili per Linux

SSH Port Forwarding

- Posted in linux by

Introduzione

SSH Port Forwarding è un meccanismo che utilizza SSH per il tunneling delle porte tcp da client a server o viceversa. Può essere utilizzato per aggiungere la crittografia alle applicazioni legacy o passare attraverso i firewall. SSH Tunneling

Local Forwarding

E' utilizzato per inoltrare una connessione indirizzata a una porta del client verso una porta di un server, eventualmente differente dal server ssh utilizzato.

In SSH, il local port forwarding viene impostato con l'opzione -L:

ssh -L 80:intra.example.com:80 gw.example.com

Questo esempio crea un tunnel ssh al server gw.example.com (jump server) e inoltra le connessioni indirizzate alla porta 80 sul computer locale alla porta 80 del server intra.example.com attraverso il tunnel.

Per impostazione predefinita, vengono inoltrate le connessioni indirizzate alla porta 80 di qualsiasi ip del client, quindi altri client potrebbero utilizzare il tunnel. Tuttavia, questo può essere limitato ai fornendo un indirizzo di bind:

ssh -L 127.0.0.1:80:intra.example.com:80 gw.example.com

L'opzione LocalForward nel file di configurazione del client ssh /etc/ssh/ssh_config può essere utilizzata per configurare il bind senza doverlo specificare nel comando

LocalForward  

Specifies that a TCP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine.
The first argument must be [bind_address:]port and the second argument must be host:port.

Esempio

ssh -f user@personal-server.com -L 2000:personal-server.com:25 -N

Il flag -f imposta ssh in background prima che venga eseguito il comando.
Il flag -L 2000:personal-server.com:25 imposta un Local Forwarding nella forma -L local-port:host:remote-port.
Il flag -N imposta ssh in modo che non venga eseguito alcun comando sul server remoto.

L'NLA (Network Level Authentication) è un flag aggiuntivo e attivo di default nelle recenti installazioni di Windows per garantire maggiore sicurezza nelle connessioni RDP. Supponiamo di avere dei computer nel proprio dominio (MYDOMAIN.ADDS) con RDP attivo solo con autenticazione NLA , come nello screenshot qui riportato: rdp-NLA In tali casi, cercare di collegarsi via rdp da linux con i parametri standard porterebbe al fallimento della connessione, perché servono alcune configurazioni aggiuntive e preliminari.

Occorre innanzitutto installare il software necessario per lo scambio di ticket kerberos:

Per debian/ubuntu:

user@linbox~$ sudo apt install krb5-user

Per Fedora:

user@linbox~$  sudo dnf install krb5-workstation

Su sistemi debian like parte una configurazione guidata in fase di installazione del pacchetto krb5-user che chiede i dati relativi al dominio windows da configurare (nome del dominio e FQDN dei domain controller, che nell'esempio qui sotto sono dc01 e dc02); in ogni caso alla fine il file /etc/krb5.conf deve contenere le seguenti voci:

[..]
    [libdefaults]
            default_realm = MYDOMAIN.ADDS
    [..]
    [realms]
            ATENEO.UNIVR.IT = {
                    kdc = dc01.mydomain.adds
                    kdc = dc03.mydomain.adds
                    admin_server = dc01.mydomain.adds
    [..]

Da terminale, come utente non privilegiato, dare il seguente comando

    user@linbox~$ kinit mydomainuser
    Password for mydomainuser@MYDOMAIN.ADDS: 
    user@linbox~$

A questo punto usare normalmente il comando rdesktop. Se la macchina remota accetta connessioni sia con NLA sia senza, verrà privilegiata la connessione sicura NLA.

XfreeRDP

Su Fedora e su altri sistemi viene privilegiato il pacchetto xfreerdp al posto di rdesktop; anche questo software può collegarsi a sistemi rdp con NLA attivo, basta utilizzare i seguenti flag:

xfreerdp /v:remotewindows.mydomain.adds /u:mydomainuser /w:1280 /h:1024 +clipboard

Ticket kerberos

La durata del ticket kerberos creato con il comando kinit è limitata e comunque non sopravvive al riavvio; per conoscere i ticket presenti nella propria sessione usare il comando klist:

user@linbox~$ klist 
    Ticket cache: FILE:/tmp/krb5cc_1000
    Default principal: mydomainuser@MYDOMAIN.ADDS

Valid starting       Expires              Service principal
    20/03/2019 10:48:37  20/03/2019 20:48:37  krbtgt/MYDOMAIN.ADDS@MYDOMAIN.ADDS
        renew until 21/03/2019 10:48:32

Automatizzare il tutto

Volendo, è possibile eseguire uno script all'accesso al proprio desktop linux perché venga automaticamente scambiato un ticket kerberos che sarà poi utile per collegarsi via RDP. Prima di tutto è necessario un file di credenziali (da salvare nella propria Home directory, ad esempio con il nome .cred_mydomain), contenente i seguenti campi:

user=mydomainuser
pass=mypassword
dom=MYDOMAIN.ADDS

Ecco quindi lo script da inserire nel proprio avvio automatico:

#!/bin/bash
#Chiedo un ticket kerberos al dominio mydomain.adds per l'utente myuserdomain
    PASS=$(cat ~/.cred_mydomain |grep pass=|sed s/"pass="//)
    echo -n "$PASS"| kinit 01codiceGIA

Il Natting di default di VirtualBox imposta indirizzi della sottorete 10.0.15.XX. Può essere comodo o necessario a volte modificare il natting di default di una macchina già installata, ecco come fare.

Da macchina spenta aprire un terminale e digitare:

VBoxManage setextradata VM_NAME VBoxInternal/Devices/pcnet/0/LUN#0/Config/Network 172.23.24/24

(In questo esempio viene settato l'ip privato 172.23.24).

Lo stesso comando può venire dato anche su sistemi Windows, naturalmente, avendo l'accortezza, dopo aver aperto un propt dei comandi, di portarsi nella directory di installazione di VirtualBox.

Lavorando a riga di comando su una piattaforma Linux, prima o poi, abbiamo bisogno di un aiuto sui comandi della shell. Anche se sono disponibili i comandi di sistema man e whatis, a volte l'aiuto del primo è troppo descrittivo mentre il secondo lo è poco.

Ci sono poi applicazioni di terze parti come cheat, che mostra l'aiuto sul comando della shell anche quando il computer non è connesso a Internet, ma solo su comandi predefiniti.

E' possibile creare un nuovo comando attraverso uno script scritto da Jackson (https://www.mankier.com/explain), che è in grado di spiegare i comandi di shell all'interno della shell bash in modo molto efficace e indovinando quale parte della pagina di aiuto sia la migliore da visualizzare. Il comando si chiama explain.

L'unico requisito è il pacchetto curl. Se non è già installato sul sistema in uso, installarlo con i comandi:

apt-get install curl

Installazione del comando explain in Linux

Bisogna inserire il codice sottostante come nel file ~/.bashrc dell'utente.

# Add this to ~/.bash_profile or ~/.bashrc
explain () {
  if [ "$#" -eq 0 ]; then
    while read  -p "Command: " cmd; do
      curl -Gs "https://www.mankier.com/api/v2/explain/?cols="$(tput cols) --data-urlencode "q=$cmd"
    done
    echo "Bye!"
  elif [ "$#" -eq 1 ]; then
    curl -Gs "https://www.mankier.com/api/v2/explain/?cols="$(tput cols) --data-urlencode "q=$1"
  else
    echo "Usage"
    echo "explain                  interactive mode."
    echo "explain 'cmd -o | ...'   one quoted command to explain it."
  fi
}

# Update 26-03-2015. If using this command gives no output, see if running a simple fetch causes this error:
# $ curl https://www.mankier.com
# curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).
# If so, try specifying a cipher in the curl commands: curl --ciphers ecdhe_ecdsa_aes_128_sha

https://www.mankier.com/blog/explaining-shell-commands-in-the-shell.html

Dopo aver inserito il codice e averlo salvato, è necessario disconnettersi dalla sessione corrente e accedere nuovamente per rendere effettive le modifiche.

Utilizzo del comando explain

Proviamo alcuni esempi:

  1. Cosa fa 'du -h': explain 'du -h'

  2. Cosa fa 'tar -zxvf': explain 'tar -zxvf'

  3. Confrontare due comandi
    E' possibile andare in modalità interattiva semplicemente digitando il comando explain e poi digitare i comandi uno dopo l'altro per vedere cosa fanno.
    Per uscire dalla modalità interattiva, è sufficiente fare Ctrl + c.

  4. E' possibile chiedere cosa fanno più comandi in pipeline: explain 'ls -l | grep -i Desktop'

Dokuwiki è un potente wiki opensource che permette di editare, far versioning di documenti e caricare file e immagini, anch'essi sottoposti a controllo di versione.

Il controllo di versione funziona in modo trasparente se si utilizza l'interfaccia web di dokuwiki, ma supponiamo di avere dei file che vengono generati sul server che ospita la vostra istanza dokuwiki, e supponiamo di volerli rendere disponibili come media all'interno di dokuwiki stesso, con il controllo di versione.

Dokuwiki non offre nessuno strumento nativo per questo tipo di esigenza ma, con un po' di reverse engineering di come funziona il sistema di versioning di dokuwiki è possibile realizzare tale istanza, ovvero copiare localmente un file all'interno della struttura media di dokuwiki, mantenendone il versioning (potendo quindi ripristinare versioni precedenti, qualora lo si rendesse necessario).

Prima di entrare nella modalità operativa occorre spiegare un attimo come funziona dokuwiki e il suo sistema di versioning. Dokuwiki è un sistema che funziona senza database, quindi tutta la logica di funzionamento è presente all'interno di directory e files nella struttura dell'istanza di dokuwiki.

Supponiamo di voler mantenere aggiornato, con controllo di versione, il file logs.zip creato da uno script sul server stesso che monta l'istanza di dokuwiki. Supponiamo di mantenere il file logs.zip all'interno del contenitore generale media.

Se si fa l'upload da interfaccia web del file logs.zip, quello che avviene a livello di filesystem è che il file viene salvato nella directory <path_dokuwiki>/data/media . Se il file viene sostituito da una versione più recente, il media manager compie queste azioni:

  1. Calcola la data di ultima modifica in timestamp unix del file logs.zip originale
  2. Sposta il file logs.zip originale nella directory <path_dokuwiki>/data/media_attic e lo rinomina come logs.<unix_timestamp_ultima_modifica>.zip
  3. Aggiunge al file <path_dokuwiki>/data/media_meta/logs.zip.changes una riga, la cui sintassi viene descritta più avanti, che mantiene le informazioni per il versioning
  4. Copia il nuovo file logs.zip in <path_dokuwiki>/data/media

Volendo fare "l'upload" del file logs.zip dall'interno del server stesso occorre quindi simulare le operazioni svolte dal media manager di dokuwiki.

La sintassi dei file con estensione .changes, che sono responsabili del mantenimento di versione, è la seguente; per ogni nuova versione del file caricata viene aggiunta una riga contenente le seguenti informazioni, separate da tabulazione:

  1. tempo di ultima modifica in unix timestamp del nuovo file
  2. ip di origine
  3. Flag di creazione/modifica
  4. path del file in notazione namespace
  5. utente che ha fatto la modifica
  6. riga "creata" se creazione
  7. dimensione del file in byte

Usando uno script bash è possibile eseguire tutte le operazioni e i calcoli necessari, in particolare:

  1. tempo di ultima modifica in unix timestamp del nuovo file stat -c %Y
  2. ip di origine 127.0.0.1
  3. Flag di creazione/modifica C oppure E
  4. path del file in notazione namespace logs.zip
  5. utente che ha fatto la modifica (il proprio utente dokuwiki va bene)
  6. riga "creata" se creazione
  7. dimensione del file in byte ls -l file| awk '{print $5}'

Un ipotetico script in bash, quindi, conterrebbe le seguenti righe:

fileupd="<path>/logs.zip"
lastmod=$(stat -c %Y $fileupd)
fileupdsize=$(ls -l $fileupd| awk '{print $5}'
echo "$lastmod    127.0.0.1    E    logs.zip    mydoku-user        $fileupdsize >> <path_dokuwiki>/data/media_meta/logs.zip

Nello stesso script dovrebbe comparire anche la linea relativa allo spostamento e alla rinomina della vecchia versione del file logs.zip all'interno della directory <path_dokuwiki>/data/media_attic:

mv <path_dokuwiki>/media/logs.zip <path_dokuwiki>/media_attic/logs.$(stat -c %Y <path_dokuwiki>/media/logs.zip).zip

Infine, resta da copiare il nuovo file logs.zip all'interno della directory media e sistemarne i permessi perché sia leggibile all'utente che esegue l'istanza web (per Debian/Ubuntu, ad esempio, è l'utente www-data

mv $fileupd <path_dokuwiki>/media/
chown www-data:www-data <path_dokuwiki>/media/logs.zip

Per rendere il tutto automatico è possibile sfruttare naturalmente cron/anacron, così da far eseguire lo script senza necessità di interazione.

Sfruttando il software illustrato nell'articolo "Scaricare un video di Youtube da linea di comando", è possibile anche ottenere un file audio da un video o una playlist di Youtube.

Il processo è composto da due passi principali:

  1. viene scaricato il media nel formato originario (.webm)
  2. il media viene convertito nel formato desiderato (.mp3)

Per il passo di conversione il software youtube-dl si appoggia a:

  • avconv
  • ffmpeg (consigliato)

Andiamo quindi ad installare il software ffmpeg con il comando

sudo apt-get update
sudo apt-get install ffmpeg
ffmpeg -version

Per convertire in un file mp3 un video di Youtube possiamo utilizzare il comando

youtube-dl -i --extract-audio --audio-format mp3 --audio-quality 0 https://www.youtube.com/watch?v=xymjDyGIvQ4

dove

-i - ignora gli errori
--extract-audio - estrae la traccia audio
--audio-format mp3 - converte l'audio in formato mp3
--audio-quality 0 - imposta la qualità audio migliore

Se vogliamo aggiungere i tag ID3 partendo dai metadati del video di Youtube basta aggiungere lo switch --add-metadata

youtube-dl -i --extract-audio --audio-format mp3 --audio-quality 0 --add-metadata https://www.youtube.com/watch?v=xymjDyGIvQ4

Da Gnome >=3.8 occorre usare gvfs-mime (gio mime per Gnome >= 3.20) per manipolare l'applicazione associata di default per gestire il calendario.

Controllo dell'applicazione predefinita:

Gnome <3.20

gvfs-mime --query text/calendar

Gnome >= 3.20

gio mime text/calendar

Impostare la propria applicazione predefinita (google calendar):

Gnome <3.20

gvfs-mime --set text/calendar google-calendar.desktop

Gnome >= 3.20

gio mime text/calendar google-calendar.desktop

Il file google-calendar.desktop può essere creato in questo modo:

gnome-desktop-item-edit --create-new ~/.local/share/applications/google-calendar.desktop

Completare la finestra di dialogo con il seguente comando per aprire il browser con google calendar:

xdg-open <https://www.google.com/calendar>

Quindi riavviare la gnome-shell o rifare il logon nel proprio ambiente desktop perl'applicazione delle modifiche.

Se si vuole utilizzare il calendario California come predefinito (https://wiki.gnome.org/Apps/California) dare questo comando:

Gnome <3.20

gvfs-mime --set text/calendar california.desktop

Gnome >= 3.20

gio mime  text/calendar california.desktop

Teamviewer© è un software per il controllo remoto di una postazione; viene distribuito per tutti i maggiori sistemi operativi, Linux incluso. Se avete installato il software completo, pacchettizzato in formato deb o rpm, viene anche aggiunto un canale ai vostri repository per l'aggiornamento del software, ma soprattutto viene aggiunto un demone, teamviewerd, che parte all'avvio del computer e resta in attesa di connessioni. Il demone è necessario anche se usiamo la nostra postazione per controllarne un'altra, ma ha naturalmente la doppia funzione; quando si installa Teamviewer anche la nostra macchina diventa potenzialmente controllabile da remoto. Certo, è necessario avere l'accoppiata di codice id e password, ma se non vi piace l'idea di avere un demone sempre in ascolto per una connessione remota sulla vostra postazione, ecco come fare per avviare Teamviewer, demone incluso, solo quando è strettamente necessario.

Innanzitutto occorre creare uno script wrapper, semplicemente uno script bash che si occupa di:

  • Avviare il demone (chiedendo delle credenziali amministrative)
  • Avviare l'interfaccia di Teamviewer
  • Alla chiusura di Teamviewer fermare il demone

Prendete lo script bash che trovate qui sotto e salvatelo come teamviewer-wrapper all'interno di una directory compresa nel vostro PATH di ricerca degli eseguibili (generalmente $HOME/bin può essere una buona scelta se siete gli unici utilizzatori del pc):

#!/bin/bash
#A wrapper for teamviewer
#Runs teamviewer daemon only when needed

#Set teamviewer path
teamv_path="/opt/teamviewer/tv_bin/"

#check path existence
if [ ! -d $teamv_path ]; then
    zenity --error --text "Errore.\nIl percorso $teamv_path non esiste."
    exit 1
else
    pid_daemon=$(pidof teamviewerd)
    if [ ! $pid_daemon == '' ]; then
        zenity --warning --text "Attenzione, il demone di teamviewer era già in esecuzione.\nPer disabilitarne l'avvio automatico usa il comando\n\nsudo systemctl disable teamviewerd\n\nda terminale."
    else
        pkexec /opt/teamviewer/tv_bin/teamviewerd -d
        pid_daemon=$(pidof teamviewerd)
    fi
    if [ $pid_daemon -gt 1 ]; then
        /opt/teamviewer/tv_bin/TeamViewer
        pkexec kill -9 $pid_daemon
        pid_daemon=$(pidof teamviewerd)
        if [ ! $pid_daemon == '' ]; then
            zenity --warning --text "Attenzione, il demone di teamviewer sembra ancora in esecuzione"
        fi
    fi
fi

A questo punto rendiamo lo script eseguibile; apriamo una finestra di terminale e digitiamo:

chmod +x $HOME/bin/teamviewer-wrapper

Ora occorre fermare e disabilitare il demone teamviewerd, i comandi da eseguire da terminale sono:

sudo systemctl disable teamviewerd
sudo systemctl stop teamviewerd

Ora potete lanciare il comando teamviewer-wrapper dal terminale; se volete integrarlo nel menu del vostro desktop, potete copiare il contenuto riportato qui sotto all'interno della directory $HOME/.local/share/applications, salvando il file con il nome com.teamviewer.TeamViewer.desktop

#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Categories=Network;

Name=TeamViewer 13
Comment=Remote control and meeting solution.
Exec=env teamviewer-wrapper

Icon=TeamViewer
Terminal=false

Aggiornamento di Teamviewer

Ogni volta che il pacchetto Teamviewer viene aggiornato, il demone teamviewerd viene riabilitato e fatto partire in modo silente, quindi dopo l'aggiornamento occorre ricordarsi di dare questi due comandi, per fermare e disabilitare nuovamente l'avvio al boot del demone:

sudo systemctl disable teamviewerd
sudo systemctl stop teamviewerd

Googler è un curioso strumento a linea di comando che permette di cercare risultati su Google (Web o News) direttamente dal terminale. È possibile scorrere tra i risultati con i tasti freccia della tastiera; ogni link è numerato sequenzialmente e per aprire il link che ci interessa nel browser predefinito basta digitare il numero corrispondente.

Per installare googler su Debian/Ubuntu basta digitare da terminale il comando:

sudo apt-get install googler

Per cercare il terminae "Italia" nel Web con googler basta un semplice:

googler Italia

Il risultato sarà qualcosa del genere: googler-italia

Per ricercare nelle news occorre aggiungere il flag -N, quindi per cercare le ultime notizie con la parola chiave Italia il comando sarà:

googler -N italia

Il risultato del comando sarà qualcosa di simile: googler-news-italia

Googler ha anche molte opzioni per un uso avanzato dello strumento; se siete curiosi vi consiglio di leggere la pagina di manuale, disponibile naturalmente con il comando:

man googler

Trova e Sostituisci in Vim - Parte 1

- Posted in linux by

Questo articolo, suddiviso in parti, mostra degli esempi d'uso della funzione "Trova e Sostituisci" nell'editor Vim.

Vim fornisce il comando :s (sostituisci) per la ricerca e la sostituzione di stringhe di testo.

Esempi di base

:s/foo/bar/g

Trova ogni occorrenza della stringa 'foo' (nella riga corrente) e la sostituisce con la stringa 'bar'.

:%s/foo/bar/g

Trova ogni occorrenza della stringa 'foo' (in tutte le righe del testo) e la sostituisce con la stringa 'bar'.

:%s/foo/bar/gc

Trova ogni occorrenza della stringa 'foo' (in tutte le righe del testo) e la sostituisce con la stringa 'bar', chiedendo prima conferma.

 :%s/\<foo\>/bar/gc

Trova ogni occorrenza esatta della stringa 'foo' (in tutte le righe del testo) e la sostituisce con la stringa 'bar', chiedendo prima conferma.

:%s/foo/bar/gci

Trova ogni occorrenza (case insensitive, per il flag i) della stringa 'foo' (in tutte le righe del testo) e la sostituisce con la stringa 'bar', chiedendo prima conferma.

:%s/foo/bar/gcI

Trova ogni occorrenza (case sensitive, per il flag i) della stringa 'foo' (in tutte le righe del testo) e la sostituisce con la stringa 'bar', chiedendo prima conferma.

Il flag g significa globale: ogni occorrenza nella riga viene cambiata, piuttosto che solo la prima. Questo flag assume l'impostazione predefinita per l'opzione gdefault e edcompatible (off), che richiede che il flag g sia incluso in % s///g per eseguire un sostituzione globale. Usando :set gdefault si crea confusione perché la sostituzione %s/// è globale, mentre %s///g non lo è (cioè g inverte il suo significato).

Quando si usa la flag c, è necessario confermare cosa fare per ogni occorrenza trovata. Vim produrrà qualcosa come

replace with foobar (y/n/a/q/l/^E/^Y)? 

dove foobar è la stringa in sostituzione.

Puoi digitare

  • y che significa sostituire questa occorrenza,
  • n per saltare questa occorrenza,
  • a sostituire questa e tutte le occorrenze rimanenti,
  • q per uscire dal comando,
  • l per sostituire questa occorrenza e uscire,
  • ^E per far scorrere lo schermo verso l'alto tenendo premuto il tasto Ctrl e premendo E
  • ^Y per far scorrere lo schermo verso il basso di tenendo premuto il tasto Ctrl e premendo Y.

Le ultime due scelte sono disponibili solo se Vim è una build normal, big o huge o la funzione insert_expand è stata abilitata al momento della compilazione (cercare +insert_expand nell'output del comando :version).