Come limitare gli utenti ssh ad un singolo comando

Introduzione

Oggi mi sono trovato nella necessità di dover utilizzare un utente, tramite protocollo ssh, per eseguire un singolo e semplice comando da remoto verso un server linux.

Per ragioni di sicurezza mi sono chiesto se esistesse la possibilità di limitare tale utenza all’esecuzione  di un unico programma, senza ricorrere a jail (chroot) o shell “castrate” di terze parti.

Googolando e leggendo il man di ssh  ho scoperto una soluzione facile e carina:

AUTHORIZED_KEYS FILE FORMAT
 AuthorizedKeysFile specifies the file containing public keys for public
 key authentication; if none is specified, the default is
 ~/.ssh/authorized_keys. Each line of the file contains one key (empty
 (because of the size of the public key encoding) up to a limit of 8 kilo-
 bytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16
 kilobits. You don't want to type them in; instead, copy the
 identity.pub, id_dsa.pub, or the id_rsa.pub file and edit it.

...
...
...

 command="command"
 Specifies that the command is executed whenever this key is used
 for authentication. The command supplied by the user (if any) is
 ignored. The command is run on a pty if the client requests a
 pty; otherwise it is run without a tty. If an 8-bit clean chan-
 nel is required, one must not request a pty or should specify
 no-pty. A quote may be included in the command by quoting it
 with a backslash. This option might be useful to restrict cer-
 tain public keys to perform just a specific operation. An exam-
 ple might be a key that permits remote backups but nothing else.
 Note that the client may specify TCP and/or X11 forwarding unless
 they are explicitly prohibited. The command originally supplied
 by the client is available in the SSH_ORIGINAL_COMMAND environ-
 ment variable. Note that this option applies to shell, command
 or subsystem execution.

In poche parole autenticando gli utenti remoti in ssh tramite lo scambio delle chiavi pubbliche, quindi senza utilizzare alcuna password, è possibile specificare l’unico programma che l’utente potrà eseguire.

Chiave Privata e Pubblica

Per permettere ad un client di collegarsi su un server remoto ssh tramite lo scambio delle chiavi, sono necessarie due azioni:

  1. Generazione delle chiave privata e pubblica per l’utente (ad esempio pippo) che utilizzerà il client.
  2. Copia della chiave pubblica sul server nella home directory di pippo

Generazione delle chiavi

Per generare le chiavi basta eseguire lato client il seguente comando:

[pippo@client ~]$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pippo/.ssh/id_rsa): (Premi invio)
Created directory '/home/pippo/.ssh'.
Enter passphrase (empty for no passphrase): (Premi invio)
Enter same passphrase again: (Premi invio)
Your identification has been saved in /home/pippo/.ssh/id_rsa.
Your public key has been saved in /home/pippo/.ssh/id_rsa.pub.
The key fingerprint is:
f3:3b:e4:2d:e9:d2:1d:b3:93:70:45:cc:58:36:0c:96 pippo@client.localdomain
[pippo@client ~]$

Come si può notare la chiave privata (id_rsa) e quella pubblica (id_rsa.pub) vengono create nella cartella .ssh  all’interno della home utente.

Copia della chiave pubblica sul server

Per copiare la chiave si possono utilizzare svariati metodi, qui di seguito riporto i due più classici:

1)

[pippo@client ~]$ ssh-copy-id pippo@server
pippo@server's password: (Inserisci la password)
Now try logging into the machine, with "ssh 'pippo@server'", and check in:

 .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

[pippo@client ~]$

2)

In alternativa si può utilizzare il classico “scp“, ma prima è necessario eseguire un paio di comandi lato server:

[pippo@server ~]$ mkdir ~/.ssh
[pippo@server ~]$ chmod 700 ~/.ssh/

A questo punto copiare la chiave sul server ed inserire le credenziali richieste:

[pippo@client ~]$ scp ~/.ssh/id_rsa.pub server:/home/pippo/.ssh/authorized_keys

Infine sistemare i permessi del file appena caricato sul server:

[pippo@server ~]$ chmod 600 ~/.ssh/authorized_keys

Limitazione utente

Come anticipato nello spezzone di “man” copiato all’inizio del post, per limitare gli utenti ssh ad un singolo comando è necessario modificare lato server il file authorized_keys.

Ponendo il caso di voler fare eseguire solo il comandi “id” all’utente pippo, il file authorized_keys deve essere modificato da così:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA....E96KU2aGiF7BuNe3vQ== pippo@client.localdomain

a così:

command="id" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA....E96KU2aGiF7BuNe3vQ== pippo@client.localdomain

In pratica basta aggiungere all’inizio della riga l’opzione command=”” mettendo tra virgolette il comando interessato.

E’ possibile testare il comando lato client eseguendo il comando:

[pippo@client ~]$ ssh pippo@server
uid=522(pippo) gid=522(pippo) gruppi=522(pippo)
Connection to server closed.

Controllando l’output si nota che il server ssh dopo aver eseguito il comando id, senza aver richiesto la password, chiude la connessione al client.

Naturalmente qui si apre un mondo, ad esempio è possibile sostituire il singolo comando con uno script, creato sul server, che esegue più programmi.

Se vogliamo rendere il comando più dinamico, e quindi personalizzare gli argomenti da passare, basta aggiungere la variabile $SSH_ORIGINAL_COMMAND all’opzione command=””:

command="id $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA....E96KU2aGiF7BuNe3vQ== pippo@client.localdomain

Esempio:

[pippo@client ~]$ ssh pippo@server "id --version"
id (GNU coreutils) 5.97
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

Written by Arnold Robbins and David MacKenzie.

Prima di salutarvi vi consiglio di aggiungere anche queste ulteriori restrizioni all’interno del file authorized_keys:

command="id $SSH_ORIGINAL_COMMAND",no-port-forwarding,no-pty,no-agent-forwarding,no-X11-forwarding

Con questa modifica l’utente, oltre a non poter eseguire altri comandi, non potrà eseguire i vari forwarding o aprire terminali virtuali.