hmm: Groovy auf Jenkins Server: SVN Passwort sicher hinterlegen

Hi Leute,

ich möchte auf meinem Jenkins Server SVN Passwörter "sicher" hinterlegen. Mit sicher meine ich, dass man die nicht unbedingt direkt loopen können sollte.

SSH ist leider nicht möglich, da das SVN Repositority sowas nicht kriegen soll.

Meine Ideen wären:

  1. Idee:

Jeder Nutzer ändert sein Jenkins Passwort auf sein SVN Passwort. Dieses Passwort wird standartmäßig vom Jenkins Codiert gespeichert.

Mit

Jenkins.instance.getMe().getConfigFile().asString()

bekomm ich ein XML wo das drin steht:

<hudson.security.HudsonPrivateSecurityRealm_-Details>
      <passwordHash>#jbcrypt:$2a$10$mVxgiI7qSjhCLiLmQuqXMe5isaymYvacvyzBjp7/qLTblZ/hlL786</passwordHash>
</hudson.security.HudsonPrivateSecurityRealm_-Details>

für Idee 1 müsste ich den entweder Decodieren (was eventuell nicht geht, weil es ein einseitiger Hash sein könnte) oder meinem SVN zu verstehen geben. dass das gehashte Passwort ok ist (falls das geht).

was haltet ihr davon? falls das geht, könnt ihr mir sagen wie?

  1. Idee:

Ich schreibe eine neue Anwendung in der der Nutzer sein SVN Passwort speichert und sichere dieses gehasht auf dem Jenkins Server. Habt ihr eine Idee wie ich das so haschen kann, dass es sich anschließend wieder für das SVN enthashen oder auf andere weise fürs SVN nutzen lässt?

Hintergrund ist, dass wir einen Jenkinsprozess haben der Sachen ins SVN eincheckt und wir wollen, dass diese Sachen unter den entsprechenden Usernamen eingecheckt werden und nicht per globalen SVN-Jenkinsuser.

  1. Tach,

    ich möchte auf meinem Jenkins Server SVN Passwörter "sicher" hinterlegen. Mit sicher meine ich, dass man die nicht unbedingt direkt loopen können sollte.

    „loopen“?

    SSH ist leider nicht möglich, da das SVN Repositority sowas nicht kriegen soll.

    Warum nicht?

    <hudson.security.HudsonPrivateSecurityRealm_-Details>
          <passwordHash>#jbcrypt:$2a$10$mVxgiI7qSjhCLiLmQuqXMe5isaymYvacvyzBjp7/qLTblZ/hlL786</passwordHash>
    </hudson.security.HudsonPrivateSecurityRealm_-Details>
    

    Ich hoffe das war nicht der echte zu deinem PW gehörende Hash (wenn du dich an übliche PW-Richtlinien hälst, sollte das zwar kein Problem sein, aber…); man sollte nicht darauf vertrauen, dass Hash-Funktionen in alle Ewigkeit ungebrochen bleiben werden.

    für Idee 1 müsste ich den entweder Decodieren (was eventuell nicht geht, weil es ein einseitiger Hash sein könnte)

    Das eventuell kann ich für diesen Hash ausräumen, das ist bcrypt, im Moment gibt es keine Möglichkeit aus diesem Hash auf den Klartext zu schließen.

    oder meinem SVN zu verstehen geben. dass das gehashte Passwort ok ist (falls das geht).

    Theoretisch könntest du den Hash selber als PW hinterlegen, aber… (s.u.)

    Ich schreibe eine neue Anwendung in der der Nutzer sein SVN Passwort speichert und sichere dieses gehasht auf dem Jenkins Server. Habt ihr eine Idee wie ich das so haschen kann, dass es sich anschließend wieder für das SVN enthashen oder auf andere weise fürs SVN nutzen lässt?

    Das geht konzeptioniell nicht, ein (kryptographischer) Hash unterscheidet sich von Verschlüsselung gerade dadurch, dass er eine Einwegfunktion ist (sein sollte).

    Hintergrund ist, dass wir einen Jenkinsprozess haben der Sachen ins SVN eincheckt und wir wollen, dass diese Sachen unter den entsprechenden Usernamen eingecheckt werden und nicht per globalen SVN-Jenkinsuser.

    Ist http://svnbook.red-bean.com/en/1.7/svn.serverconfig.netmodel.html#svn.serverconfig.netmodel.credcache dafür nicht ausreichend?

    Und dann einmal die Bitte um mehr Information, damit man ein sinnvolles Konzept erdenken kann:

    • Läuft der SVN Server auf der selben Maschine wie das Jenkins?
    • Sollen die User sich im SVN ohne das Jenkins auch anmelden können?

    mfg
    Woodfighter

    1. hallo,

      danke für die antworten.

      das svn ist auf einem anderen Server und kann per url erreicht werden. die Nutzer haben bereits einen svn zugang. dieser svn zugang soll nun von jedem Nutzer nur einmal im jenkinsserver hinterlegt werden.

      ich bin hierauf gestoßen:

      https://cloudbees.zendesk.com/hc/en-us/articles/217708168-create-credentials-from-groovy

      jetzt überlege ich, ob es sinn macht eine Jenkins Anwendung zu schreiben in der jeder Nutzer sein svn Login einmal speichert. dafür würde ich dann ein groovy objekt schreiben, dass so ein credential unter diesem cloudbees speichert. macht das sinn? als Domain wird mit "com.cloudbees.plugins.credentials.domains.Domain@0 " angezeigt, kann man da Passwörter "sicher" hinterlegen?

      1. Tach,

        das svn ist auf einem anderen Server und kann per url erreicht werden.

        ok, und meine zweite Frage?

        Sollen die User sich im SVN ohne das Jenkins auch anmelden können?

        mfg
        Woodfighter

        1. Tach,

          das svn ist auf einem anderen Server und kann per url erreicht werden.

          ok, und meine zweite Frage?

          Sollen die User sich im SVN ohne das Jenkins auch anmelden können?

          mfg
          Woodfighter

          ja, sie sollen sich weiterhin im svn auch ohne Jenkins anmelden können.

          ich experimentiere gerade hiermit:

          https://cloudbees.zendesk.com/hc/en-us/articles/217708168-create-credentials-from-groovy

          das teil gehört zu dem plugin das bereits im Jenkins eingebaut worden ist. die Handhabung ist aber komplizierter als ich dachte, den mein groovy 2.4.5 will das hier nicht machen:

          Credentials c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, id, "description:"+id, "user", "password")
          
          

          Fehlermeldung:

          $ "pfad...."
          org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
          "pfad ..."/hudson7640406788083638574.groovy: 36: unable to resolve class Credentials 
           @ line 36, column 17.
                 Credentials creds = (Credentials) new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, id, "description:"+id, "user", "password")
                             ^
          
          "pfad..."/hudson7640406788083638574.groovy: 36: unable to resolve class Credentials 
           @ line 36, column 25.
                 Credentials creds = (Credentials) new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, id, "description:"+id, "user", "password")
                                     ^
          
          "pfad...."/hudson7640406788083638574.groovy: 36: unable to resolve class UsernamePasswordCredentialsImpl 
           @ line 36, column 39.
                 Credentials creds = (Credentials) new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, id, "description:"+id, "user", "password")
          

          anstelle von "pfad..." steht der richtige pfad zur Datei auf meinem Jenkins Server.

          1. Tach,

            das svn ist auf einem anderen Server und kann per url erreicht werden.

            ok, und meine zweite Frage?

            Sollen die User sich im SVN ohne das Jenkins auch anmelden können?

            ja, sie sollen sich weiterhin im svn auch ohne Jenkins anmelden können.

            ok, dann würde ich das folgendermaßen sehen:

            1. Ich als User würde ein PW, dass ich zur Authentifizierung für einen Dienst (hier svn) nutze keinem anderen Dienst (hier jenkins) anvertrauen, den ich nicht selbst kontrolliere.
            2. SVN erlaubt m.w. nur ein Set an Credentials pro User.

            Wenn ich das implementieren würde, würde ich erstens die Möglichkeit lassen, das Passwort jedesmal wenn es gebraucht wird (vielleicht auch mit einem Cache innerhalb der Session) vom User abzufragen und es ansonsten mit einem vom User vergebenen PW verschlüsselt in der Userkonfiguration abzulegen. Falls das zu kompliziert ist, würde ich vermutlich einfach dem SVN weitere User nach dem Schema $username-jenkins anlegen und diese automatisiert über das Tool verwalten, dann ist es nicht der selbe User, aber es ist sofort zuordenbar.

            ich experimentiere gerade hiermit:

            https://cloudbees.zendesk.com/hc/en-us/articles/217708168-create-credentials-from-groovy

            Warum nutzt du das Plugin nicht einfach selber, das beschreibt doch genau die Situation, die du willst: https://www.cloudbees.com/blog/open-sourcing-credentials-plugin

            unable to resolve class Credentials

            Da stimmt der Classpath (oder dessen Inhalt) wohl nicht.

            mfg
            Woodfighter

            1. Im worst case muss ich die Passwörter jedes Nutzers auf dem Jenkins speichern.

              meine derzeitige Strategie ist:

              1. der globale svn user im Jenkins wurde per credential plugin angelegt, d.h. ich kann so einen user manuell für jeden Nutzer anlegen.

              2. ich lege diese credential plugin user automatisch mit einem groovy script an

              mein Problem ist, dass ich nicht verstehe wie ich diesen code hier

              https://github.com/jenkinsci/credentials-plugin

              auf meinen Jenkins Server bekomme. ich glaube ich brauche diesen code um

              import com.cloudbees.plugins.credentials.impl.*
              import com.cloudbees.plugins.credentials.* 
              
              

              richtig importerien zu können. in Java würde ich gucke ob ich irgend eine passende cloudbees jar in maven oder ant dependencies setzen kann.

              mein ziel ist eine classe die dann ungefähr so aussieht:

              https://github.com/jenkinsci/puppet-jenkins/blob/master/files/puppet_helper.groovy

              Problem: der Import klappt nicht, weil ich wahrscheinlich irgendwas irgendwie installieren bzw. runterladen muss.

    2. Hallo,

      der oben beschriebene Weg hat funktioniert. Der Trick war, das Groovy Script nicht als "Executable Skript" im Jenkins zu erstellen, sondern als "Evaluatet Skript".

  2. Moin!

    ich möchte auf meinem Jenkins Server SVN Passwörter "sicher" hinterlegen. Mit sicher meine ich, dass man die nicht unbedingt direkt loopen können sollte.

    Jenkins hat einen Passwort-Storage, der erlaubt, dass man in einzelnen Jobs nur "das Passwort von X" referenziert, aber es dort nicht im Klartext in die Konfiguration eintragen muss/kann.

    1. Idee:

    Jeder Nutzer ändert sein Jenkins Passwort auf sein SVN Passwort. Dieses Passwort wird standartmäßig vom Jenkins Codiert gespeichert.

    Wieso muss der Jenkins die User-Passworte vom SVN kennen? Was soll der damit machen?

    Die übliche Vorgehensweise wäre doch, dass der Jenkins ebenfalls einen SVN-Account bekommt und mit dem dort liest und ggf. auch schreibt, unabhängig von den Usern.

    Hintergrund ist, dass wir einen Jenkinsprozess haben der Sachen ins SVN eincheckt und wir wollen, dass diese Sachen unter den entsprechenden Usernamen eingecheckt werden und nicht per globalen SVN-Jenkinsuser.

    Tja, geht nicht. Würde auch mit SSH nicht gehen. Würde mit Git gehen (bis zu einem gewissen Grad), weil die Angabe des Usernamens und der Mailadresse beim Commit unabhängig von der Prüfung der Lese- oder Schreibberechtung auf dem Git-Server sind. Git nativ kennt gar kein derartiges Sicherheitsprotokoll, das ist immer im darumliegenden Transportprotokoll implementiert. Git-intern gibt es lediglich PGP-signierte Commits - und die wiederum sind im Zusammenspiel mit den Hashes der Commits ziemlich manipulationssicher (und wenn sowas im Spiel wäre, müsste der Jenkins also wieder die PGP-Schlüssel aller Mitarbeiter kennen - unschön).

    Ich würde der Tatsache ins Auge sehen, dass eine SVN-Authentifizierung der menschlichen User auf dem Jenkins innerhalb eines automatisierten Jobs nicht vorgesehen ist. Selbstverständlich kannst du die Klartext-Passworte, die du deshalb benötigst, weil sonst der SVN-Login nicht geht, irgendwo speichern und da auch noch viel Security drumrumwickeln.

    Alternativ implementierst du mit dem SVN-Server OAuth2 und lässt jeden User den Prozess durchlaufen, mit den nur ihm bekannten Credentials dem Jenkins ein Token zukommen zu lassen, mit dem dieser dann als Stellvertreter agieren kann.

    Grüße Sven

    1. "Wieso muss der Jenkins die User-Passworte vom SVN kennen? Was soll der damit machen?"

      Vorallem soll der Name des Nutzer der sich im Jenkins eingeloggt hat im SVN Commit stehen.

      Oben beschreibe ich gleich meine derzeitige Strategie.