Jenkins在OS X上:xcodebuild给出代码签名错误


107

摘要:

使用最新的安装程序(截至1.449-2012年3月9日),在OS X上设置Jenkins变得非常容易,但是,管理代码签名的过程仍然非常困难,没有简单的答案。

动机:

运行无头CI服务器,该服务器遵循在OS X上运行服务的常见最佳实践(此处以通俗的语言进行了解释)。

背景:

处理:

通过OS X 安装程序包安装Jenkins CI 。对于“安装类型”步骤,单击“自定义”按钮,然后选择“以'jenkins身份启动”。

讨论:

此时的天真期望是,带有构建脚本的自由样式项目xcodebuild -target MyTarget -sdk iphoneos应该可以工作。如该帖子的标题所示,它不是,并且失败并显示:

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

很明显需要发生什么-您需要在默认的钥匙串中添加有效的代码签名证书和私钥。在研究如何实现这一目标时,我没有找到一种不会使系统处于一定程度的漏洞的解决方案。

问题1:jenkins守护程序没有默认的钥匙串

sudo -u jenkins security default-keychain ...产生“找不到默认钥匙串”

正如Ivo Dancet在下面指出的那样,默认情况下,jenkins守护程序的UserShell设置为/ usr / bin / false(我认为这是一个功能,而不是错误)。按照他的回答将UserShell更改为bash。然后,您可以使用sudo su jenkins以jenkins用户身份登录并获得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

好,太棒了。现在,我们有了一个默认的钥匙串。让我们继续吧?但是,首先,为什么我们还要打扰默认钥匙串?

在整个研究过程中,我阅读的几乎所有答案,建议或对话都表明,应该将他们的代码签名证书和密钥丢到系统钥匙串中。如果您security list-keychains在Jenkins中作为自由样式项目运行,则将看到唯一可用的钥匙串是系统钥匙串。我认为大多数人想到了将证书和密钥放入其中的想法。但是,这似乎是一个非常糟糕的主意-特别是考虑到您需要使用密码创建纯文本脚本来打开钥匙串

问题2:添加代码签名证书和私钥

这就是我真正开始变得娇气的地方。我有一种直觉,我应该创建一个新的专用于詹金斯的公共/私人密钥。我的想法是,如果jenkins守护程序受到威胁,那么我可以轻松地在Apple的Provisioning Portal中吊销证书,并生成另一个公钥/私钥。如果我为我的用户帐户和Jenkins使用相同的密钥和证书,那么如果jenkins服务受到攻击,则意味着更加麻烦(损坏?)。

指向Simon Urbanek的答案,您将使用纯文本密码从脚本中解锁钥匙串。在jenkins守护程序的钥匙串中保留“一次性”证书和钥匙以外的任何东西似乎是不负责任的。

我对任何相反的讨论都非常感兴趣。我是否过于谨慎?

为了在Terminal中创建新的CSR作为jenkins守护进程,我做了以下工作...

  1. sudo su jenkins
  2. certtool r CertificateSigningRequest.certSigningRequest 系统会提示您输入以下内容(其中大多数是我对正确答案所作的有根据的猜测;您有更好的见解吗?请分享。)...
    • 输入密钥和证书标签:
    • 选择算法:(r对于RSA)
    • 以位为单位输入密钥大小: 2048
    • 选择签名算法:(5用于MD5)
    • 输入挑战字符串:
    • 然后是有关RDN的一系列问题
  3. 使用新的Apple ID将生成的CSR文件(CertificateSigningRequest.certSigningRequest)提交到Apple的Provisioning Portal
  4. 批准请求并下载.cer文件
  5. security unlock-keychain
  6. security add-certificate ios_development.cer

这使我们更近了一步...

问题3:配置配置文件和钥匙串解锁

我在Provisioning Portal中创建了一个特殊的配置文件,以供CI使用,希望如果发生一些问题,我可以将影响减小一些。最佳做法还是过于谨慎?

  1. sudo su jenkins
  2. mkdir ~/Library/MobileDevice
  3. mkdir ~/Library/MobileDevice/Provisioning\ Profiles
  4. 将您在Provisioning Portal中设置的供应配置文件移动到该新文件夹中。现在,距离能够以jenkins的形式从命令行运行xcodebuild尚有两步之遥,这意味着我们也即将获得运行Jenkins CI的构建。
  5. security unlock-keychain -p <keychain password>
  6. xcodebuild -target MyTarget -sdk iphoneos

现在,当以jenkins守护程序身份登录时,可以从命令行获得成功的构建,因此,如果我们创建一个自由样式项目并添加最后两个步骤(上面的#5和#6),我们将能够自动构建我们的iOS项目!

可能没有必要,但是在我成功完成所有设置后,我感觉最好将jenkins UserShell设置回/ usr / bin / false。我是偏执狂吗?

问题4:默认钥匙串仍然不可用!

编辑:我将编辑内容发布到我的问题,重新启动以确保我的解决方案是100%,当然,我省去了一步

即使完成了上述所有步骤,您也需要按照此答案中的说明在/Library/LaunchDaemons/org.jenkins-ci.plist上修改Launch Daemon plist 。请注意,这也是openrdar错误

它看起来应该像这样:

<?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>

通过此设置,我还将推荐用于JenkinsXcode插件,它使设置xcodebuild脚本更加容易。在这一点上,我还建议您阅读xcodebuild的手册页-到此为止,您在Terminal中做到了,对吧?

此设置不是完美的,非常感谢您提供任何建议或见解。

我很难选择一个“正确”的答案,因为我用来解决问题的方法是收集几乎每个人的意见。我试图至少给每个人一个投票,但将答案授予西蒙,因为他主要回答了原始问题。此外,萨米· 蒂卡Sami Tikka)为使詹金斯(Jenkins)通过AppleScript作为普通的OS X应用程序而付出的努力值得称赞。如果您只想让Jenkins起来并在用户会话中快速运行(即不作为无头服务器),则他的解决方案更像Mac。

我希望我的努力能够引发进一步的讨论,并帮助下一个可怜的人,他们认为他们可以在一个周末为他们的iOS项目安装Jenkins CI,因为他们听说过很多奇妙的事情。


更新:2013年8月9日

有了这么多的赞誉和喜爱,我想我会在18个月后回到这里,并吸取一些简短的经验教训。

第1课:不要让詹金斯接触公共互联网

在2012年的WWDC上,我向Xcode和OS X Server工程师提出了这个问题。我听到“不要那样做!”的刺耳声音。我问过的任何人。他们都认为自动构建过程很棒,但是只能在本地网络上访问服务器。OS X Server工程师建议允许通过VPN进行远程访问。

第2课:现在有新的安装选项

我最近在CocoaHeads上介绍了我的詹金斯经历,而令我惊讶的是,我发现了一些新的安装方法-Homebrew甚至Bitnami Mac App Store版本。这些绝对值得一试。乔纳森•赖特(Jonathan Wright)有一个要点,详细说明了让Homebrew Jenkins工作

第3课:不,认真的说,不要将构建箱暴露给互联网

从原始帖子中可以很明显地看出,我既不是系统管理员,也不是安全专家。关于私人物品的常识(钥匙串,证书,证书等)使我对将我的詹金斯盒子放在互联网上感到非常不安。在这篇文章中,《被忽视的潜力》的尼克·阿诺特Nick Arnott)能够很容易地确认我的希比·吉比斯。

TL; DR

在过去的一年半中,我对其他希望自动化构建过程的人的建议发生了变化。确保您的Jenkins机器位于防火墙后面。使用安装程序,Bitnami Mac App Store版本,Sami Tikka的AppleScript等将Jenkins安装并设置为Jenkins专用用户;这解决了我上面详述的大多数头痛问题。如果需要远程访问,则在OS X Server中设置VPN服务需要十分钟的时间。我已经使用此设置一年多了,对此我感到非常满意。祝好运!


10
我很伤心,我只能对这个简洁而完整的有问题的答案进行
投票

Jenkins在OS X Yosemite上的发布中断了某些事情-使用了Jenkins的安装程序。
2014年

将您的证书移至系统钥匙串并感到高兴;)
朱利安·F·韦纳特

Answers:


30

在使用钥匙串之前,必须先对其进行解锁。您可以security unlock-keychain用来解锁。您可以以交互方式(更安全)或通过在命令行中指定密码(不安全)来执行此操作,例如:

security unlock-keychain -p mySecretPassword...

显然,将其放入脚本会损害该钥匙串的安全性,因此人们经常使用仅签名凭证来设置单个钥匙串,以最大程度地减少此类损坏。

通常,Terminal钥匙串已被您的会话解锁,因为默认的钥匙串在登录时已解锁,因此您无需这样做。但是,未在会话中运行的任何进程都不会解锁钥匙串,即使它具有您作为用户的权限(最常见的情况是ssh,也会影响其他进程)。


但是,我还很难加载系统钥匙串以外的任何钥匙串。security unlock-keychain -p password -k /path/codesign.keychain不起作用。
edelaney05

您是否使用了上面示例中的默认钥匙串?请注意,对于自定义钥匙串,您需要先将其设置为位于搜索路径上,因此请首先尝试使用默认钥匙串。另外请注意,没有-k论据,unlock-keychain因此您尝试执行的操作似乎都不正确(请参阅参考资料security help unlock-keychain)。
Simon Urbanek

我尝试了一些不同的方法,但最终又回到了同一地点。我编辑了问题,希望它更清楚了吗?
edelaney05 '02

它与原始问题完全不同...首先,您应以jenkins身份登录(例如通过sudo -u jenkins bash),并检查您是否对整个路径都具有权限。您做了很多您没有说过的事情(例如dscl用来创建用户),所以您确实是一个人。您还将需要检查起始位置设置(取决于您是否设置了外壳,您可以sudo -u jenkins -i用来获取相应的登录设置)。
Simon Urbanek '02

12

假设您还希望通过Jenkins进行临时分发,则除了提供配置文件之外,Jenkins还必须有权访问分发证书和团队管理员身份。

使用.cer文件中的导出身份,您可以像这样以编程方式导入它,-A开关允许所有程序访问此条目。另外,您可以使用多个-T /path/to/program开关来允许codesignxcodebuild访问。

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

当然,我们还应该拥有以大致相同的方式导入的Apple WWDCRA证书:

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

但是,我们还需要的私钥devcertificate.cer。为此,您需要将相应的私钥导出为.p12密钥并设置密码。将其放置在您可以从Jenkins shell进行访问,解锁钥匙串并导入的位置:

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

导入分发证书的工作方式相同。我不知道为什么您需要解锁钥匙串才能导入.p12而不是.cer,但是很好。

您还需要访问配置文件,我很快将这些说明编辑到这篇文章中。


1
您能更新配置文件访问说明吗?
路加福音


5

我遇到了同样的问题,并且一直在寻找答案。这是我学到的一件事。

我正在以jenkins用户(由安装程序创建的用户)运行jenkins,正如其他所有人所提到的那样,他没有访问权限与普通用户相同。我没有尝试以jenkins用户身份登录,而是创建了第二个构建项目,该项目仅具有一个构建步骤,即“ Execute Shell”,在其中运行要作为jenkins用户测试的命令。

设置好之后,我可以运行命令

security list-keychains

这告诉我,詹金斯唯一能看到的就是系统钥匙串。

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

有了这些知识,我便打开了钥匙串访问应用程序,并将我的“ iPhone Developer:xxxx”证书复制到了系统钥匙串中(右键单击,从“登录”钥匙串中复制)。

这使我通过了证书/私钥对代码签名错误,但又打开了一个具有配置文件的文件(似乎是类似但不同的问题)。


我遇到了相同的配置文件问题,对如何解决这个问题有何想法?
Santthosh

2
我发现Jenkins用户的配置文件存储在“ / Users / Shared / Jenkins / Library / MobileDevice / Provisioning Profiles”中,因此在构建过程中迈出了一步,将配置文件从git repo内部复制到该位置。这使我可以更新配置文件并将其推送到SCM中,Jenkins会自动选择该更改。
brianestey'4

如果您将login.keychain复制到您的jenkins钥匙串库中,则需要将其锁死,以便jenkins用户可以对其进行安全解锁
ganoro 2012年

1
您是英雄,我两天都在头发上

5

要更改密码,您可以使用sudo passwd jenkins <new-pw>。但是我认为最好使用dscl命令更改密码。

在我的安装中,jenkins(官方安装程序)的用户外壳为/ usr / bin / false。将其更改为bash解决了无法登录的问题:

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

您现在应该可以使用登录su jenkins


这对我非常有帮助-我create-keychain在jenkins用户无法使用的命令中遇到了类似的问题。运行此命令似乎可以解决问题。
lxt 2012年

当我运行命令来更改詹金斯用户密码时,系统会要求我输入当前密码。我不知道这是什么,我无法按Enter键。有什么建议?
CMVR 2013年

4

我已经使用Xcode插件来构建iOS应用。在配置项目时。

选择添加构建步骤> Xcode>代码签名和OS X钥匙串选项。

勾选解锁钥匙串框并添加如下内容(例如) 在此处输入图片说明

somtimes,如果我得到错误

代码签名错误:...

我将重新打开詹金斯,然后再次输入密码以解锁


3

对于具有与钥匙串问题的人,我建议你试试我的替代詹金斯在安装https://github.com/stisti/jenkins-app,下载在https://github.com/stisti/jenkins-app/downloads

Jenkins.app在您的用户会话中运行Jenkins,因此钥匙串访问问题不是问题:)


令人担心的是,这个Jenkins用户位于用户空间中而不是守护程序空间中……因此,如果攻击者能够破坏您的Jenkins用户,则他们将拥有对您计算机的完全访问权限。
edelaney12年5

这可能会解决我遇到的问题。问题是我有一个现有的Jenkins安装(反之亦然),并且我不想丢失我的所有构建-等等。在casE中会发生什么?
Mike S

2

如果您使用sudo,则可以使用passwd更改Jenkins用户的密码。然后,您可以获取Jenkins密码。

另外,我不确定这是否是您遇到的问题,但是我通过Jenkins使用的ANT脚本有以下问题:

<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>

1
似乎您在“ macbuild”用户下设置了Jenkins;我假设此用户是用户而不是守护程序。我绝对知道(现在),钥匙串需要通过命令行args解锁(请参阅Simon Urbanek的评论),但是我仍然不确定如何为jenkins守护程序创建默认钥匙串。
edelaney05 '02

1

出于某种原因,在新安装Jenkins的Lion上,“安全”实用程序不适用于我。

在“ sudo su jenkins”之后,它能够创建新的钥匙串,但是默默地忽略了所有“ default-keychain -s ...”或“ unlock”命令,这些命令返回零退出状态并且不打印任何内容到控制台。列出默认或登录钥匙串没有任何效果,钥匙串搜索列表仅包含系统钥匙串,无论我键入什么,我都无法更改。

在我登录到该用户的桌面并启动了Keychain Utility之后,它确实显示了我创建的钥匙串,然后一切如上一篇文章所述进行了。

我想知道Lion中的某些初始钥匙串行为是否已更改,还是我错过了一些东西?


我在“干净”的Lion安装中执行了上述步骤,因此在您进入之前可能存在安全问题?另一种可能性是自从我最初发布以来已经进行了安全性/ OS X更新?
edelaney12年5

0

我将公司的私钥和公钥添加到了钥匙串中。我添加了将要构建的产品的配置文件。

由于该用户没有帐户,因此我使用我的帐户登录了devcenter。下载了配置证书并将其加载到Xcode中。

我没有专门为构建角色帐户添加证书,例如。詹金斯。

我确实将其添加到构建脚本中:如上所述,安全性解锁钥匙串-p mySecretPassword,但是...

我创建了一个文件〜/ .ssh / mypass并将密码添加到该文件中。

然后,该命令将变为:security unlock-keychain -p cat ~/.ssh/mypass

构建工作像冠军一样。我得到了ipa文件,该文件加载到应用程序中央并在设备上运行。


0

还可以以OS X用户(而不是守护程序)的身份安装并启动JenkinsCI:

  1. 使用官方安装程序(https://jenkins-ci.org/) 安装jenkins
    • 点击下一步
    • 点击“自定义”
    • 取消选择“以'jenkins'的身份启动”- *重要*该选项通常允许无头的jenkins,这种钥匙头无法与钥匙串访问配合使用
  2. 发射 http://127.0.0.1:8080
    • 验证它不会启动
    • 可能需要停止詹金斯 sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
  3. 双击 /Applications/Jenkins/jenkins.war
    • 当然这应该自动启动@启动
  4. 打开 http://127.0.0.1:8080
    • 验证它现在正在运行

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.