애플 공증(notarization) 기록

#Apple#Notarization
• • •

개요

일렉트론으로 개발한 앱을 macOS로 출시하는 과정이 꽤나 까다로웠다. 서명, 공증, 스탬핑 과정을 거쳐야 한다.

  • 코드 서명(Code Signing)
    • 앱 리소스에 디지털 서명을 추가하는 과정
    • macOS Gatekeeper가 앱의 출처와 무결성을 확인하도록 보장하기 위한 목적
    • 서명이 없으면 "알 수 없는 개발자" 경고가 발생하고 이를 실행하려면 별도 시스템 설정이나 우회 필요
    • 자동 업데이트 기능 구현 시 필수사항
    • Apple Developer Program 가입 필요
  • 공증(Notarization)
    • Apple이 애플리케이션의 코드 서명 여부, 악의적 콘텐츠 유무를 확인하는 과정
    • Gatekeeper가 앱을 신뢰할 수 있는 소프트웨어로 인식하도록 티켓 부여
    • macOS 10.15(Catalina) 이후 필수. 공증 없으면 앱 실행 차단 가능
    • Apple ID(애플 계정 ID), Password(App Specific Password), Team ID 필요
  • 스탬프 (Stapling)
    • 공증 티켓을 앱 패키지에 직접 첨부하는 과정
    • 오프라인 환경에서도 Gatekeeper가 공증 상태 확인 가능
    • 사용자 설치 시 네트워크 연결 불필요, 배포 안정성 향상
    • xcrun stapler staple 커맨드로 첨부 가능(Electron Builder가 자동으로 진행)

Electron Builder 설정

./electron-builder.yml
appId: com.your-app-id.app
productName: Your Product Name
files:
  - dist/**/*
  - dist-electron/**/*
directories:
  buildResources: public
  output: release
mac:
  target:
    target: dmg
    arch: universal
  category: public.app-category.healthcare-fitness
  entitlements: build/entitlements.mac.plist
  entitlementsInherit: build/entitlements.mac.plist
  hardenedRuntime: true
  gatekeeperAssess: false
  notarize: true

hardenedRuntime은 공증을 위한 필수 설정으로, 다음과 같은 보안 관련 제약 적용

  • 메모리 보호: 실행 가능한 메모리에 대한 쓰기 권한을 제한하여 코드 주입 공격 방지
  • 리소스 접근 제한: 카메라, 마이크, 파일 시스템, 네트워크 등 민감한 리소스에 대한 접근을 명시적으로 제어
  • 디버깅 제한: ptrace와 같은 디버깅 도구를 통한 프로세스 추적 차단
  • JIT(Just-In-Time) 컴파일 제한: JIT 컴파일을 사용하는 코드 실행 제한(예: 일부 JavaScript 엔진)
  • 시스템 무결성 보호(SIP): 시스템 파일 및 프로세스에 대한 무단 접근 방지

위 제약 사항으로 인해 필요한 권한이 있다면 entitlements에 추가 설정 필요

권한 설정

entitlements.mac.plist 파일은 앱의 권한을 정의하는데 사용된다. 너무 광범위하게 설정하는 경우 배포 후 앱이 실행되는 현상이 있다고 하니 필요한 내용만 설정하는 것이 좋다.

기타 설정

package.json
{
  "electron:publish": "npm run build && npm run build:electron && electron-builder --config electron-builder.yml"
}
.zshrc
export APPLE_ID="your apple account"
export APPLE_APP_SPECIFIC_PASSWORD="abcd-abcd-abcd-abcd"
export APPLE_TEAM_ID="3DFWE4CSC"
터미널에 직접 export해도 됨

유용한 커맨드

서명 여부 확인

성공 출력
> codesign --verify --deep --strict --verbose=2 /path/to/YourApp.app

# --- 중략 ---

Your Product.app: valid on disk
Your Product.app: satisfies its Designated Requirement
히스토리 확인
xcrun notarytool history \
  --apple-id "your-apple-id@com" \
  --team-id "your-team-id" \
  --password "your-app-specific-password"
로그 확인
> xcrun notarytool log ($job-id) \
  --apple-id "your-apple-id@com" \
  --team-id "your-team-id" \
  --password "your-app-specific-password"
job-id는 히스토리에서 볼 수 있다

공증 결과 확인

성공 출력
> spctl -a -vvv Your\ Product.app
 
Your Product.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Your Name (12HAGCQ9Z2)

staple 부착

> stapler staple Your\ Product.app
Electon Builder는 자동으로 해줌

staple 여부 확인

성공 출력
> stapler validate Your\ Product.app

\[\[Processing\]\]: /path/to/Your Product.app
The validate action worked!

키체인 저장하기

> xcrun notarytool store-credentials \
  --apple-id "your-apple-id@com" \
  --team-id "your-team-id" \
  --password "your-app-specific-password"

Profile name:
my-profile-name
Validating your credentials...
Success. Credentials validated.
Credentials saved to Keychain.
To use them, specify `--keychain-profile "my-profile-name"`
> xcrun notarytool history --keychain-profile "my-profile-name"

확장 속성 확인

xattr -l /path/to/YourApp.app
NOTE

확장 속성은 macOS 파일 시스템에서 파일이나 폴더에 추가적인 메타데이터를 저장하는 기능

  • 시스템 보안 및 권한: 코드 서명, 샌드박싱, Gatekeeper 관련 정보 저장
  • Finder 메타데이터: 파일에 추가된 태그, 주석, 또는 다운로드 출처 정보
  • 애플리케이션 설정: 특정 앱이 파일에 연결한 사용자 정의 데이터
  • Gatekeeper 및 Notarization: 애플리케이션이 다운로드된 출처(예: 인터넷) 또는 Notarization 상태를 기록
  • 확장 속성은 macOS의 보안 및 사용자 경험을 강화하는 데 중요한 역할을 하며, 특히 애플리케이션 배포 및 실행 시 Gatekeeper, 코드 서명, 샌드박싱과 관련된 정보를 포함

이슈 기록

서명이 InProgress로 남아있던 문제

  • Electon Builder 설정으로 코드 서명을 진행할 때 InProgress에서 코드 서명이 끝나지 않는 이슈가 있었음
  • 다음 날까지 코드 서명이 진행 중으로 나온 것을 확인
  • 다른 일정으로 바빠서 며칠이 지난 후 확인했을 때 모두 Accepted된 것을 확인
  • 그 이후로는 잘 되고 있어서 일시적인 현상이라고 생각하고 있음
  • 관련 이슈

배포된 파일이 실행되지 않는 문제

  • 지인 및 개인 노트북으로 이메일 또는 macOS 메모 앱으로 공유 및 설치했을 때 "실행할 수 없음" 팝업과 함께 실행이 안되는 현상이 있었음
  • 여러 커맨드로 서명, 공증, 스탬핑 여부를 확인했으나 모두 정상이었고 관련 설정을 바꾸면서 테스트했으나 처음에는 원인을 찾지 못함
  • 나중에 다운로드한 쪽에서 확장 속성과 공증 여부를 확인해보니 아래와 같이 출력되는 것을 확인
확장 속성 확인
> xattr -l /path/to/YourApp.app
com.apple.provenance:
com.apple.quarantine: 0087;1210fd4c;com.apple.cloud;
공증 여부 확인
> spctl --assess --verbose /path/to/YourApp.app
Your Product.app: File created by an AppSandbox, exec/open not allowed
  • Gatekeeper가 앱이 아닌 앱을 전달하는 방식에 따라 앱 실행을 차단할 수 있음을 인지
  • Google Drive에 올리고 브라우저를 통해 다운로드 받았을 때는 정상 실행 가능
  • 관련 근거를 찾을 수 있는 문서는 아직 찾지 못했으나 같은 커맨드를 실행했을 때 결과는 다음과 같았음
확장 속성 확인
> xattr -l /path/to/YourApp.app
com.apple.macl:
com.apple.provenance:
com.apple.quarantine: 00c1;68220004;Arc;
Arc 브라우저로 다운받았음
공증 여부 확인
> spctl --assess --verbose /path/to/YourApp.app
YourApp.app: accepted
source=Notarized Developer ID

참고

published 9 months ago · last updated 9 months ago