반응형

와일드카드 인증서는 단일 도메인과 모든 하위 도메인을 보호할 수 있는 SSL/TLS 인증서로(*.domain.com), 여러 서브도메인을 한 번에 관리할 수 있다. 와일드카드 인증서를 발급하려면 DNS-01 챌린지를 통해 도메인 소유권을 인증해야 한다. 아쉽게도 시놀로지 나스의 기본 기능만으로는 DNS 레코드를 직접 조작할 수 없기 때문에 와일드카드 인증서를 발급할 수 없다.

 

이 문제는 acme.sh를 사용하면 해결할 수 있다. acme.sh는 DNS 인증 과정을 자동화하여 와일드카드 인증서를 손쉽게 발급하고 갱신할 수 있도록 지원한다. 특히, 시놀로지 나스에서 인증서를 갱신하려면 80/443 포트를 개방해야 하지만, acme.sh는 이러한 포트 개방이 필요 없어서 보안상 훨씬 유리하다. acme.sh의 장점은 다음과 같다. 

 

 

 

시작하기에 앞서


  • Cloudflare에 도메인이 등록되어 있어야 한다.
  • Cloudflare API 토큰 발급이 필요하다. (가이드 포스팅)
  • 시놀로지 나스에 SSH로 접속할 수 있어야 한다. (가이드 포스팅)
  • 인증서는 Let's Encrypt를 통해 발급받는다.
  • DSM 버전 7.2.2-72806

 

 

설정 방법


acme.sh 설치

나스 SSH 접속 후 아래 명령어를 입력한다. "your@email.com" 부분은 본인 이메일 주소로 변경한다.

# 루트 사용자로 전환 (DSM 계정 비밀번호 입력 필요)
sudo su
# 홈 디렉토리로 이동
cd ~

# acme.sh 최신 버전 다운로드
wget https://github.com/acmesh-official/acme.sh/archive/master.tar.gz

# 다운로드 받은 압축 파일 해제
tar xvf master.tar.gz

# acme.sh 디렉터리로 이동
cd acme.sh-master/

# acme.sh 설치
./acme.sh --install \
  --nocron \
  --home /usr/local/share/acme.sh \
  --accountemail "your@email.com"

# 환경 변수 적용
source ~/.profile

 

🔍 acme.sh 명령어 플래그 설명

  • --nocron: 자동 갱신을 위한 크론 작업 비활성
  • --home: acme.sh 홈 디렉터리 지정
  • --accountemail: 인증서 계정 이메일 설정

 

 

DNS 구성

도메인 영역 DNS 편집 권한이 있는 Cloudflare API 토큰 발급 후 아래 명령어를 통해 DNS 환경 변수를 설정한다. "your-token" 값은 Cloudflare API 토큰을 입력하고, "your@email.com" 값은 Cloudlfare 로그인에 사용하는 이메일 주소를 입력한다.

# Cloudflare API 토큰 설정 (DNS 인증에 필요)
export CF_Token="your-token"

# Cloudflare 계정 이메일 설정
export CF_Email="your@email.com"

 

 

인증서 생성

인증서를 발급할 때 첫 번째 -d 플래그에 지정한 값이 기본 도메인이 되고, 해당 도메인 이름을 기준으로 인증서 폴더가 자동으로 생성된다. 

 

예를 들어 첫 번째 -d 플래그에 domain.com, 두 번째 -d 플래그에 *.domain.com을 입력하면 domain.com 이름으로 폴더가 생성된다. 이땐 여러 도메인과 서브도메인을 포함하는 SAN 인증서로 발급된다. 와일드카드 도메인 *.domain.com을 기본 도메인으로 지정할 수도 있다.

 

아래 내용 중 "your-domain.com" 값을 본인 도메인으로 변경한 후 명령어를 실행한다.

# acme.sh가 설치된 디렉터리로 이동
cd /usr/local/share/acme.sh

# 인증서를 발급할 도메인 설정
export CERT_DOMAIN="your-domain.com"

# DNS 인증 방법 설정 (Cloudflare 사용)
export CERT_DNS="dns_cf"

# Let's Encrypt를 사용하여 SSL 인증서 발급 요청
./acme.sh --issue \
  --server letsencrypt \
  --home . \
  -d "$CERT_DOMAIN" \
  -d "*.$CERT_DOMAIN" \
  --dns "$CERT_DNS" \
  --keylength 2048

 

🔍 acme.sh 명령어 플래그 설명

  • --issue: 인증서 발급 요청
  • --server: ACME 서버 지정
  • -d: 인증서를 발급받을 도메인 지정 (와일드카드 지원)
  • --dns: DNS API 인증 방법 지정
  • --keylength: RSA 키 길이 지정

 

명령어를 실행하면 도메인 이름으로 폴더가 생성된다. 도메인, 포트 등 인증서 관련 설정은 해당 폴더의 conf 파일에 저장된다.

📦 /usr/local/share/acme.sh/your-domain.com
├─ ca.cer
├─ fullchain.cer
├─ your-domain.com.cer
├─ your-domain.com.conf
├─ your-domain.com.csr
├─ your-domain.com.csr.conf
└─ your-domain.com.key

 

 

기본 인증서 배포

인증서는 아래 2가지 방법으로 배포할 수 있다.

 

  1. 임시 어드민 유저로 배포 (추천)
  2. 기존 어드민 유저로 배포

 

공식 문서에선 관리자 자격증명 제공이 필요 없는 임시 어드민 유저 방식을 권장하고 있다. 2단계 인증(2FA)이 설정되어 있어도 문제없이 배포할 수 있다. 만약 시놀로지 DSM 포트를 임의로 변경했을 경우 SYNO_PORT 환경 변수를 통해 바뀐 포트 번호를 명시해야 한다.

# 임시 관리자 권한 활성화
export SYNO_USE_TEMP_ADMIN=1

# Synology DSM 포트 설정 (5000 기본값 사용시 생략 가능)
export SYNO_PORT="포트번호" 

# Synology DSM에 인증서 배포
./acme.sh --deploy \
  --home . \
  -d "$CERT_DOMAIN" \
  --deploy-hook synology_dsm

 

🔍 acme.sh 명령어 플래그 설명

  • --deploy: 인증서 배포 실행
  • -d: 배포할 도메인 지정
  • --deploy-hook: 인증서 배포 hook 파일 지정

 

위 명령어를 실행하면 저장된 conf 구성 파일을 불러온 뒤 인증서 배포가 진행되며, 기존에 있던 기본 인증서를 덮어쓴다. DSM 제어판 - 보안 - 인증서 탭을 보면 교체된 기본 인증서를 확인할 수 있다.

 

 

인증서 자동 갱신 설정

DSM 제어판 - 작업 스케줄러 - 생성 - 예약된 작업 - '사용자 정의 스크립트' 클릭.

 

[일반] 탭 - '작업' 이름 지정, '사용자'는 root로 변경.

 

[스케줄] 탭 - 실행 주기 설정. 예) 매월(월간) 첫 번째(처음) 토요일 00:00

 

[작업 설정] 탭 - '사용자 정의 스크립트'에 아래 명령어 복사/붙여 넣기.

/usr/local/share/acme.sh/acme.sh --cron --home /usr/local/share/acme.sh

 

 

'실행 상세 정보를 이메일로 보내기'에 체크하면 실행 결과를 아래처럼 이메일로 받아볼 수 있다.

작업 스케줄러가 예약 작업을 완료했습니다.

작업: Renew Cert
시작 시간: Sun, 09 Mar 2025 00:28:01 +0900
중지 시간: Sun, 09 Mar 2025 00:28:02 +0900
현재 상태: 0 (정상)
표준 출력/오류:

[Sun Mar 9 00:28:02 KST 2025] ===Starting cron===
[Sun Mar 9 00:28:02 KST 2025] Renewing: 'romantech.net'
[Sun Mar 9 00:28:02 KST 2025] Renewing using Le_API=https://acme-v02.api.letsencrypt.org/directory
[Sun Mar 9 00:28:02 KST 2025] Skipping. Next renewal time is: 2025-05-06T14:42:25Z
[Sun Mar 9 00:28:02 KST 2025] Add '--force' to force renewal.
[Sun Mar 9 00:28:02 KST 2025] Skipped romantech.net
[Sun Mar 9 00:28:02 KST 2025] ===End cron===

 

 

(번외) Plex Media Server 인증서 설정


acme.sh를 통해 인증서가 갱신될 때마다 PKCS#12 형식(.pfx, .p12)으로 변환한 후 Plex Media Server 인증서로 사용할 수 있다. 참고로 Plex는 1.32 버전부터 OpenSSL 3.0으로 업그레이드되면서 레거시 암호화 방식의 PEM 인증서 파일을 더 이상 지원하지 않는다.

 

 

공유 폴더 읽기 권한 추가

💡 아래 가이드에서 Plex 인증서는 /volume1/Document/Synology/cert 경로에 저장한다.

 

DSM 제어판 - 공유 폴더 - 인증서를 저장할 공유 폴더 선택 - 편집 버튼 클릭.

 

[권한] 탭 - 상단 드롭다운 클릭 후 '시스템 내부 사용자' 선택 - PlexMediaServer 항목에 '읽기 전용' 체크.

 

 

인증서 변환 스크립트 생성

나스 SSH 접속 후 루트 사용자로 전환하고 acme.sh 디렉터리로 이동한다.

sudo su # 루트 사용자로 전환
cd /usr/local/share/acme.sh # acme.sh 디렉터리로 이동

 

아래 내용에서 "your-domain.com" 값은 본인 도메인으로 변경하고, "pkcs12-password" 값은 인증서에 적용할 암호로 변경한 후 명령어를 실행한다. 인증서 암호는 Plex에서 사용해야 하므로 잘 기록해 둔다.

cat > /usr/local/share/acme.sh/to_pkcs12.sh << EOF
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

DOMAIN="your-domain.com"                       # 도메인
ACME_HOME="/usr/local/share/acme.sh"           # acme.sh 홈 디렉터리
CERT_DIR="${ACME_HOME}/${DOMAIN}"              # 도메인의 인증서 경로
TO_CERT_DIR="/volume1/Document/Synology/cert"  # 변환된 PKCS12 인증서 저장 경로
PASSWORD="pkcs12-password"                     # PKCS12 인증서 암호

# 인증서 파일 유무 확인 (없으면 오류 출력 후 종료)
if [[ ! -f "${CERT_DIR}/${DOMAIN}.key" || ! -f "${CERT_DIR}/${DOMAIN}.cer" || ! -f "${CERT_DIR}/ca.cer" ]]; then
  echo "Error: One or more certificate files are missing in ${CERT_DIR}." >&2
  exit 1
fi

# 변환된 PKCS12 인증서를 저장할 디렉토리가 없으면 생성
mkdir -p "${TO_CERT_DIR}"

# 인증서를 PKCS12(.pfx) 형식으로 변환
convert_cert() {
  echo "Starting PKCS12 conversion..."
  openssl pkcs12 -export -out "${TO_CERT_DIR}/plex.pfx" \
    -inkey "${CERT_DIR}/${DOMAIN}.key" \
    -in "${CERT_DIR}/${DOMAIN}.cer" \
    -certfile "${CERT_DIR}/ca.cer" \
    -certpbe AES-256-CBC \
    -keypbe AES-256-CBC \
    -macalg SHA256 \
    -password "pass:${PASSWORD}"

  if [[ -f "${TO_CERT_DIR}/plex.pfx" ]]; then
    echo "Certificate successfully converted to PKCS12 file."
    echo "Saved at: ${TO_CERT_DIR}/plex.pfx"
  else
    echo "Error: Failed to create PKCS12 certificate file." >&2
    exit 1
  fi
}

# Plex 미디어 서버 재시작
restart_plex() {
  echo "Restarting PlexMediaServer..."
  synopkg restart PlexMediaServer # root 유저로 실행 중이므로 sudo 불필요
}

convert_cert
restart_plex
EOF

 

위 명령어를 실행하면 /usr/local/share/acme.sh 경로에 to_pkcs12.sh 스크립트가 생성된다. 아래 명령어로 스크립트 파일에 실행 권한을 부여한다.

chmod +x /usr/local/share/acme.sh/to_pkcs12.sh

 

스크립트를 실행하여 변환된 인증서가 지정한 경로(/volume1/Document/Synology/cert)에 정상적으로 추가되는지 확인해 본다.

/usr/local/share/acme.sh/to_pkcs12.sh # 스크립트 실행
# Certificate successfully converted to PKCS12 file.
# Saved at: /volume1/Document/Synology/cert/plex.pfx
# Restarting PlexMediaServer...
# restart package [PlexMediaServer] successfully

ls -lh /volume1/Document/Synology/cert/plex.pfx # 변환된 인증서 정보 확인
# ----------+ 1 root root 4.3K Mar  9 17:35 .../plex.pfx

 

 

Renew Hook 지정

conf 인증서 설정 파일의 Le_RenewHook 옵션을 통해 인증서 갱신을 완료했을 때 실행할 명령어를 지정할 수 있다. Le_RenewHook='/usr/local/share/acme.sh/to_pkcs12.sh' 이런 식으로 스크립트 경로를 입력해 두면 인증서를 갱신할 때마다 to_pkcs12.sh 파일이 실행된다.

아래 명령어로 your-domain.com.conf 설정 파일의 Le_RenewHook 값을 스크립트 경로로 변경할 수 있다. your-domain.com 부분은 본인 도메인 주소로 변경한다.

# 도메인의 인증서 파일이 포함된 경로로 이동
cd /usr/local/share/acme.sh/your-domain.com

# sed -i "s|패턴|변경할값|" 수정할파일
sed -i \
"s|^Le_RenewHook=.*|Le_RenewHook='/usr/local/share/acme.sh/to_pkcs12.sh'|" \
your-domain.com.conf

 

🔍 명령어 설명

  • sed: 스트립 편집기. 텍스트 파일 내용을 직접 변경하거나 출력할 때 사용
  • -i: 파일 직접 수정 옵션. macOS에선 -i '' 빈 문자열 추가 필요
  • s|A|B|: A를 B로 변경하는 구문
    • ^Le_RenewHook=.*: Le_RenewHook= 뒤의 모든 값을 포함하는 정규식
      • ^: 문자열 시작
      • .*: 임의 문자 0번 이상 매칭
    • Le_RenewHook='...': 변경할 값

 

이후 인증서 갱신이 이루어지면 Base64로 인코딩한 값이 Le_RenewHook 옵션에 저장된다. 

# /usr/local/share/acme.sh/to_pkcs12.sh 문자열을 Base64로 인코딩하면...
# L3Vzci9sb2NhbC9zaGFyZS9hY21lLnNoL3RvX3BrY3MxMi5zaA==
Le_RenewHook='__ACME_BASE64__START_L3Vzci9sb2NhbC9zaGFyZS9hY21lLnNoL3RvX3BrY3MxMi5zaA==__ACME_BASE64__END_'

 

 

Plex 인증서 경로 지정

Plex 설정 - 네트워크 페이지에서 인증서 경로, 인증서 암호, 인증서 도메인을 입력한다. 인증서 파일이 위치한 공유 폴더에 PlexMediaServer 읽기 권한 주는 걸 잊지 말자. 인증서 도메인은 나스 접속 도메인과 동일한 주소를 입력한다.

 

인증서 경로나 파일을 변경했다면 패키지 센터에서 Plex Media Server를 중지했다가 다시 시작해야 적용된다. 

 

나스 SSH 접속 상태에서 아래 명령어로 재시작할 수도 있다.

synopkg restart PlexMediaServer

 

 

레퍼런스


반응형