Config ssh : utilisation de AllowUsers ou AllowGroups?

Plop !

* yunohost version 11.0.10.2
* Serveur distant
    Accès SSH

J’étais en train de jouer avec des hooks pour modifier mon /etc/ssh/sshd_config et ce qui devait arriver arriva : je me suis mis dehors :smiley:

Jusqu’à présent j’utilisais AllowUsers user1 user2 pour n’autoriser que user1 et user2 à se connecter en SSH, l’un pour quand j’administre mon serveur, le second pour recevoir les backup d’un serveur tiers via restic.

Ces deux users n’existent pas dans yunohost et n’ont d’autre utilité que celles sus-citées.

Or, lorsque j’ai voulu MaJ le fichier de config ssh avec regen-conf, je me suis aperçu qu’il existe dorénavant cette ligne :

AllowGroups ssh.main sftp.main ssh.app sftp.app admins root

Mes deux users n’étant pas dans ces groupes, ça bloque.

tl;dr :

Ce qui m’amène à ces questions :

  • Quelle différence entre les .app et les .main ?
  • Le groupe root a-t-il vraiment besoin d’être présent ? Il me semble qu’on empêche justement la connexion SSH pour root.
  • Dans mon cas spécifique, j’ai commenté la ligne AllowGroups. Ne serait-il pas plus propre de plutôt ajouter mes deux users dans les groupe idoines et réactiver cette ligne ? Si oui, confer premier point : dans quel(s) groupe(s) faut-il les inscrire ?

Merci :slight_smile:

Conseil général pour les apprentis sorciers du SSH: toujours garder un terminal ouvert en secours quand on teste une nouvelle configuration. Les terminaux déjà ouverts lors d’un redémarrage de sshd persistent, et permettent de rattraper les couacs. :slight_smile:

Les groupes .app sont des groupes UNIX, tandis que les .main sont des groupes LDAP destinés aux utilisateurs humains.

On empêche la connexion SSH pour root uniquement pour les connexions provenant de l’Internet. Elles sont autorisées depuis un VPN ou le réseau local, cf. la fin du fichier:

PermitRootLogin no
...
Match Address 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,169.254.0.0/16,fe80::/10,fd00::/8
    PermitRootLogin yes

Simplifie-toi la vie et ajoute-les au groupe ssh.app.
Sache qu’avec YunoHost 11.1 ont introduira un groupe admins pour que les utilisateurs standards puissent administrer le serveur. Plus besoin de ton user1. :wink:

1 Like

Salut titus :slight_smile:

  • J’avais un SSH déjà ouvert… et fail2ban qui tournait, ce dernier étant très punitif chez moi D:

  • Ok pour les groupes (un peu contre-intuitif : j’aurais pensé que les .app concernait uniquement ce qui passe par les applications Yunohost et que le .main impactait l’ensemble du serveur).

  • Pour root : oui, bien vu. Étant sur des serveurs distants j’ai tendance à oublier cet aspect.

  • Partageant des ressources sur internet, je pense qu’il y a plus de risques d’avoir des tentatives de forcing via des utlisateurs “diffusés” sur diverses app (nextcloud, gitea, etc…) que pour des users “fantômes”.

=> Je vais modifier mon hook pour forcer l’inclusion de mon user dans le groupe ssh.app (pas hyper propre de relancer les commandes à chaque regen_conf, mais au moins pas de risque d’oublier en cas de restoration du système).

Pour le moment ça ressemble à ça :

#!/bin/bash

# A placer dans /etc/yunohost/hooks.d/conf_regen/

if ! grep AllowUsers /etc/ssh/sshd_config; then
    #Remplacer user1 par l'utilisateur pouvant se connecter en ssh
	#Si plusieurs utilisateurs, les separer par  un espace
    sed -i 's/LoginGraceTime 120/LoginGraceTime 120\nAllowUsers user1/g' /etc/ssh/sshd_config
fi

#Remplacer 12345 par le numéro de port SSH voulu (22 par defaut)
yunohost settings set security.ssh.port -v 12345

#Revocation de la possibilité de se connecter avec un password
yunohost settings set security.ssh.password_authentication -v no

#Utilisation de TLS v1.3
yunohost settings set security.ssh.compatibility -v modern

Donc remplacer le bloc if par un truc du genre :

if [[ $(getent group ssh.app | grep user1) == "" ]]; then #Si user1 n'est pas dans le groupe ssh.app
        usermod -a -G ssh.app user1 #on ajoute le user au groupe
fi
1 Like

Pour ceux que ça pourraient intéresser, j’ai refait le hook. Si vous voyez des corrections ou améliorations à apporter, n’hésitez pas :slight_smile:

#!/bin/bash

# A placer dans /etc/yunohost/hooks.d/conf_regen/

# Yunohost et SSH	: voir https://yunohost.org/en/ssh
# Yunohost et Sécurité	: voir https://yunohost.org/en/security

# Variables
USERS=(user1 user2) # liste des utilsateurs, à séparer par des espaces.
PORT=22 # Port SSH (22 par défaut)
PWD=False # (True|False) : True pour autoriser l'authentification par mot de passe, False pour forcer l'authentification par clef
COMPATIBILITY=modern # (intermediate|modern) # Gestion de TLS 1.2, voir https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29


for i in "${USERS[@]}" # on boucle sur les différents utilisateurs de l'array USERS
do
	if [[ $(yunohost user list | grep "username: $i") != "" ]];then # si le user est un user yunohost
		if [[ $(getent group ssh.main | grep $i) == "" ]]; then #Si le user n'appartient pas au groupe LDAP ssh
			yunohost user permission add ssh $i #on ajoute le user au groupe ssh.main (groupe LDAP)
		fi
	elif [[ $(getent group ssh.app | grep $i) == "" ]]; then #Si l'utilisateur n'appartient pas au groupe UNIX ssh
		usermod -a -G ssh.app $i #on ajoute le user au groupe ssh.app (groupe UNIX)
	fi
done


# MaJ du port ssh
if [[ $(grep "Port $PORT" /etc/ssh/sshd_config) == "" ]]; then #test si le port ssh correspond à celui de la variable $PORT
	yunohost settings set security.ssh.port -v $PORT
fi

# Révocation de la possibilité de se connecter avec un password.
#****** /!\ si $PWD=False, assurez vous d'avoir au préalable ajouté une clef à vos users ! /!\ ******


if [[ $(yunohost settings get security.ssh.password_authentication) != "$PWD" ]]; then #test si la possibilité se connecter en SSH avec un mot de passe correspond à la variable $PWD
	if [[ $PWD == "False" ]]; then
		yunohost settings set security.ssh.password_authentication -v no #on force l'authentification par clef
	elif [[ $PWD == "True" ]]; then
		yunohost settings set security.ssh.password_authentication -v yes #on autorise l'authentification par mot de passe
	fi
fi


# Gestion TLS 1.2
if [[ $(yunohost settings get security.ssh.compatibility) != "$COMPATIBILITY" ]]; then #test si on est déjà dans le mode de compatibilité voulu
	yunohost settings set security.ssh.compatibility -v $COMPATIBILITY
fi
1 Like

Bonjour Kit,
J’ai un peu du mal à comprendre le principe des hooks.
En gros lorsqu’on installe Yunohost on a un petit playbook Ansible qui va aller appliquer une configuration personnalisée de sshd_config hors on voit bien ensuite qu’il est embêté par cette config personnalisée.
Du coup si j’ai bien compris le hook est un script qui se déclenche à un certain moment (après une maj ? ) et qui va aller appliquer des actions particulières ?

Merci pour ton aide :slight_smile:

Je ne maitrise pas (encore) ansible :smiley:

De mon point de vue, quand tu fais un regen-conf de tel ou tel service, yunohost remet tout à zéro puis applique les hooks dans le bon ordre.

Idem pour le diagnostique, il vérifiera que t’as la config vanille à laquelle les hooks auront été appliqués.

Mais peut-être que je me plante, @Aleks saura sans doute corriger :smiley:

1 Like

La regen-conf est le mécanisme déclenché par yunohost tools regen-conf (suivi possiblement d’une liste de service ou autres trucs à configurer)

Sous le capot il appelle un ensemble de scripts bash

Ça se produit en deux étapes bien distinctes :

  • étape “pre” : ça génère les configurations “telles qu’elle devrait être si l’instance suit le standard yunohost”
  • étape “post” : pour chaque cible, ça applique (ou pas) la conf en fonction de si elle est détectée comme manuellement modifiée par rapport à la dernière application de la regenconf ET ça fait aussi des bricoles telles que reload les services, réajuster les permissions unix, etc.

Il est possible de créer ses propres hooks pour personnaliser les configurations de manière plus pérenne que juste en modifiant à la main la conf (auquel cas yunohost arrête de toucher complètement au fichier, ce qui est problématique sur le long-terme car on ne bénéficie du coup plus des améliorations qui viennent du core)

Pour ça il faut

  • créer un script bash comme par exemple /etc/yunohost/hooks.d/conf_regen/26-dovecot_ssl qui tournera après la conf dovecot “de base” et permet de modifier la conf générée à l’étape “pre”
  • Le nommage du script est imporant et suit la syntaxe xx-service_foobar où : xx est la priorité (tu peux mettre 99 si ça te parle pas), dovecot est le nom du service pour lequel tu surcharges la conf, et foobar est un nom de ton choix
  • Le début du script ressemble toujours à quelque chose comme:
#!/bin/bash

action=$1 # Sommes-nous en train de faire l'étape "pre" ou "post" ?
pending_dir=$4 # Il s'agit du dossier dans lequel sont stockés les conf "pending"
# Dans cet exemple, il s'agit de surcharger la conf SSH ... qui est en fait dans `$pending_dir/../ssh` (généré par le hook ssh "de base") ... puis ensuite il s'agit d'une arborescende unix-like classique avec `etc/ssh/sshd_config` ...
ssh_conf=$pending_dir/../ssh/etc/ssh/sshd_config

# Si on est pas dans l'action pre, on sort tout de suite car on ne veut rien faire de spécial dans l'action post
[[ "$action" == "pre" ]] || exit 0
# Si le fichier à override n'existe pas ... on quite sans rien faire de spécial. Cette ligne n'est pas ultra importante
[[ -e "$ssh_conf" ]] || exit 0

# La vraie logique est ici
# Exemple bidon : on remplace le mot "foo" par "bar" dans le fichier de conf ssh
sed "s/foo/bar/g" -i $ssh_conf
  • Ensuite lorsqu’on appelle yunohost tools regen-conf, ou plus spécifiquement yunohost tools regen-conf ssh, YunoHost lancera le hook “de base” de SSH suivi du hook custom
5 Likes

Ok merci à vous deux pour vos explications très détaillées :smiley: