一尘不染

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

jenkins

摘要:

使用最新的安装程序(截至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 sujenkins以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的公共/私有密钥。我的想法是,如果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上修改LaunchDaemon 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中做到了,对吧?

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

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

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


更新:2013年8月9日

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

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

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

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

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

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

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

TL; DR

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


阅读 273

收藏
2020-07-25

共1个答案

一尘不染

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

security unlock-keychain -p mySecretPassword...

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

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

2020-07-25