Forum Programmation.shell Sudo su - user sur un serveur distant // Scripting

Posté par  . Licence CC By‑SA.
Étiquettes :
1
6
déc.
2018

Bonjour la communauté !

Mon problème est simple, j'ai un serveur maître qui va se connecter sur plusieurs serveurs distants dans un même script.
Chaque connexion se fera sur un user spécifique, pour ensuite se connecter sur le user applicatif pour mes commandes suivantes. Le user applicatif le "sudo su – userAPP" ne demande pas de mot de passe.

Le script exécuté depuis le serveur maître est le suivant :

ssh -t server1
sudo su - userAPP
ls -l
cp /mon/fichier /mon/autre/fichier
exit
ssh -t server2
sudo su - userAPP
ls -l
cp /mon/fichier /mon/autre/fichier
exit

Comme beaucoup le savent déjà, un sudo su relance un terminal et nous n'avons une impression de "bug" (en mode serveur distant) car plus rien ne s'exécute. De plus au lancement de mon script sur le serveur maître, je dois avoir la possibilité de mettre des variables en argument (par exemple $server1 $server2 $userAPP) qui soit récupérable tous au long de mon script.

Les contraintes :

Le problème que je pose ici se passe dans un cadre d'entreprise, je n'ai donc pas la possibilité d'installer des nouveaux outils (type fabric car je sais qu'on va m'en parler).
De plus je n'ai pas non plus la possibilité de me connecter directement sur mon user applicatif en faisant "ssh userAPP@server". Je ne peux pas changer des droits pour que la commande citée précédemment fonctionne.

Je ne pense pas être la première personne à qui ce problème arrive, enfin, j’espère !

Des idées ?
Merci d’avance !

  • # des pistes

    Posté par  . Évalué à 3. Dernière modification le 06 décembre 2018 à 12:50.

    en une fois, option "-c" de sudo

    sudo su - userAPP -c 'ls -l ;cp /mon/fichier /mon/autre/fichier'

    ca fonctionne tres bien avec ssh -t server devant

    • [^] # Re: des pistes

      Posté par  . Évalué à 5.

      Pourquoi utiliser "sudo su"? Ça me semble moyennement pertinent, non? Juste un sudo devrait faire le taf?

      Sinon, compte tenu des contraintes de l'OP, à savoir pas d'installation possible sur les machines distantes, je conseillerais l'usage d'un outil de déploiement sans agent (agentless).
      J'ai déjà utilisé un peu Rex, mais pas Ansible qui est plus connu:
      * Rex, nécessite perl et un serveur ssh sur la cible;
      * ansible, nécessite python et un serveur ssh sur la cible;

      J'ai opté pour Rex, parce que mes cibles sont sous Debian (perl obligatoire) et je voulais réduire au maximum le nombre de dépendances. Ansible étant plus connu, il est probablement plus simple de trouver de l'aide.
      Pour l'usage que j'ai eu, j'ai trouvé Rex assez facile à utiliser cela dit (même si je n'ai pas eu vraiment le temps de l'apprivoiser complètement).
      C'est plutôt pratique: on peut configurer des tâches, des cibles, et des groupes de cibles. À partir de là, il est possible d'invoquer facilement une ou plusieurs tâches spécifiques sur un nombre variables de groupes ou de cibles, y compris en parallèle.

      Pour régler le problème des machines accessibles uniquement par une «machine proxy», il est possible d'utiliser les rebonds ou les «proxycommand» ssh, par exemple avec une configuration ssh dans ce goût là:

      Host mon_proxy
          User proxy_user
          Hostname proxy.example.com
      
      Host ma_cible_1
          User cible_1_user
          Hostname cible_1
          ProxyCommand ssh -C mon_proxy /bin/nc -U %h
      

      Juste un commentaire sur l'extrait plus haut: mes cibles à moi, elles sont derrière des liens GPRS, du coup pas d'accès direct.
      Les cibles établissent donc un tunnel inversé, non pas vers un port de la machine distante, mais vers un fichier de socket UNIX dont le nom dépend de la cible: ça facilite l'allocation de l'identifiant, vu que ce fichier est généré en fonction de l'identifiant de la cible. Et puis, pas besoin de se souvenir si ma_cible_1 utilise le port 2222 ou 2223: il suffit de lister les fichiers.
      Ça implique le netcat d'openBSD, mais s'il n'est pas disponible, on peut utiliser des trucs plus standard, c'est juste plus chiant. Pour le coup, j'ai l'avantage d'avoir les accès root sur tous mes systèmes :°

      • [^] # Commentaire supprimé

        Posté par  . Évalué à 5. Dernière modification le 06 décembre 2018 à 13:54.

        Ce commentaire a été supprimé par l’équipe de modération.

        • [^] # Re: des pistes

          Posté par  . Évalué à 1.

          Bonjour, merci pour ta réponse.

          donc tu proposes de faire :

          ssh -t server1
          sudo -i -u userAPP
          ls -l
          cp /mon/fichier /mon/autre/fichier
          exit

          ?

          • [^] # Commentaire supprimé

            Posté par  . Évalué à 3.

            Ce commentaire a été supprimé par l’équipe de modération.

            • [^] # Re: des pistes

              Posté par  . Évalué à 1. Dernière modification le 06 décembre 2018 à 16:05.

              ls -l c'est juste une commande au hasard pour vérifier la faisabilité.

              je vais faire des tests et je reviens aux nouvelles.

              • [^] # Re: des pistes

                Posté par  . Évalué à 0.

                ls -l c'est juste une commande au hasard pour vérifier la faisabilité.

                Bon… j'ai voulu mitiger ma pensée en lisant le sudo su, notamment parce que je reconnais l'avoir commis. Mais le ls dans un script, c'est le pire exemple de hasard… S'il vous plaît les gens, gardez à l'esprit que des enfants peuvent lire ces obscénités et les reproduire, ce qui peut faire subir à des gens bien éduqués la maintenance de ce genre de trucs!
                Plutôt que ls, dans un script, utilisez donc find ou (inclusif) stat, il me semble qu'ils sont moins sujets à changement et plus aisés à parser! Sans parler, pour find de la possibilité de changer aisément la profondeur de recherche.

      • [^] # Re: des pistes

        Posté par  . Évalué à 1.

        Bonjour, merci pour ta réponse!

        Effectivement, Ansible serait la meilleur des solutions dans mon cas.. je ne connais pas Rex.
        Toutefois, je dois rester dans les clous et me contenter de faire du "scripting" et ne pas utiliser d'outil d'automatisation. (pour diverses raisons)

        Je n'ai pas non plus d'accès direct aux différents serveurs, le serveur maître est un Bastion.

        • [^] # Re: des pistes

          Posté par  . Évalué à 2.

          (pour diverses raisons)

          On dirait que t'es à l'école, la…

          À moins que ta boîte ne te laisse même pas installer un outil en mode utilisateur, mais ça reviens à t'empêcher d'écrire sur ton disque. Si c'est le cas, sérieux, changes de boîte. Sauf si tu es masochiste.

          Je n'ai pas non plus d'accès direct aux différents serveurs, le serveur maître est un Bastion.

          Rex (comme Ansible, probablement) sont utilisable sans installation sur les serveurs proxy ou les cibles, c'est justement leur force: ils sont «agentless», sans agent.
          Il suffit de les installer sur le poste de l'opérateur… et de savoir configurer correctement SSH.

          Moi j'ai accès aux miens, mais mon but est à terme d'empêcher tous les développeurs irresponsables (genre, ceux dont le pass user est " ", idem pour le root, non, je ne plaisante pas, sachant qu'il est possible d'accéder au LAN par wifi et que la machine en question n'est jamais éteinte…) de ma boîte d'y avoir accès, tout en pouvant intervenir dessus malgré tout (faudrait aussi que je bride un peu plus le sudo…).

          Toutefois, je dois rester dans les clous et me contenter de faire du "scripting"

          Accessoirement, le perl, c'est du script. Vraiment. Perl à été créé pour justement remplacer sh+sed+grep+awk+whatever, avec le gain de performances que l'on peut attendre d'un moins grand nombre de fork/exec. Pour faire simple, je dirais que sh, c'est le mode interactif du script système (beaucoup de texte), quand la perf on s'en balance. Le perl, c'est quand on fait du script système, mais qu'on fait souvent la tâche, et qu'aller vite est utile. La syntaxe est aussi plus lisible qu'un mélange des outils sus-cités.

          Python est aussi un langage de script, mais il est généraliste.
          Pour finir, Rex fournit en pratique un DSL de type déclaratif, basé sur perl.

    • [^] # Re: des pistes

      Posté par  . Évalué à 1.

      Bonjour, merci pour ta réponse.

      Je confirme cette façon de faire me permet de passer plusieurs commandes sur le serveur cible. Toutefois il est impossible de récupérer des variables initialisées dans le serveur maître (du moins il me semble).

      De plus impossible de voir le résultat à l'écran (par exemple je ne verrai pas mon "ls -l").

  • # Expect

    Posté par  (site web personnel, Mastodon) . Évalué à 1. Dernière modification le 06 décembre 2018 à 14:03.

    Je ne sais pas si tu dispose de cet outils, c'est pas ce qu'il y a de plus propre mais "Expect" fonctionne très bien. Pour information, Expect de base est en Tcl/Tk mais il existe une version Python (et peut-être d'autres). Dans tous les cas je ne crois aps que ce soit souvent de base dans les distrib (Même si Python l'est bien sûr il y a des dépendances fortes je crois).

    Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.

    • [^] # Re: Expect

      Posté par  . Évalué à 1.

      Bonjour, merci pour ta réponse.

      Je vais regarder si on dispose de cet outil sur nos serveurs.
      Merci!

  • # Réponse trouvé!

    Posté par  . Évalué à 1.

    Bonsoir.

    Via un autre forum, on m'a proposé ceci:

    ssh server <<eof
    sudo -iu UserAPP <<in_eof
    pwd
    ls -l
    in_eof
    eof

    Fonctionne parfaitement pour ce que j'ai a faire!
    Merci pour toutes vos réponses!

    A bientôt.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.