← retour aux snippets

ssh: restreindre une clé dans authorized_keys

Limiter une clé publique à une commande, une source IP et interdire les forwards pour un accès contrôlé.

bash sécurité #ssh#security#acl

objectif

Restreindre l’usage d’une clé SSH à une commande précise, bloquer les forwards (agent, port, X11, pty) et limiter les adresses autorisées, directement dans ~/.ssh/authorized_keys.

code minimal

# ligne unique à placer dans ~/.ssh/authorized_keys (utilisateur cible)
# force l'exécution d'un script, interdit les forwards, limite aux IP 203.0.113.0/24
command="/usr/local/bin/backup-rsync --read-only",restrict,from="203.0.113.0/24" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexampleExampleKeyMaterialOnlyForDemo deploy@laptop

utilisation

# 1) sécuriser les permissions
install -d -m 0700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 0644 ~/.ssh/authorized_keys

# 2) ajouter la clé restreinte (édition via tee, pas de sudo si user courant)
cat >> ~/.ssh/authorized_keys <<'EOF'
command="/usr/local/bin/backup-rsync --read-only",restrict,from="203.0.113.0/24" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexampleExampleKeyMaterialOnlyForDemo deploy@laptop
EOF

# 3) script forcé (exemple) côté serveur
sudo install -m 0755 -o root -g root /dev/stdin /usr/local/bin/backup-rsync <<'EOSH'
#!/usr/bin/env bash
set -Eeuo pipefail
# lecture seule via rsync (pull autorisé, pas de push)
exec /usr/bin/rsync --server --sender -logDtpre.iLsfxC -- . /srv/backup/
EOSH

# 4) test: la session ne doit PAS ouvrir de shell interactif
ssh -i ~/.ssh/id_ed25519 user@serveur.data.pm 'true'  # exécute la commande forcée

variante(s) utile(s)

# autoriser uniquement un tunnel local vers Postgres (pas d'autres ports)
permitopen="127.0.0.1:5432",restrict ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexample user@host

# restreindre à SFTP interne et chroot d'upload (par clé, sans toucher sshd_config)
command="/usr/lib/openssh/sftp-server -d /upload",restrict ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexample user@host

# fixer des variables d'environnement non sensibles pour la commande forcée
environment="MODE=ro",restrict,command="/usr/local/bin/task" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexample user@host

# limiter à une IP unique (v4) et un fqdn (attention au DNS)
from="198.51.100.42",restrict ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIexample user@host

notes

  • l’option restrict (OpenSSH ≥7.2) équivaut à no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty,no-user-rc.
  • command="..." force l’exécution et ignore la commande fournie par le client; combinez avec restrict pour fermer les échappatoires.
  • from=".../prefix" accepte IP, plages CIDR et hôtes; préférez les IP pour éviter les surprises DNS.
  • les permissions doivent être strictes: ~/.ssh en 0700, authorized_keys en 0644 (ou 0600).
  • vérifiez avec ssh -v que la commande forcée s’exécute et qu’aucun forward n’est permis (messages “Port forwarding disabled”).