Comme tout autre développeur et administrateur système solo, je fais des choses en utilisant ssh. Certaines choses sont automatisées à l'aide de scripts, et d'autres nécessitent une connexion ssh. Par exemple, un de mes scripts se connecte à mon serveur Linux et FreeBSD à l'aide de clés ssh publiques et effectue un type de travail particulier pour moi. J'ai un compte utilisateur dédié à cet effet appelé autovivek sur Raspberry PI 4 pour Ansible et l'automatisation de scripts personnalisés. Voici comment cela fonctionne :
{rpi4:~}$ ssh [email protected] /path/to/taks1
Dans d'autres cas, il envoie des scripts et les exécute ensuite sur le serveur distant nommé 192.168.2.17. Ça a l'air bien, non ? Donc, lorsque je dois effectuer des sauvegardes et d'autres tâches, je verrouille le compte utilisateur autovivek sur le serveur afin qu'il ne modifie pas les données sur les disques. Par exemple, voici comment verrouiller un compte utilisateur :
{linux-server:~}$ sudo usermod -L -e 1 autovivek
{freebsd-server:~}$ sudo pw lock -n autovivek
Une mise en garde sur le verrouillage des comptes utilisateurs Linux et FreeBSD
Cependant, j'ai rapidement découvert qu'un utilisateur nommé autovivek peut toujours se connecter au serveur et effectuer des modifications malgré le verrouillage des serveurs Linux et FreeBSD. J'ai bêtement supposé que cela fonctionnerait dès la sortie de la boîte. Mais, mon garçon, j'ai eu une grosse surprise.
Après une inspection minutieuse sur autobox (ordinateur RPi 4), j'ai découvert que j'ai activé le multiplexage ssh pour accélérer ssh il y a quelques jours dans mon fichier ~/.ssh/config :
Host * IdentitiesOnly yes ControlPath ~/.ssh/controlmasters/%r@%h:%p ControlMaster auto ControlPersist yes
Qu'est-ce que le multiplexage SSH ?
Le multiplexage SSH n'est rien d'autre que le transport de plusieurs sessions SSH sur une seule connexion TCP. En d'autres termes, OpenSSH réutilise une connexion TCP existante pour plusieurs sessions SSH simultanées. Un compte utilisateur verrouillé ou déverrouillé n'a pas d'importance sur la machine distante si une session est déjà établie sur le serveur OpenSSH. Il se connectera directement en utilisant le ssh. Voici comment savoir si la session est ouverte ou non :{rpi4:~}$ ssh -O check [email protected]
Voici ce que je vois :
Master running (pid=418156)
Bien sûr, la commande ss confirmera également l'ouverture de la session :
{rpi4:~}$ ss -o state established ( dport = :ssh or sport = :ssh ) | grep 192.168.2.17
Session ouverte en arrière-plan
tcp 0 0 192.168.2.25:ssh 192.168.2.17:22201 timer:(keepalive,1min13sec,0) tcp 0 0 192.168.2.25:46412 192.168.2.17:ssh timer:(keepalive,67min,0)
Du côté du serveur, une session similaire sera également ouverte en arrière-plan :
{linux-server:~}$ ss -o state established ( dport = :ssh or sport = :ssh ) | grep 192.168.2.17
Sorties :
Netid Recv-Q Send-Q Local Address:Port Peer Address:Port Process tcp 0 0 192.168.2.17:ssh 192.168.2.25:41884 timer:(keepalive,29min,0)
En d'autres termes, la commande ss confirme que ssh écoute en arrière-plan sur le serveur quand ControlPersist réglé sur yes du côté client dans le fichier ~/.ssh/config. Il maintient la connexion ouverte entre le client ssh et le serveur pour accélérer l'opération. Et c'est la cause première de mon problème. Ah, le mystère est résolu. Extrait de la page de manuel ssh_config(5) :
- La directive ControlPersist indique que la connexion maître doit rester ouverte en arrière-plan (en attendant les futures connexions client) après la fermeture de la connexion client initiale.
- Si elle est définie sur non, la connexion maître ne sera pas placée en arrière-plan et sera fermée dès que la connexion client initiale sera fermée.
- On peut lui donner la valeur yes ou 0, alors la connexion maître restera en arrière-plan indéfiniment jusqu'à ce qu'elle soit tuée ou fermée par un mécanisme tel que la fonction "ssh -O exit".
- Si elle est définie à un temps en secondes, ou un temps dans l'un des formats documentés dans sshd_config(5), alors la connexion maître en arrière-plan sera automatiquement terminée après qu'elle soit restée inactive sans connexion client pendant le temps spécifié.
Voici donc comment j'ai résolu mon problème.
Comment verrouiller les comptes utilisateurs Linux et FreeBSD en toute sécurité et bloquer l'accès ssh immédiatement
Un compte de verrouillage n'est pas suffisant. Il serait préférable d'arrêter tous les processus appartenant à l'utilisateur nommé 'autovivek'. En d'autres termes, je fais cela maintenant :
{linux-server:~}$ sudo killall -STOP -u autovivek
En d'autres termes, la procédure correcte pour verrouiller le compte sur les serveurs Linux et FreeBSD est la suivante :
{linux-server:~}$ sudo usermod -L -e 1 autovivek # Linux
{freebsd-server:~}$ sudo pw lock -n autovivek # FreeBSD
Puis sur les deux serveurs :
{linux-server:~}$ killall -STOP -u autovivek # STOP all processes owned by the autovivek user
Bien sûr, vous pouvez le tuer, mais j'avais juste besoin de les arrêter et ensuite, lorsque la sauvegarde est terminée, je déverrouille le compte utilisateur et je reprends la session :
{linux-server:~}$ sudo usermod -e -1 -U autovivek # Linux
{freebsd-server:~}$ sudo pw unlock -n autovivek # FreeBSD
De nouveau, exécutez la commande killall sur les deux serveurs pour reprendre tous les processus appartenant à l'utilisateur 'autovivek' :
{linux-server:~}$ killall -CONT -u autovivek # Resume session
Signal SIGSTOP et SIGCONT
La commande killall envoie le -STOP (SIGSTOP) pour arrêter tous les processus appartenant à un utilisateur nommé 'autovivek'. De même, le signal -CONT (SIG) est utilisé pour continuer (reprendre) les processus appartenant à un utilisateur nommé 'autovivek' s'ils sont actuellement arrêtés.
Résumé
Il s'agit en effet d'un récit édifiant sur le verrouillage des comptes utilisateurs Linux et FreeBSD. Peu importe la prudence dont vous faites preuve, il y aura toujours des effets secondaires avec l'optimisation. J'ai activé l'optimisation de la vitesse de ssh via le multiplexage, et j'ai rencontré quelques surprises. Consultez les pages de manuel suivantes en utilisant la commande man pour plus d'informations :
$ man sshd_config
$ man ssh_config
$ man ssh
$ man kill
$ man killall
$ man 7 signal
Cela me rappelle le script de procédure de suppression de compte Unix que j'ai développé il y a de nombreuses années lorsque l'administrateur système supprimait le compte utilisateur sur HP-UX. Tout d'abord, il recherche tous les cron/at jobs, processus, emails et fichiers appartenant à l'utilisateur. Ensuite, il archive tous les fichiers et les supprime.