[macos] OS X의 Jenkins : xcodebuild에서 코드 서명 오류 발생

요약:

최신 설치 프로그램을 사용하면 OS X에서 Jenkins를 설정하는 것이 훨씬 쉬워 졌지만 ( 1.449-2012 년 3 월 9 일 기준 ), 코드 서명 프로세스를 관리하는 것은 간단한 대답없이 여전히 매우 어렵습니다.

자극:

OS X에서 서비스를 실행하기위한 일반적인 모범 사례를 따르는 헤드리스 CI 서버를 실행합니다 ( 일부는 여기에서 일반 언어로 설명 됨 ).

배경:

방법:

OS X 설치 프로그램 패키지 를 통해 Jenkins CI를 설치합니다 . “설치 유형”단계에서 Customize 버튼을 클릭하고 “Start at boot as ‘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 : 젠킨스 데몬에 대한 기본 키 체인 없음

sudo -u jenkins security default-keychain
… “기본 키 체인을 찾을 수 없습니다”가 나타납니다.

Ivo Dancet가 아래에서 지적했듯이 , UserShell은 기본적으로 jenkins 데몬에 대해 / 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-keychainsJenkins에서 자유 스타일 프로젝트로 실행 하면 사용 가능한 유일한 키 체인이 시스템 키 체인임을 알 수 있습니다. 나는 그것이 대부분의 사람들이 인증서와 키를 거기에 넣는 아이디어를 생각 해낸 곳이라고 생각합니다. 그러나 이것은 매우 나쁜 생각처럼 보입니다. 특히 키 체인을 열려면 암호가있는 일반 텍스트 스크립트를 만들어야 한다는 점 감안 하면 더욱 그렇습니다 .

문제 2 : 코드 서명 인증서 및 개인 키 추가

이것은 내가 정말 비꼬기 시작하는 곳입니다. Jenkins와 함께 사용하기 위해 고유 한 새 공개 / 개인 키를 만들어야한다는 직감이 있습니다. 내 생각 과정은 jenkins 데몬이 손상되면 Apple의 프로비저닝 포털에서 인증서를 쉽게 취소하고 다른 공개 / 개인 키를 생성 할 수 있다는 것입니다. 내 사용자 계정과 Jenkins에 동일한 키와 인증서를 사용하면 젠킨스 서비스가 공격 당하면 더 많은 번거 로움 (손상?)을 의미합니다.

Simon Urbanek의 대답 을 가리키면 일반 텍스트 암호로 스크립트에서 키 체인을 잠금 해제하게됩니다. 젠킨스 데몬의 키 체인에 “일회용”인증서와 키 이외의 것을 보관하는 것은 무책임한 것처럼 보입니다.

나는 반대되는 어떤 논의에 매우 관심이 있습니다. 지나치게 조심하고 있습니까?

터미널에서 jenkins 데몬으로 새 CSR을 만들기 위해 다음을 수행했습니다.

  1. sudo su jenkins
  2. certtool r CertificateSigningRequest.certSigningRequest 다음을 입력하라는 메시지가 표시됩니다 (이 중 대부분은 정답에 대해 교육적인 추측을했습니다. 더 나은 통찰력이 있습니까? 공유하십시오.) …
    • 키 및 인증서 레이블 입력 :
    • 알고리즘 선택 : r(RSA 용)
    • 키 크기를 비트 단위로 입력하십시오. 2048
    • 서명 알고리즘 선택 : 5(MD5의 경우)
    • 질문 문자열 입력 :
    • 그런 다음 RDN에 대한 많은 질문
  3. 생성 된 CSR 파일 (CertificateSigningRequest.certSigningRequest)을 새 Apple ID로 Apple의 프로비저닝 포털에 제출합니다.
  4. 요청을 승인하고 .cer 파일을 다운로드합니다.
  5. security unlock-keychain
  6. security add-certificate ios_development.cer

이것은 우리를 한 걸음 더 가까이 데려갑니다 …

문제 3 : 프로비저닝 프로파일 및 키 체인 잠금 해제

문제가 발생하면 영향을 조금 더 작게 만들었 으면하는 희망으로 CI와 함께 사용하기 위해 프로비저닝 포털에서 특수 프로비저닝 프로파일을 만들었습니다. 모범 사례입니까, 지나치게 신중합니까?

  1. sudo su jenkins
  2. mkdir ~/Library/MobileDevice
  3. mkdir ~/Library/MobileDevice/Provisioning\ Profiles
  4. 프로비저닝 포털에서 설정 한 프로비저닝 프로파일을이 새 폴더로 이동하십시오. 이제 젠킨스로 명령 줄에서 xcodebuild를 실행할 수있는 두 단계가 남았습니다. 즉, 빌드를 실행하는 Jenkins CI를 가져올 수 있다는 의미이기도합니다.
  5. security unlock-keychain -p <keychain password>
  6. xcodebuild -target MyTarget -sdk iphoneos

이제 젠킨스 데몬으로 로그인했을 때 명령 줄에서 성공적인 빌드를 얻습니다. 따라서 자유형 프로젝트를 만들고 마지막 두 단계 (위의 # 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>

이 설정을 사용하면 Jenkins 용 Xcode 플러그인을 권장 하여 xcodebuild 스크립트를 조금 더 쉽게 설정할 수 있습니다. 이 시점에서 xcodebuild에 대한 man 페이지를 읽어 보는 것도 좋습니다. 터미널에서 여기까지 왔죠?

이 설정은 완벽하지 않으며 조언이나 통찰력을 높이 평가합니다.

내 문제를 해결하기 위해 사용하게 된 것은 거의 모든 사람의 의견을 모아 놓은 것이기 때문에 “정답”을 선택하는 데 어려움을 겪었습니다. 나는 모든 사람에게 적어도 찬성표를 주려고 노력했지만 Simon이 원래 질문에 대부분 답변했기 때문에 Simon에게 답변을 부여합니다. 또한 Sami Tikka 는 Jenkins가 AppleScript를 일반 OS X 앱으로 사용하도록하는 그의 노력에 대해 많은 공로를 인정받을 만합니다. Jenkins를 시작하고 사용자 세션 내에서 빠르게 진행하는 데만 관심이 있다면 (즉, 헤드리스 서버가 아닌) 그의 솔루션은 훨씬 더 Mac과 비슷합니다.

내 노력이 더 많은 토론을 불러 일으키고 그들이들은 모든 멋진 것들 때문에 주말에 iOS 프로젝트를위한 Jenkins CI 설정을 얻을 수 있다고 생각하는 다음 가난한 영혼을 돕길 바랍니다.


업데이트 : 2013 년 8 월 9 일

찬성 투표와 즐겨 찾기가 너무 많아서 18 개월 후에 배운 간단한 교훈과 함께이 문제로 돌아올 것이라고 생각했습니다.

레슨 1 : Jenkins를 공개 인터넷에 노출하지 마십시오

2012 년 WWDC에서 저는이 질문을 Xcode 및 OS X Server 엔지니어에게 가져갔습니다. 나는 “그렇게 하지마!”라는 불협화음을 받았다. 내가 물어 본 사람에게서. 그들은 모두 자동화 된 빌드 프로세스가 훌륭하지만 서버는 로컬 네트워크에서만 액세스 할 수 있어야한다는 데 동의했습니다. OS X Server 엔지니어는 VPN을 통한 원격 액세스 허용을 제안했습니다.

레슨 2 : 이제 새로운 설치 옵션이 있습니다.

저는 최근에 CocoaHeads에서 제 Jenkins 경험에 대해 이야기했고 놀랍게도 Homebrew와 심지어 Bitnami Mac App Store 버전 과 같은 새로운 설치 방법을 발견했습니다 . 이것들은 확실히 확인할 가치가 있습니다. Jonathan WrightHomebrew Jenkins가 작동 하도록하는 요지를 자세히 설명 합니다.

레슨 3 : 아니요, 진지하게, 빌드 박스를 인터넷에 노출하지 마세요

내가 시스템 관리자도 아니고 보안 전문가도 아니라는 것이 원래 게시물에서 분명합니다. private-y 항목 (키 체인, 자격 ​​증명, 인증서 등)에 대한 상식으로 인해 Jenkins 상자를 인터넷에 올리는 것이 매우 불편했습니다. Neglected Potential의 Nick Arnott이 기사 에서 내 heebie-jeebies를 꽤 쉽게 확인할 수있었습니다 .

TL; DR

빌드 프로세스를 자동화하려는 다른 사람들에게 내 추천이 지난 1 년 반 동안 변경되었습니다. Jenkins 시스템이 방화벽 뒤에 있는지 확인하십시오. 설치 프로그램, Bitnami Mac App Store 버전, Sami Tikka의 AppleScript 등을 사용하여 Jenkins를 전용 Jenkins 사용자로 설치하고 설정합니다. 이것은 위에서 설명한 두통의 대부분을 해결합니다. 원격 액세스가 필요한 경우 OS X Server에서 VPN 서비스를 설정하는 데 10 분 정도 걸립니다. 저는이 설정을 1 년 넘게 사용해 왔으며 매우 만족합니다. 행운을 빕니다!



답변

키 체인을 사용하려면 먼저 잠금을 해제해야합니다. security unlock-keychain잠금 해제에 사용할 수 있습니다 . 대화식으로 (안전) 또는 명령 줄에 암호를 지정 (안전하지 않음)하여 수행 할 수 있습니다. 예 :

security unlock-keychain -p mySecretPassword...

분명히 이것을 스크립트에 넣으면 해당 키 체인의 보안이 손상되므로 사람들은 종종 이러한 손상을 최소화하기 위해 서명 자격 증명만으로 개별 키 체인을 설정합니다.

일반적 Terminal으로 키 체인은 로그인시 기본 키 체인이 잠금 해제되므로 세션에 의해 이미 잠금 해제되어 있으므로 그렇게 할 필요가 없습니다. 그러나 세션에서 실행되지 않는 모든 프로세스는 사용자로되어 있어도 키 체인이 잠금 해제되지 않습니다 (가장 일반적으로 ssh, 다른 프로세스에도 영향을 미침 ).


답변

Jenkins를 통해 임시 배포를 수행하려는 경우에도 Jenkins가 프로비저닝 프로필 외에 배포 인증서 및 팀 관리자 ID에 액세스 할 수 있어야합니다.

.cer 파일에서 내 보낸 ID를 사용하여 프로그래밍 방식으로 가져올 수 있습니다. -A 스위치는 모든 프로그램이이 항목에 액세스 할 수 있도록 허용하는 것입니다. 또는 여러 -T /path/to/program스위치를 사용하여 허용 codesign하고 xcodebuild액세스 할 수 있습니다. :

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

물론, 거의 동일한 방식으로 가져온 Apple WWDCRA 인증서도 있어야합니다.

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

그러나 우리는 또한 devcertificate.cer. 이렇게하려면 해당 개인 키를 .p12 키로 내보내고 암호를 설정해야합니다. Jenkins 셸에서 액세스 할 수있는 위치에 넣고 키 체인을 잠금 해제하고 가져올 수 있습니다.

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

배포 인증서 가져 오기도 동일한 방식으로 작동합니다. .cer가 아닌 .p12를 가져 오기 위해 키 체인을 잠금 해제해야하는 이유를 모르겠습니다.

프로비저닝 프로파일에 대한 액세스 권한도 필요합니다. 곧이 게시물에서 해당 지침을 편집하겠습니다.


답변

나는 똑같은 문제를 겪었고 대답을 위해 얼마 동안 주변을 검색했습니다. 여기 제가 배운 한 가지가 있습니다.

나는 jenkins 사용자, 설치 프로그램에서 만든 사용자로 jenkins를 실행하고 있으며 다른 모든 사람들이 일반 사용자와 동일한 키 체인에 액세스 할 수 없다고 언급했습니다. 젠킨스 사용자로 로그인하는 대신 젠킨스 사용자로 테스트 할 명령을 실행하는 “셸 실행”이라는 빌드 단계가있는 두 번째 빌드 프로젝트를 만들었습니다.

설정이 완료되면 명령을 실행할 수 있습니다.

security list-keychains

그리고 이것은 젠킨스가 볼 수있는 유일한 것은 시스템 키 체인이라는 것을 나에게 보여주었습니다.

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

그런 다음 키 체인 접근 앱을 열고 “iPhone Developer : xxxx”인증서를 시스템 키 체인에 복사했습니다 (마우스 오른쪽 버튼을 클릭하고 “로그인”키 체인에서 복사).

이로 인해 인증서 / 개인 키 쌍 코드 서명 오류를 통과했지만 프로비저닝 프로필로 다른 하나를 열었습니다 (비슷하지만 다른 문제처럼 보임).


답변

암호를 변경하려면을 사용할 수 있습니다 sudo passwd jenkins <new-pw>. 그러나 암호를 변경하려면 dscl 명령을 사용하는 것이 더 낫다고 생각합니다.

내 설치에서 jenkins (공식 설치 프로그램)에는 사용자 셸 / usr / bin / false가 있습니다. bash로 변경하면 로그인 할 수없는 문제가 해결되었습니다.

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

이제로 로그인 할 수 있습니다 su jenkins.


답변

Xcode 플러그인을 사용하여 iOS 앱을 빌드했습니다. 프로젝트 구성 중.

고르다 추가 빌드 단계> 엑스 코드> 코드 서명 및 OS X 키 체인 옵션을.

잠금 해제 키 체인 상자와 (예제) 다음과 같이 추가
여기에 이미지 설명 입력

가끔 오류가 발생하면

코드 서명 오류 : …

Jenkins를 다시 열고 암호를 다시 입력하여 잠금을 해제합니다.


답변

키 체인에 문제가있는 사람들을 위해 https://github.com/stisti/jenkins-app 에서 대체 Jenkins 설치 프로그램을 사용해 보는 것이 좋습니다 . https://github.com/stisti/jenkins-app/downloads

Jenkins.app은 사용자 세션에서 Jenkins를 실행하므로 키 체인 액세스 문제는 문제가되지 않습니다. 🙂


답변

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>