Jenkins sur OS X: xcodebuild donne une erreur de signe de Code

résumé:

installer Jenkins sur OS X a été considérablement facilité avec L'installateur le plus récent ( en date du 1.449 - 9 mars 2012 ), cependant la gestion du processus de signature de code est encore très difficile sans réponse simple.

la Motivation:

exécutez un serveur de CI sans tête qui suit les meilleures pratiques communes pour exécuter des services sur OS X ( dont certains sont expliqués ici en langage clair ).

Contexte:

Processus:

Install Jenkins CI via OS X installer package . Pour l'étape" Type D'Installation", cliquez sur le bouton Personnaliser et choisissez "Démarrer à l'amorçage" jenkins."

Discussion:

l'attente naïve à ce stade était qu'un projet de style libre avec le script de construction xcodebuild -target MyTarget -sdk iphoneos devrait fonctionner. Comme indiqué par le titre de ce poste, il ne fait pas et échoue avec:

Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain

il est assez évident ce qui doit se produire - vous devez ajouter un certificat de signature de code valide et une clé privée dans le porte-clés par défaut. En cherchant comment y parvenir, je n'ai pas trouvé de solution qui n'ouvre pas le système à un certain niveau de vulnérabilité.

Problème 1: Pas de porte-clés par défaut pour le démon jenkins

sudo -u jenkins security default-keychain ...les rendements "Un trousseau par défaut n'a pas pu être trouvé"

comme indiqué ci-dessous par Ivo Dancet , L'UserShell est défini à /usr/bin/false pour le démon jenkins par défaut (je pense que c'est une fonctionnalité, pas un bug); suivre sa réponse pour changer l'UserShell à bash. Vous pouvez ensuite utiliser sudo su jenkins pour se connecter en tant qu'utilisateur jenkins et obtenir une invite bash.

  1. sudo su jenkins
  2. cd ~/Library
  3. mkdir Keychains
  4. cd Keychains
  5. security create-keychain <keychain-name>.keychain
  6. security default-keychain -s <keychain-name>.keychain

OK, Super. Nous avons un porte-clés par défaut maintenant; allons de l'avant à droite? Mais d'abord, pourquoi s'est-on donné la peine de faire un porte-clés par défaut?

presque toutes les réponses, suggestions ou conversation que j'ai lu tout au long de la recherche suggèrent que l'on devrait juste jeter leurs certs de signature de code et des clés dans le porte-clés du système. Si vous lancez security list-keychains comme un projet de style libre à Jenkins, vous voyez que le seul porte-clés disponible est le porte-clés du système; je pense que c'est là que la plupart des gens sont venus avec l'idée de mettre leur certificat et la clé là-dedans. Mais, cela semble juste comme une très mauvaise idée - surtout étant donné que vous aurez besoin de créer un script texte simple avec le mot de passe pour ouvrir le porte-clés .

problème 2: Ajout de certificats de signature de code et de clés privées

C'est là que je commence vraiment à avoir des problèmes. J'ai le pressentiment que je devrais créer une nouvelle clé publique / privée unique à utiliser avec Jenkins. Mon processus de pensée est si le démon jenkins est compromis, alors je peux facilement révoquer le certificat dans le portail D'approvisionnement D'Apple et générer une autre clé publique / privée. Si j'utilise le même clé et le certificat pour mon compte d'utilisateur et Jenkins, cela signifie plus de tracas (dommage?) si le service de jenkins est attaqué.

pointant vers réponse de Simon Urbanek vous déverrouillerez le porte-clés à partir d'un script avec un mot de passe en clair. Il semble irresponsable de garder autre chose que des certificats et des clés" jetables " dans le porte-clés du démon jenkins.

je suis très intéressé à toute discussion à contraire. Suis-je trop prudents?

pour faire un nouveau CSR comme le démon jenkins dans le Terminal j'ai fait ce qui suit...

  1. sudo su jenkins
  2. certtool r CertificateSigningRequest.certSigningRequest on vous demandera ce qui suit (la plupart de ceux-ci j'ai fait des suppositions instruites à la bonne réponse; avez-vous une meilleure vision? S'il vous plaît partager.)...
    • entrer l'étiquette de la clé et du certificat:
    • Sélectionner l'algorithme: r (pour RSA)
    • entrez la taille de la clé en bits: 2048
    • sélectionner l'algorithme de signature: 5 (pour MD5)
    • Entrez la chaîne challenge:
    • puis un tas de questions pour RDN
  3. soumettre le fichier CSR généré (CertificateSigningRequest.certSigningRequest) sur le portail D'approvisionnement D'Apple sous un nouveau Apple ID
  4. Approuver la demande et télécharger le .fichier cer
  5. security unlock-keychain
  6. security add-certificate ios_development.cer

cela nous rapproche un peu...

problème 3: profil D'approvisionnement et déverrouillage du porte-clés

j'ai fait un profil d'approvisionnement spécial dans le portail D'approvisionnement juste pour une utilisation avec CI dans l'espoir que si quelque chose de mauvais il se passe que j'ai fait de l'impact d'un peu plus petite. Pratique exemplaire ou trop prudent?

  1. sudo su jenkins
  2. mkdir ~/Library/MobileDevice
  3. mkdir ~/Library/MobileDevice/Provisioning Profiles
  4. déplacez le profil d'approvisionnement que vous avez configuré dans le portail D'approvisionnement dans ce nouveau dossier. nous sommes maintenant à deux pas de pouvoir exécuter xcodebuild à partir de la ligne de commande comme jenkins, et donc cela signifie que nous sommes également proches pour être en mesure d'obtenir le CI Jenkins en cours d'exécution constructions.
  5. security unlock-keychain -p <keychain password>
  6. xcodebuild -target MyTarget -sdk iphoneos

maintenant nous obtenons une construction réussie à partir d'une ligne de commande lors de la connexion en tant que démon jenkins, donc si nous créons un projet de style libre et ajoutons ces deux dernières étapes (#5 et #6 ci-dessus) nous serons en mesure d'automatiser la construction de notre projet iOS!

ce n'est peut-être pas nécessaire, mais j'ai senti mieux définir jenkins UserShell retour à / usr/bin / false après que j'ai eu avec succès toute cette configuration. Suis-je paranoïaque?

problème 4: porte-clés par défaut toujours pas disponible!

( EDIT: j'ai posté les modifications apportées à ma question, redémarré pour m'assurer que ma solution a été de 100%, et bien sûr, je l'avais laissé de côté une étape )

, Même après toutes les étapes ci-dessus, vous aurez besoin de modifier le Lancement du Démon plist dans /Library/LaunchDaemons/org.jenkins-ci.plist comme indiqué dans cette réponse . Veuillez noter qu'il s'agit également d'un openrdar bug .

il devrait ressembler à ceci:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>EnvironmentVariables</key>
        <dict>
                <key>JENKINS_HOME</key>
                <string>/Users/Shared/Jenkins/Home</string>
        </dict>
        <key>GroupName</key>
        <string>daemon</string>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>org.jenkins-ci</string>
        <key>ProgramArguments</key>
        <array>
                <string>/bin/bash</string>
                <string>/Library/Application Support/Jenkins/jenkins-runner.sh</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>UserName</key>
        <string>jenkins</string>
        <!-- **NEW STUFF** -->
        <key>SessionCreate</key>
        <true />
</dict>
</plist>

avec cette configuration, je recommande également le plugin Xcode pour Jenkins , ce qui rend la configuration du script xcodebuild un peu plus facile. À ce stade, je recommande également la lecture les pages de manuel pour xcodebuild - enfer vous l'avez fait si loin en Terminal, non?

cette configuration n'est pas parfaite, et tout conseil ou aperçu est grandement apprécié.

j'ai eu du mal à choisir une réponse" correcte " puisque ce que je suis venu à utiliser pour résoudre mon problème était une collection d'à peu près tout le monde. J'ai essayé de donner à tout le monde au moins un vote positif, mais attribuer la réponse à Simon parce qu'il a répondu la plupart du temps la question originale. En outre, Sami Tikka mérite beaucoup de crédit pour ses efforts pour obtenir Jenkins de travailler à travers AppleScript comme un simple ol' OS X app. Si vous êtes seulement intéressé à obtenir Jenkins et aller rapidement dans votre session d'utilisateur (c.-à-d. pas en tant que serveur sans tête) sa solution est beaucoup plus Mac-like.

j'espère que mes efforts susciteront d'autres discussions, et aideront la prochaine pauvre âme qui vient penser qu'ils peuvent obtenir Jenkins CI installation pour leurs projets iOS en un week-end à cause de toutes les choses merveilleuses qu'ils ont entendu à ce sujet.


Mise À Jour: 9 Août 2013

avec tant de révocations et de favoris, j'ai pensé revenir à cela 18 mois plus tard avec quelques brèves leçons apprises.

Leçon 1: Ne pas exposer Jenkins à l'internet public

à la WWDC 2012, j'ai posé cette question aux ingénieurs de Xcode et OS X Server. J'ai reçu une cacophonie de "ne fais pas ça!"de quelqu'un, j'ai demandé. Ils ont tous convenu qu'un processus de construction automatisé était génial, mais que le serveur ne devrait être accessible que sur le réseau local. Les ingénieurs du serveur OS X ont suggéré d'autoriser l'accès à distance via VPN.

Leçon 2: Il y a de nouvelles options d'installation maintenant

j'ai récemment donné un CocoaHeads parler de mon expérience Jenkins, et à ma grande surprise j'ai trouvé quelques nouvelles méthodes d'installation - Homebrew et même une Bitnami Mac App Store version. Ces sont certainement la peine de vérifier. Jonathan Wright a un résumé détaillant obtenir des Homebrew Jenkins de travail .

Leçon 3:

il est assez clair d'après le post original que je ne suis ni un administrateur système, ni un expert en sécurité. Le bon sens des choses privées (porte-clés, justificatifs d'identité, certificats, etc.) me mettait mal à l'aise de mettre ma boîte Jenkins sur internet. Nick Arnott à potentiel négligé a pu confirmer mon heebie-jeebies assez facilement dans cet article .

TL; DR

ma recommandation aux autres qui cherchent à automatiser leur processus de construction a changé au cours des 18 derniers mois. Assurez-vous que votre machine Jenkins est derrière votre pare-feu. Installez et mettez Jenkins en place comme un utilisateur Jenkins dédié soit en utilisant l'installateur, Bitnami Mac App Store version, AppleScript de Sami Tikka, etc; cela résout la plupart des maux de tête que je détaille ci-dessus. Si vous avez besoin d'un accès à distance, configurer les services VPN sur le serveur OS X prend dix minutes top chrono. J'utilise cette configuration depuis plus d'un an et j'en suis très heureux. Bonne chance!

104
demandé sur Community 2012-02-12 03:57:28

11 réponses

Les porte-clés

doivent être déverrouillés avant de pouvoir être utilisés. Vous pouvez utiliser security unlock-keychain pour déverrouiller. Vous pouvez le faire de manière interactive (safer) ou en spécifiant le mot de passe sur la ligne de commande (unsafe), par exemple:

security unlock-keychain -p mySecretPassword...

évidemment, mettre cela dans un script compromet la sécurité de ce porte-clés, si souvent les gens mettent en place un porte-clés individuel avec seulement les justificatifs d'identité de signature pour minimiser de tels dommages.

typiquement dans Terminal le le porte-clés est déjà déverrouillé par votre session, puisque le porte-clés par défaut est déverrouillé lors de la connexion, donc vous n'avez pas besoin de le faire. Cependant, tout processus qui ne s'exécute pas dans votre session n'aura pas de porte-clés déverrouillé même s'il vous a en tant qu'utilisateur (le plus souvent cela affecte ssh , mais aussi tout autre processus).

27
répondu Simon Urbanek 2012-02-12 03:59:55

supposons que vous vouliez aussi faire une distribution ad hoc par L'intermédiaire de Jenkins, cela nécessite que Jenkins ait accès à un certificat de Distribution, et à l'identité de l'administrateur de l'équipe, en plus des profils d'approvisionnement.

utilisant une identité exportée dans A.cer fichier, vous pouvez programmatically l'importer comme si, le-A Commutateur est de permettre à tous les programmes d'accéder à cette entrée. Vous pouvez aussi utiliser plusieurs commutateurs -T /path/to/program pour autoriser codesign et xcodebuild accès.:

$ security import devcertificate.cer -k jenkins.keychain -A

bien sûr, nous devrions aussi avoir le certificat D'Apple WWDCRA, importé à peu près de la même manière:

$ security import AppleWWDRCA.cer -k jenkins.keychain -A

Cependant, nous avons aussi besoin de la clé privée pour le devcertificate.cer . Pour ce faire, vous devez exporter la clé privée correspondante comme une .p12-clés et de définir un mot de passe. Mettez-le quelque part où vous pouvez y accéder à partir de votre shell Jenkins, déverrouiller le porte-clés, et l'importer:

$ security unlock-keychain -p YourKeychainPass jenkins.keychain
$ security import devprivatekey.p12 -k login.keychain -P ThePasswordYouSetWhenExporting -A

importation le certificat de distribution fonctionne de la même manière. Je ne sais pas pourquoi vous avez besoin de déverrouiller le porte-clés pour importer un .p12 et pas pour un .cer, mais bien.

vous aurez également besoin d'accéder aux profils de provisionnement, je vais éditer ces instructions dans ce post sous peu.

12
répondu Zsub 2012-07-18 10:44:40

pour changer le mot de passe, vous pouvez utiliser sudo passwd jenkins <new-pw> . Cependant, je pense qu'il serait préférable d'utiliser la commande dscl pour changer le mot de passe.

dans mon installation jenkins (installateur officiel) avait un utilisateur shell /usr/bin/false. Le changer pour bash a résolu le problème de ne pas pouvoir se connecter:

sudo dscl . -change /Users/jenkins UserShell /usr/bin/false /bin/bash

vous devriez maintenant pouvoir vous connecter avec su jenkins .

5
répondu Ivo Dancet 2012-03-07 08:41:06

j'ai eu le même problème et j'ai cherché pendant un certain temps une réponse. Voici une chose que j'ai appris.

j'exécute jenkins en tant qu'utilisateur de jenkins, utilisateur créé par l'installateur, et comme tout le monde l'a mentionné, il n'a pas accès au même porte-clés que votre utilisateur normal. Au lieu d'essayer de me connecter en tant qu'utilisateur de jenkins, j'ai créé un second projet de compilation qui a simplement une étape de compilation qui est "Execute Shell" dans laquelle j'exécute commandes que je veux tester en tant qu'utilisateur de jenkins.

une fois que j'ai eu cette configuration, je pouvais exécuter la commande

security list-keychains

Et cela m'a révélé que la seule chose que jenkins pouvait voir, c'était le trousseau du système.

+ security list-keychains
    "/Library/Keychains/System.keychain"
    "/Library/Keychains/System.keychain"

avec cette connaissance, j'ai alors ouvert L'application de porte-clés D'accès et copié mon certificat "développeur iPhone: xxxx" dans le porte-clés du Système (clic droit, copie à partir de la " connexion" trousseau.)

cela m'a fait passer l'erreur de code de paire certificat/clé privée, mais en a ouvert une autre avec le profil de provision (semble comme un problème similaire, mais différent).

4
répondu brianestey 2012-02-28 05:52:51

j'ai utilisé le plugin Xcode pour construire l'application iOS. Dans la configuration d'un projet.

choisir Ajouter une étape de génération > Xcode > signature de code et OS X trousseau d'options.

cochez la case 151930920" déverrouiller le porte-clés et ajoutez ce qui suit (pour des exemples):) enter image description here

parfois, si j'obtiens l'erreur

erreur de signe de Code: ...

je vais rouvrir Jenkins et entrer mot de passe à nouveau pour déverrouiller

4
répondu biolinh 2014-08-13 04:23:26

pour les personnes ayant des problèmes avec les porte-clés, je vous recommande d'essayer mon installateur Jenkins alternative à https://github.com/stisti/jenkins-app , téléchargements à https://github.com/stisti/jenkins-app/downloads

Jenkins.app exécute Jenkins dans votre session d'utilisateur, de sorte que les problèmes d'accès au porte-clés ne sont pas un problème:)

3
répondu sti 2012-03-27 20:41:59

si vous avez sudo, vous pouvez utiliser passwd pour changer le mot de passe de L'utilisateur Jenkins. Vous obtiendrez le mot de passe de Jenkins.

aussi, je ne suis pas sûr que ce soit le problème pour vous, mais le Script ANT que j'utilise via Jenkins a ceci:

<target name="unlock_keychain">
    <exec executable="security">
        <arg value="-v"/>
        <arg value="unlock-keychain"/>          
        <arg value="-p"/>
        <arg value="<My Password>"/>
        <arg value="/Users/macbuild/Library/Keychains/login.keychain"/>
    </exec>
</target>
2
répondu Feasoron 2012-02-15 21:07:51

pour une raison inconnue, l'utilitaire" security " ne marchait pas pour moi sur Lion avec L'installation de Jenkins.

après " sudo su jenkins "il a été en mesure de créer un nouveau porte-clés, mais en silence ignoré tous" default-keychain-s... les commandes " ou "déverrouillage" renvoient zéro statut de sortie et n'impriment rien sur la console. La liste par défaut ou les porte-clés de connexion ne donnaient rien, la liste de recherche des porte-clés ne contenait que le porte-clés du système, et je ne pouvais pas changer cela quoi que je tape.

après que je me suis connecté au bureau de cet utilisateur et a lancé L'utilitaire de Porte-Clés, il a fait Afficher mon porte-clés créé et après que tout a fonctionné comme décrit dans les postes supérieurs.

je me demande si le comportement initial des porte-clés a changé chez Lion, ou est-ce que je manque quelque chose?

1
répondu jazzcat 2012-07-24 16:22:47

j'ai ajouté la clé privée et publique pour l'entreprise au porte-clés. J'ai ajouté les profils de fourniture pour la production que je vais construire.

comme cet utilisateur n'avait pas de compte, je me suis connecté à devcenter avec mon compte. J'ai téléchargé les certs d'approvisionnement et je les ai chargés dans Xcode.

Je n'ai pas ajouté de cert spécifiquement pour le compte build role, ex. Jenkins.

j'ai ajouté ceci au script de construction: sécurité déverrouiller-porte-clés p mySecretPassword comme ci-dessus, mais...

j'ai créé un fichier ~/.ssh / mypass et ajouter le mot de passe au fichier.

alors la commande devient: la sécurité de déverrouillage-porte-clés p cat ~/.ssh/mypass

fonctionne comme un champion. Je reçois le fichier ipa, il se charge sur app central et fonctionne sur l'appareil.

0
répondu mpechner 2013-08-28 22:50:34

pourrait aussi installer et lancer JenkinsCI en tant qu'utilisateur OS X au lieu d'un démon:

  1. installer jenkins en utilisant l'installateur officiel ( https://jenkins-ci.org / )
    • Cliquez sur suivant
    • Cliquez Sur "Personnaliser"
    • Désélectionner "lancer au démarrage comme "jenkins" - * IMPORTANT * cette option permet normalement une tête jenkins qui ne fonctionne pas bien avec porte-clés
  2. lancement http://127.0.0.1:8080
    • vérifier qu'il NE se lance PAS
    • peut-être besoin d'arrêter de jenkins sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
  3. double clic /Applications/Jenkins/jenkins.war
    • bien sûr, cela devrait être automatisé pour démarrer @ start up
  4. ouvert http://127.0.0.1:8080
    • vérifiez que c'est maintenant en cours d'exécution
0
répondu scotopic 2014-03-26 15:37:12

pour résoudre ce problème, essayez de vous connecter à http://appleid.apple.com et mettez à jour vos questions de sécurité.

ça m'a aidé.

0
répondu Vlad 2018-05-07 08:54:32