이 문서는 NHN Cloud CDN 콘솔에서 CDN 서비스를 구성하고 이용하는 방법을 설명합니다.
Contents Delivery > CDN의 CDN 서비스 탭에서 생성 버튼을 클릭하면 CDN 서비스 생성 대화 상자가 나타납니다. CDN 서비스 도메인은 [서비스ID].toastcdn.net 형식으로 자동 생성됩니다. 만일 소유하고 있는 도메인을 서비스 도메인으로 이용하려면 도메인 별칭(domain alias) 기능을 이용할 수 있습니다. 생성을 요청한 후 서비스 배포가 완료될 때까지 최대 2시간이 걸립니다. 배포가 완료된 후 서비스를 이용할 수 있습니다.
[참고] CDN 최초 생성 시 다운로드 최적화 소요 기간 CDN 최초 생성 후 최대 3일까지 다운로드 속도가 다소 느려질 수 있습니다.
기본 정보를 설정합니다.
설명 CDN 서비스의 설명을 추가합니다.
도메인 별칭 TOSAT CDN은 기본으로 [서비스ID].toastcdn.net 형식의 서비스 도메인 주소를 제공하고 있습니다. 기본 서비스 도메인 주소가 아닌 소유한 도메인으로 CDN 서비스를 이용하려면 도메인 별칭에서 설정하면 됩니다. 소유한 도메인으로 HTTPS 프로토콜 서비스를 이용하려면 먼저 인증서 관리 탭에서 인증서를 발급한 후 도메인 별칭을 설정하시기 바랍니다. 도메인 별칭 설정 후에는 도메인의 DNS 서비스 제공 업체에서 CNAME 레코드를 다음과 같이 등록해야 합니다. DNS 설정 관련 문의는 DNS 서비스 제공 업체에 하시기 바랍니다.
CDN 서비스로 배포할 원본 파일을 제공하는 서버를 설정합니다.
원본 타입
원본 서버 원본 서버는 CDN 서비스로 배포할 원본 파일을 제공하는 서버입니다. 원본 서버는 IPv4 또는 전체 도메인 주소(FQDN, fully qualified domain name) 형식으로 입력할 수 있습니다. IP 주소는 변경될 가능성이 높기 때문에 도메인으로 설정하는 것을 권장합니다. 운영 중인 원본 서버가 없다면, 원본 타입의 인스턴스 옵션을 선택하여 NHN Cloud Instance 서비스의 인스턴스를 사용하거나 오브젝트 스토리지 옵션을 선택하여 NHN Cloud Object Storage 서비스의 컨테이너를 이용할 수 있습니다. CDN 서비스 도메인으로 보안 전송(HTTPS)을 지원하려면 원본 서버는 HTTPS 응답을 지원해야 합니다. 이는 원본 서버에 NHN Cloud CDN이 신뢰하는 인증서가 설치돼 있어야 한다는 뜻입니다. 신뢰하는 인증서는 다음 표를 참고하시기 바랍니다. 만일, 원본 서버가 HTTPS 응답을 지원할 수 없다면 원본 요청 HTTP 프로토콜 다운그레이드 설정을 이용하시기 바랍니다. 단, 원본 요청 HTTP 프로토콜 다운그레이드는 제약 사항이 있으므로 원본 서버가 HTTPS 프로토콜을 지원하는 것을 권장합니다.
[표 1] 신뢰하는 인증서 목록
Common name | Expire Date | SHA-1 Fingerprint |
---|---|---|
SecureTrust CA | 1.Jan.30 | 8782c6c304353bcfd29692d2593e7d44d934ff11 |
Entrust.net Certification Authority (2048) | 24.Jul.29 | 503006091d97d4f5ae39f7cbe7927d7d652d3431 |
DigiCert Global Root CA | 10.Nov.31 | a8985d3a65e5e5c4b2d7d66d40c6dd2fb19c5436 |
30.Sep.23 | 36b12b49f9819ed74c9ebc380fc6568f5dacb2f7 | |
QuoVadis Root CA 2 G3 | 13.Jan.42 | 093c61f38b8bdc7d55df7538020500e125f5c836 |
thawte Primary Root CA | 17.Jul.36 | 91c6d6ee3e8ac86384e548c299295c756c817b81 |
Go Daddy Root Certificate Authority - G2 | 1.Jan.38 | 47beabc922eae80e78783462a79f45c254fde68b |
GeoTrust Primary Certification Authority | 17.Jul.36 | 323c118e1bf7b8b65254e2e2100dd6029037f096 |
VeriSign Class 3 Public Primary Certification Authority - G4 | 19.Jan.38 | 22d5d8df8f0231d18df79db7cf8a2d64c93f6c3a |
Entrust Root Certification Authority | 28.Nov.26 | b31eb1b740e36c8402dadc37d44df5d4674952f9 |
29.May.29 | 5f3b8cf2f810b37d78b4ceec1919c37334b9c774 | |
AffirmTrust Commercial | 31.Dec.30 | f9b5b632455f9cbeec575f80dce96e2cc7b278b7 |
Amazon Root CA 4 | 26.May.40 | f6108407d6f8bb67980cc2e244c2ebae1cef63be |
Certum CA | 11.Jun.27 | 6252dc40f71143a22fde9ef7348e064251b18118 |
DST Root CA X3 | 30.Sep.21 | dac9024f54d8f6df94935fb1732638ca6ad77c13 |
TC TrustCenter Class 2 CA II | 1.Jan.26 | ae5083ed7cf45cbc8f61c621fe685d794221156e |
SwissSign Gold CA - G2 | 25.Oct.36 | d8c5388ab7301b1b6ed47ae645253a6f9f1a2761 |
USERTrust ECC Certification Authority | 19.Jan.38 | d1cbca5db2d52a7f693b674de5f05a1d0c957df0 |
QuoVadis Root CA 2 | 25.Nov.31 | ca3afbcf1240364b44b216208880483919937cf7 |
COMODO ECC Certification Authority | 19.Jan.38 | 9f744e9f2b4dbaec0f312c50b6563b8e2d93c311 |
USERTrust RSA Certification Authority | 19.Jan.38 | 2b8f1b57330dbba2d07a6c51f70ee90ddab9ad8e |
ISRG Root X1 | 4.Jun.35 | cabd2a79a1076a31f21d253635cb039d4329a5e8 |
DigiCert High Assurance EV Root CA | 10.Nov.31 | 5fb7ee0633e259dbad0c4c9ae6d38f1a61c7dc25 |
VeriSign Class 3 Public Primary Certification Authority - G5 | 17.Jul.36 | 4eb6d578499b1ccf5f581ead56be3d9b6744a5e5 |
GlobalSign | 15.Dec.21 | 75e0abb6138512271c04f85fddde38e4b7242efe |
QuoVadis Root CA 3 | 25.Nov.31 | 1f4914f7d874951dddae02c0befd3a2d82755185 |
GlobalSign | 18.Mar.29 | d69b561148f01c77c54578c10926df5b856976ad |
Starfield Services Root Certificate Authority - G2 | 1.Jan.38 | 925a8f8d2c6d04e0665f596aff22d863e8256f3f |
Baltimore CyberTrust Root | 13.May.25 | d4de20d05e66fc53fe1a50882c78db2852cae474 |
AAA Certificate Services | 1.Jan.29 | d1eb23a46d17d68fd92564c2f1f1601764d8e349 |
Amazon Root CA 3 | 26.May.40 | 0d44dd8c3c8c1a1a58756481e90f2e2affb3d26e |
VeriSign Class 3 Public Primary Certification Authority - G3 | 17.Jul.36 | 132d0d45534b6997cdb2d5c339e25576609b5cc6 |
GlobalSign Root CA | 28.Jan.28 | b1bc968bd4f49d622aa89a81f2150152a41d829c |
Actalis Authentication Root CA | 22.Sep.30 | f373b387065a28848af2f34ace192bddc78e9cac |
AffirmTrust Networking | 31.Dec.30 | 293621028b20ed02f566c532d1d6ed909f45002f |
AffirmTrust Premium | 31.Dec.40 | d8a6332ce0036fb185f6634f7d6a066526322827 |
QuoVadis Root Certification Authority | 18.Mar.21 | de3f40bd5093d39b6c60f6dabc076201008976c9 |
6.Jun.37 | feb8c432dcf9769aceae3dd8908ffd288665647d | |
GeoTrust Primary Certification Authority - G3 | 2.Dec.37 | 039eedb80be7a03c6953893b20d2d9323a4c2afd |
thawte Primary Root CA - G2 | 19.Jan.38 | aadbbc22238fc401a127bb38ddf41ddb089ef012 |
VeriSign Universal Root Certification Authority | 2.Dec.37 | 3679ca35668772304d30a5fb873b0fa77bb70d54 |
Cybertrust Global Root | 15.Dec.21 | 5f43e5b1bff8788cac1cc7ca4a9ac6222bcc34c6 |
Global Chambersign Root | 1.Oct.37 | 339b6b1450249b557a01877284d9e02fc3d2d8e9 |
SwissSign Silver CA - G2 | 25.Oct.36 | 9baae59f56ee21cb435abe2593dfa7f040d11dcb |
Amazon Root CA 1 | 17.Jan.38 | 8da7f965ec5efc37910f1c6e59fdc1cc6a6ede16 |
Entrust Root Certification Authority - G2 | 8.Dec.30 | 8cf427fd790c3ad166068de81e57efbb932272d4 |
Amazon Root CA 2 | 26.May.40 | 5a8cef45d7a69859767a8c8b4496b578cf474b1a |
DigiCert Assured ID Root CA | 10.Nov.31 | 0563b8630d62d75abbc8ab1e4bdfb5a899b24d43 |
30.Jun.34 | 2796bae63f1801e277261ba0d77770028f20eee4 | |
COMODO Certification Authority | 1.Jan.30 | 6631bf9ef74f9eb6c9d5a60cba6abed1f7bdef7b |
AddTrust External CA Root | 30.May.20 | 02faf3e291435468607857694df5e45b68851868 |
COMODO RSA Certification Authority | 19.Jan.38 | afe5d244a8d1194230ff479fe2f897bbcd7a8cb4 |
thawte Primary Root CA - G3 | 2.Dec.37 | f18b538d1be903b6a6f056435b171589caf36bf2 |
DigiCert Global Root G3 | 15.Jan.38 | 7e04de896a3e666d00e687d33ffad93be83d349e |
GeoTrust Global CA | 21.May.22 | de28f4a4ffe5b92fa3c503d1a349a7f9962a8212 |
DigiCert Global Root G2 | 15.Jan.38 | df3c24f9bfd666761b268073fe06d1cc8d4f82a4 |
[표 2] 사용 가능한 원본 서버 포트 번호
포트 번호 |
---|
72, 488, 1080, 1443, 7070 |
8000-9001 |
11080-11110 |
80-89 |
591, 1088, 2080, 7612 |
12900-12949 |
443, 777, 1111, 7001, 7777 |
9901-9908 |
45002 |
[예시] 원본 경로를 /files/images로 설정한 경우
- 원본 파일 URL: http://your.origin.com/files/images/logo.png
- CDN 서비스 URL: http://[서비스ID].toastcdn.net/logo.png
- CDN 서비스 URL에서 원본 경로(/files/images)를 생략하여 요청할 수 있습니다.
원본 요청 HTTP 프로토콜 다운그레이드 CDN 에지(edge) 서버는 원본 서버에 원본 파일을 요청할 때 클라이언트의 원본 요청(request)의 서비스 프로토콜(HTTP/HTTPS)로 요청합니다. 즉, 클라이언트가 HTTPS로 요청하고 원본 서버가 HTTPS 응답을 지원하지 않으면, CDN 에지 서버에서 원본 서버로 요청할 때 HTTPS 프로토콜로 요청하기 때문에 원본 파일을 응답받을 수 없습니다. 원본 서버에서 HTTP 프로토콜만 운영한다면, 원본 서버 HTTP 프로토콜 다운그레이드 설정을 사용해 CDN 에지 서버에서 원본 서버로 요청할 때 HTTPS 프로토콜을 HTTP 프로토콜로 다운그레이드해서 요청할 수 있습니다. 즉, 클라이언트에서 CDN 에지 서버 구간은 보안 통신(HTTPS)으로 통신하고, CDN 에지 서버에서 원본 서버 구간은 비보안 통신(HTTP)으로 통신하게 됩니다. 원본 요청 HTTP 프로토콜을 다운그레이드할 때는 다음과 같은 제약 사항이 있습니다.
[주의] 원본 요청 HTTP 프로토콜 다운그레이드 제약 사항 1. 전체 사이트 주소는 프로토콜 다운그레이드를 할 수 없습니다. 예를 들어 원본 서버의 전체 사이트 주소인 www.nhn.com는 다운그레이드할 수 없습니다. 2. GET, HEAD 및 OPTIONS 메서드 외 메서드는 지원되지 않습니다. 3. CDN 서버에서 원본 서버로 다운그레이드를 요청할 때 다음의 헤더는 제외될 수 있습니다. Origin, Referer, Cookie, Cookie2, sec-*, proxy-*
Forward Host Header CDN 서버가 원본 서버에 원본 파일을 요청할 때 전달할 Host 헤더 값을 설정합니다. 원본 서버가 Name-based virtual host로 운영 중이라면 요청 호스트 헤더 설정이 필요할 수 있습니다. 원본 서버의 운영 형태에 따라 적합한 설정 값을 선택하시기 바랍니다.
[주의] 보안 전송(HTTPS) 사용 시 Host 헤더와 원본 서버 인증서의 유효성 검사 클라이언트가 보안 전송(HTTPS)으로 콘텐츠를 요청하면 CDN 서버는 원본 서버의 인증서 유효 여부를 확인합니다. 원본 서버에는 Host 요청 헤더와 일치하는 CN(Common Name) 또는 SAN (Subject Alternate Name)의 인증서가 설치되어 있어야 합니다. Host 요청 헤더와 일치하는 인증서가 원본 서버에 설치되어 있지 않은 경우 보안 전송 오류가 발생합니다. Host 요청 헤더는 Forward Host Header 설정에 따라 요청 호스트 헤더 또는 원본 호스트 이름으로 설정되므로 유의하시기 바랍니다.
CDN 서비스의 루트 경로에 대한 접근 제어를 설정할 수 있습니다.
CDN에서 기본적으로 허용하는 메서드는 GET, HEAD, OPTIONS로, 이외의 메서드를 요청하면 거절 처리됩니다. 해당 메서드 이외의 메서드를 허용하려면 원하는 메서드를 선택해 설정합니다.
CDN 캐시 동작 설정과 만료 시간을 설정할 수 있습니다.
캐시 설정 CDN 서버가 원본 파일을 캐싱할 때 사용할 캐시 설정을 선택할 수 있습니다.
캐시 만료 시간(초) 캐시 만료 시간을 지정하려면 사용자 설정 사용 버튼을 클릭하고 캐시 만료 시간(초)에서 캐시 만료 시간을 변경합니다.
캐시 키 쿼리 문자열 포함 설정 URL 기반으로 생성되는 캐시 키에 요청 쿼리 문자열을 포함할지 설정할 수 있습니다.
[참고] 캐시 만료 시간 기본값과 유효 범위 캐시 만료 시간 기본값은 0입니다. 기본값을 0으로 설정하면 캐시 만료 시간은 604,800(단위/초)=1주일입니다. 캐시 만료 시간은 기본값인 0부터 2,147,483,647(단위/초)까지 입력할 수 있습니다.
[참고] NHN Cloud Object Storage 서비스에서 생성한 컨테이너를 원본 서버로 사용하는 경우 Large File Optimization 기능이 정상적으로 동작하기 위해서는 원본 서버에서 전달되는 ETag 응답 헤더가 큰따옴표로 묶인 형태여야 합니다. NHN Cloud Object Storage 컨테이너에 ETag 응답 헤더 형식 설정에 대한 자세한 내용은 Object Storage 서비스의 API 가이드 내 컨테이너 설정 변경 > RFC를 준수하는 ETag 형식 사용 설정을 참고하시기 바랍니다.
리퍼러 요청 헤더로 콘텐츠의 접근 관리를 설정합니다.
리퍼러 요청 헤더는 현재 요청된 페이지의 링크 이전의 웹 페이지 주소를 포함합니다. 리퍼러 요청 헤더로 어떤 경로에서 요청이 유입되었는지 알 수 있습니다. 리퍼러 헤더 접근 관리는 특정 리퍼러 요청 헤더만 사용자 콘텐츠에 접근할 수 있도록 설정할 수 있습니다. 정규 표현식 형태로 입력할 수 있으며, 여러 개를 입력할 때는 줄바꿈을 한 뒤 입력합니다.
접근 제어 방식
리퍼러 헤더가 없는 경우 접근 허용 리퍼러(referer) 요청 헤더가 없는 경우 콘텐츠 접근 허용 여부를 선택합니다.
[예시]
- 타입: 화이트리스트(whitelist)
- 정규 표현식:
^https://[a-zA-Z0-9._-]*\.nhn\.com/.*
임의의 nhn.com 서브 도메인의 하위 경로에서 리소스를 요청한 경우에만 콘텐츠 접근을 허용합니다.[참고] 정규 표현식의 이스케이프 문자 일부 문자는 정규 표현식에서 특수 문자로 사용됩니다. 점(
.
)을 예로 들자면, 정규 표현식에서 점(.
)은 모든 문자와 일치함을 나타내는 특수 문자입니다. 특수 문자로의 의미가 아닌 일반 문자 그대로 해석해야 한다면 이스케이프 문자 백슬래시(\
)를 특수 문자 앞에 추가하면 됩니다(예:\.
). 정규 표현식의 특수 문자에는^ . [ ] $ ( ) | * + ? { } \
등이 있습니다. 여러 개의 리퍼러를 제어할 때는 다음 줄에 연속해 입력합니다. API를 이용해 여러 개의 리퍼러를 설정할 때는 \n 토큰으로 구분해 입력합니다.
Auth Token 인증 접근 관리는 콘텐츠 요청에 인증 토큰을 추가하여 CDN 에지 서버에서 검증된 토큰만 콘텐츠 접근을 허용하는 보안 기능입니다. 일회성으로 콘텐츠 접근 허용하거나 제한된 사용자만 콘텐츠를 접근 할 수 있도록 제어할 수 있습니다. 토큰이 없거나 유효하지 않은 토큰으로 콘텐츠를 요청한 경우, 403 Forbidden 응답이 전송되며 콘텐츠에 접근할 수 없습니다.
Auth Token 인증 접근을 CDN 서비스에 적용하려면 다음의 단계에 따라 작업이 필요합니다.
[주의]
Auth Token 인증 접근 관리는 NHN Cloud CDN을 이용해 서비스 중인 애플리케이션에서도 다음의 구현이 필요합니다. 1. 콘텐츠 접근에 필요한 토큰을 생성해야 합니다. 2. 클라이언트(최종 콘텐츠 소비자)가 생성된 토큰을 포함하여 콘텐츠를 요청할 수 있도록 해야합니다. 이 작업을 하지 않고 Auth Token 인증 접근 관리를 설정할 경우, 토큰 검증 실패로 인해 콘텐츠 요청이 실패될 수 있으므로 주의하시기 바랍니다.
CDN 콘솔에서 다음의 내용을 참고하여 Auth Token 인증 접근 관리를 설정합니다.
[주의] 요청 URL 경로와 파일 확장자 요청 URL 경로와 파일 확장자 모두 설정한 경우, 두 조건 중 하나만 일치해도 토큰 접근 제어가 동작합니다. [예시] 요청 URL 경로 /nhn/*, 파일 확장자 png 가 설정된 경우: /nhn 하위의 모든 파일 또는 파일 확장자가 png인 콘텐츠에 대해 토큰을 검증합니다.
최종 콘텐츠 사용자가 콘텐츠에 접근하려면 토큰과 함께 콘텐츠를 요청해야 합니다. 따라서, 토큰을 생성해 최종 콘텐츠 사용자에게 발급해야 합니다. 토큰 생성은 NHN Cloud CDN을 이용해 서비스 중인 애플리케이션에서 구현되어야 합니다. 토큰 생성 방법은 다음의 샘플 코드를 참고하여 토큰을 생성합니다.
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NhnCloudAuthTokenAccessControlExample {
// NHN Cloud 콘솔에서 확인한 인증 토큰 암호화 키
private static final String AUTH_TOKEN_ENCRYPT_KEY = "{NHN Cloud CDN 서비스의 토큰 암호화 키}";
// 토큰 유효 시간(seconds)
private static final Long TOKEN_DURATION_SECONDS = 3600L;
public static void main(String[] args) throws AuthTokenException {
String path = "/nhn/%EC%9D%B8%EC%A6%9D/%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF.png";
String singleWildcardPath = "/nhn/%EC%9D%B8%EC%A6%9D/*";
String[] multipleWildcardPath = {"/nhn/%EC%9D%B8%EC%A6%9D*", "/nhn/auth/*"};
System.out.println(" ----------------- ");
System.out.println(" 기본 토큰 발급 ");
System.out.println(" ----------------- ");
AuthToken authToken = new AuthToken(AUTH_TOKEN_ENCRYPT_KEY, TOKEN_DURATION_SECONDS);
System.out.println("단일 URL 토큰: token=" + authToken.generateURLToken(path));
System.out.println("와일드카드 토큰: token=" + authToken.generateWildcardPathToken(singleWildcardPath));
System.out.println("멀티 와일드카드 토큰: token=" + authToken.generateWildcardPathToken(multipleWildcardPath));
System.out.println(" ----------------- ");
System.out.println(" 세션 식별자를 포함한 토큰 발급 ");
System.out.println(" ----------------- ");
AuthToken authTokenWithSession = new AuthToken(AUTH_TOKEN_ENCRYPT_KEY, TOKEN_DURATION_SECONDS, "example-sessionId");
System.out.println("단일 URL 토큰: token=" + authTokenWithSession.generateURLToken(path));
System.out.println("와일드카드 토큰: token=" + authTokenWithSession.generateWildcardPathToken(singleWildcardPath));
System.out.println("복수 와일드카드 토큰: token=" + authTokenWithSession.generateWildcardPathToken(multipleWildcardPath));
}
public static class AuthToken {
/** 토큰 암호화 알고리즘(SHA256 고정) **/
private static final String HMAC_SHA_256 = "HmacSHA256";
/** 토큰 암호화 키 (NHN Cloud CDN 콘솔 > Auth Token 인증 접근 관리 > 암호화 키) **/
private String key;
/** 세션 식별자 */
private String sessionId;
/** 토큰의 유효 시간(단위: 초) */
private Long durationSeconds;
/** 토큰 생성 전 url encode 적용 여부 */
private Boolean escapeEarly;
/** 토큰 Body 필드의 구분자 */
private final String fieldDelimiter = "~";
/** wildcardPath 구분자 */
private final String aclDelimiter = "!";
public AuthToken(String key, Long durationSeconds) {
this.key = key;
this.sessionId = null;
this.durationSeconds = durationSeconds;
this.escapeEarly = true;
}
public AuthToken(String key, Long durationSeconds, String sessionId) {
this.key = key;
this.sessionId = sessionId;
this.durationSeconds = durationSeconds;
this.escapeEarly = true;
}
/**
* 단일 URL에 대한 토큰을 생성합니다.
* @param path : contents url (example: /auth/contents/example.png)
* @return created token
* @throws AuthTokenException
*/
public String generateURLToken(String path) throws AuthTokenException {
return generateToken(createExpireTime(), this.sessionId, path, null);
}
/**
* 와일드카드 경로에 대한 토큰을 생성합니다.
* @param wildcardPath : "/auth/contents/*"
* @return 생성된 토큰값
* @throws AuthTokenException
*/
public String generateWildcardPathToken(String wildcardPath) throws AuthTokenException {
return generateWildcardPathToken(new String[] {wildcardPath});
}
/**
* 복수 개의 와일드카드 경로에 대한 토큰을 생성합니다.
* @param wildcardPaths (example: ["/auth/contents/*", "/auth/*/images/*"])
* @return 생성된 토큰값
* @throws AuthTokenException
*/
public String generateWildcardPathToken(String... wildcardPaths) throws AuthTokenException {
return generateToken(createExpireTime(), this.sessionId, null, wildcardPaths);
}
private String createExpireTime() {
Long nowSeconds = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTimeInMillis() / 1000L;
Long exp = nowSeconds + this.durationSeconds;
return exp.toString();
}
private String generateToken(String exp, String sessionId, String path, String[] wildcardPaths) throws AuthTokenException {
try {
StringBuilder token = new StringBuilder();
token.append("exp=")
.append(exp)
.append(this.fieldDelimiter);
if (wildcardPaths != null && wildcardPaths.length > 0) {
token.append("acl=")
.append(escapeEarly(StringUtils.join(wildcardPaths, this.aclDelimiter)))
.append(this.fieldDelimiter);
}
if (sessionId != null && sessionId.length() > 0) {
token.append("id=")
.append(escapeEarly(sessionId))
.append(this.fieldDelimiter);
}
StringBuilder hashSource = new StringBuilder(token);
if (path != null && path.length() > 0) {
hashSource.append("url=")
.append(escapeEarly(path))
.append(this.fieldDelimiter);
}
// remove last fieldDelimiter char
hashSource.deleteCharAt(hashSource.length() - 1);
Mac hmac = Mac.getInstance(HMAC_SHA_256);
byte[] keyBytes = DatatypeConverter.parseHexBinary(this.key);
SecretKeySpec secretKey = new SecretKeySpec(keyBytes, HMAC_SHA_256);
hmac.init(secretKey);
byte[] hmacBytes = hmac.doFinal(hashSource.toString().getBytes());
return token.toString() + "hmac=" + String.format("%0" + (2 * hmac.getMacLength()) + "x", new BigInteger(1, hmacBytes));
} catch (NoSuchAlgorithmException e) {
throw new AuthTokenException(e.getMessage());
} catch (InvalidKeyException e) {
throw new AuthTokenException(e.getMessage());
}
}
private String escapeEarly(final String text) throws AuthTokenException {
if (this.escapeEarly == true) {
try {
StringBuilder newText = new StringBuilder(URLEncoder.encode(text, "UTF-8"));
Pattern pattern = Pattern.compile("%..");
Matcher matcher = pattern.matcher(newText);
String tmpText;
while (matcher.find()) {
tmpText = newText.substring(matcher.start(), matcher.end()).toLowerCase();
newText.replace(matcher.start(), matcher.end(), tmpText);
}
return newText.toString();
} catch (UnsupportedEncodingException e) {
return text;
} catch (Exception e) {
throw new AuthTokenException(e.getMessage());
}
} else {
return text;
}
}
}
public static class AuthTokenException extends Exception {
private static final long serialVersionUID = 1L;
public AuthTokenException(String msg) {
super(msg);
}
}
}
클라이언트(최종 콘텐츠 소비자)가 콘텐츠 요청시 콘솔에서 설정한 토큰 위치에 생성된 토큰값을 포함하여 요청하도록 합니다.
curl --cookie "token={생성된 토큰값}" \
-X GET http://xxx.toastcdn.net/auth/contents/example.png
curl -H "token: {생성된 토큰값}" \
-X GET http://xxx.toastcdn.net/auth/contents/example.png
curl -d "token={생성된 토큰값}" \
-X GET http://xxx.toastcdn.net/auth/contents/example.png
CDN에서 사용자에게 응답 시 전달되는 헤더를 추가/변경/삭제하는 기능입니다. 헤더는 중복되지 않은 헤더 이름으로 최대 10개까지 설정할 수 있습니다.
[참고] CORS(교차 출처 리소스 공유) 설정 아래와 같이 HTTP 응답 헤더를 설정하여 CORS를 허용할 수 있습니다. - Action: Modify - 헤더 이름: Access-Control-Allow-Origin - 헤더 값: *(와일드카드) 혹은 허용할 원본 URI
서비스 도메인 이름을 제외한 CDN 서비스 설정을 변경할 수 있습니다.
다음과 같이 CDN 서비스 수정 페이지로 이동합니다.
수정 작업은 몇 십분 내 완료되며, 도메인 별칭 설정이 변경된 경우에는 몇 시간이 걸릴 수 있습니다.
[참고] CDN 서비스 수정 중 배포 상태와 서비스 상태 서비스 수정 작업이 진행 중이면 기존 CDN 서비스 설정으로 운영됩니다. 만약 수정 작업에 실패하면 기존 설정 정보로 롤백되며, CDN 서비스 목록의 배포 상태가 빨간색 원으로 표시됩니다. 설정 정보에 오류가 있거나 내부적으로 오류가 발생했을 때 수정 작업에 실패합니다.
CDN 서비스를 일시적으로 중단하거나 재시작할 수 있습니다.
[참고] 일시 정지와 재시작 동작의 지연 CDN 서비스 일시정지와 재시작은 CDN 서비스 도메인의 DNS 레코드를 변경하여 동작됩니다. 따라서 캐시 DNS 서버에서 TTL 동안 캐시되어 있거나 DNS 전파에 따라 일시정지/재시작이 완료 되어도 즉시 일시정지/재시작이 동작되지 않을 수 있습니다.
[주의] 발급된 인증서가 연동된 CDN서비스의 일시정지 인증서가 연동된 CDN 서비스를 일시정지 하는 경우, 인증서 갱신이 불가합니다. 인증서 관리 > 인증서 목록의 인증서 갱신 시작일 이전에 CDN 서비스를 재시작하시기 바랍니다. 인증서 갱신 시작일로 부터 5일 동안은 인증서 갱신 기간이므로 해당 기간에 일시정지를 하면 인증서가 만료될 수 있으므로 유의하시기 바랍니다.
CDN 서비스를 삭제합니다. 삭제 작업은 복구할 수 없으므로 유의하시기 바랍니다.
[참고] CDN 서비스 삭제 소요 시간 CDN 서비스 삭제 작업은 몇 시간(최대 2~3시간)이 걸릴 수 있습니다.
[주의] 발급된 인증서가 연동된 CDN 서비스의 삭제 인증서가 연동된 CDN 서비스를 삭제하면, 인증서를 갱신할 수 없습니다. 인증서 관리의 인증서 목록에서 인증서 갱신 시작일 이전에 서비스 중인 다른 CDN 서비스로 연동하시기 바랍니다. 인증서 갱신 시작일로부터 5일 동안은 인증서 갱신 기간이므로 해당 기간에 삭제하면 인증서가 만료될 수 있으므로 유의하시기 바랍니다.
CDN 캐시 서버는 캐시 설정에 따라 지정된 만료 시간 동안 원본 서버의 파일을 캐시합니다. 파일을 캐시하면 원본 파일이 변경되어도 캐시가 만료되기 전까지는 변경전 원본 파일을 유지합니다. 변경된 원본 파일로 콘텐츠를 즉시 업데이트하려면 Purge를 요청해야 합니다. Purge를 하면 요청한 콘텐츠의 오래된 캐시 데이터를 삭제하고 원본 서버에서 새 원본 파일을 다시 캐시합니다.
Purge 탭을 클릭하고 Purge 버튼을 클릭합니다. )
Purge 유형을 선택합니다.
Purge는 사용량 제한이 있으므로 아래 표를 참고하시고 사용량이 초과되지 않도록 유의하시기 바랍니다.
분류 | [서비스ID].toastcdn.net |
---|---|
제한 단위 | 프로젝트별(Appkey) |
특정 파일 | 1초당 요청 가능: 1회, 요청당 URL 수 제한: 200 URL |
전체 파일 타입 | 5분당 요청 가능: 1회 |
[주의] [서비스ID].toastcdn.net 서비스를 생성한 후 Purge 실패 오류 CDN 서비스를 생성한 후 약 1시간 이내에는 Purge 요청에 실패할 수 있습니다. 이후에도 계속 실패하면 NHN Cloud 고객 센터로 문의해 주시기 바랍니다.''
네트워크 전송량, HTTP 상태 코드별 통계 및 다운로드가 가장 많은 콘텐츠의 순위 통계를 확인할 수 있습니다. 7일 이내 통계 데이터는 정확하지 않으므로 참고용으로만 이용하시기 바랍니다. 정확한 통계 데이터는 7일 이후에 확인하시기 바랍니다.
[참고] 최대 검색 기간 최근 90일간의 통계 데이터만 조회가 가능합니다.
[참고] Top Contents By Hits 통계 제약사항 하루 이전까지, 하루 이상의 범위로 조회가 가능합니다. 100KB 이하의 콘텐츠 혹은 요청 횟수가 하루 50번 미만인 콘텐츠는 통계에서 제외됩니다.
소유한 도메인으로 콘텐츠를 보안 전송(HTTPS)하려면 CDN 서버에 소유한 도메인의 인증서를 배포해야 합니다. 인증서가 없으면 클라이언트(브라우저)와 CDN 에지 서버 간 보안 통신(HTTPS)을 할 수 없어 인증서 오류가 발생합니다. NHN Cloud CDN의 인증서 관리는 다음과 같은 기능을 제공합니다.
인증서 관리 탭에서 인증서를 발급할 수 있습니다.
[주의] 인증서 발급 전 확인 사항 1. 소유한 도메인만 인증서를 발급할 수 있으므로 먼저 도메인을 구매하신 후 진행하시기 바랍니다. 2. 다른 인증 기관(CA, certificate authority)에서 발급한 인증서는 이용할 수 없습니다. 3. 단일 도메인의 인증서 발급만 가능합니다. 와일드카드, 멀티 도메인 등의 인증서는 지원하지 않습니다. 4. 인증서 발급은 프로젝트당 5개로 제한됩니다. 한도 조정이 필요한 경우 NHN Cloud 고객 센터로 문의하시기 바랍니다. 5. 신규 인증서 발급 요청 후 도메인 검증 단계는 몇 십분(최대 1~2시간) 후 변경될 수 있습니다. 인증서 상태가 도메인 검증 상태로 변경되면 NHN Cloud 프로젝트 멤버를 대상으로 이메일 발송됩니다. 만일 시스템 오류로 이메일이 발송되지 않는다면 콘솔에서 상태를 확인하시기 바랍니다.
신규 인증서 발급을 요청한 후 인증서 상태가 '도메인 검증'이 되면 도메인을 검증하시기 바랍니다. 도메인 검증 방법은 콘솔에서 도메인을 선택하여 확인하거나, 프로젝트 멤버에게 전송된 도메인 검증 가이드 메일의 내용을 참고하시기 바랍니다.
도메인 검증은 발급 요청한 인증서 도메인의 실제 소유자인지 확인하는 단계 입니다. 도메인 검증을 진행하지 않으면 인증서를 발급할 수 없습니다. 도메인 소유자인지 확인하기 위해 도메인 검증 방식으로 도메인의 제어 권한을 확인합니다. 도메인 검증 방식에는 DNS TXT 레코드 추가 또는 HTTP 페이지 추가 방식이 있으며 두 가지 방식 중 하나만 진행하면 됩니다.
도메인의 DNS 제어 권한을 확인해 도메인을 검증합니다.
레코드값: 임의의 문자열 (콘솔 또는 발송된 이메일 가이드의 레코드값을 작성합니다.)
nslookup 명령어로 추가한 TXT 레코드가 질의되는지 확인합니다. DNS 전파 시간에 따라 질의되기까지 시간이 소요될 수 있습니다.
nslookup -type=TXT _acme-challenge.[발급 요청한 인증서 도메인].
다음 화면은 NHN Cloud DNS+ 서비스에서 설정한 예시입니다. DNS 서비스 제공 업체에 따라 설정 방법은 다를 수 있습니다.
도메인이 연결된 웹 서버에 HTTP 페이지를 추가해 도메인을 검증합니다.
[주의] 도메인 검증 주의 사항 1. 도메인 검증은 인증서 발급 요청일로부터 5일 이내에 진행해야 합니다. 기간 내 진행하지 않으면 인증서 발급은 자동으로 취소됩니다. 2. 도메인 검증 작업 완료 후 검증에 성공하면 몇 시간 내 인증서 발급 및 배포 작업이 진행됩니다. 하루 이상 진행되지 않으면 도메인 검증 작업 내용이 올바른지 확인합니다. 문제가 없는데도 진행되지 않으면 NHN Cloud 고객 센터로 문의해 주시기 바랍니다. 3. 도메인 검증 방식 중 HTTP 페이지 추가 방식은 HTTP 서버가 기본 포트 80 포트로 운영 중일 때만 가능합니다. 포트를 변경할 수 없다면 DNS TXT 레코드 추가 방식을 이용하시기 바랍니다.
도메인 검증을 통과하면 몇 시간 내 인증서 발급 및 배포 작업이 진행됩니다. 콘솔의 인증서 상태가 인증서 발급 및 배포 단계로 표시되며, NHN Cloud 프로젝트 멤버 대상으로 알림 메일이 발송됩니다. 이 단계에서는 별도로 작업할 내용은 없습니다.
[참고] 인증서 발급과 배포 단계의 작업 시간 인증서 발급 및 배포 작업은 최대 9시간 이상 걸릴 수 있습니다.
발급된 인증서를 이용하려면 CDN 서비스와 연동해야 합니다. 이 작업을 진행하지 않거나 작업 내용을 유지하지 않으면 발급된 인증서가 만료될 수 있으므로 주의하시기 바랍니다.
CNAME 레코드 설정: 인증서 도메인의 DNS 서비스 제공 업체의 DNS 관리에서 다음의 CNAME 레코드를 추가합니다.
도메인 별칭 설정: 인증서를 이용할 CDN 서비스에 도메인 별칭 설정을 추가합니다.
[참고] CNAME 레코드 전파 시간 CNAME 레코드 설정 시 다양한 요인에 따라 DNS 전파에 시간이 소요될 수 있습니다. 따라서 서비스 연동 과정을 올바르게 수행한 뒤에도 일정 시간 동안 인증서 발급 상태가 [CDN 서비스 연동 대기]로 표시될 수 있습니다. 설정을 올바르게 하였는데도 24시간 이상 [CDN 서비스 연동 대기] 상태가 지속될 경우 NHN Cloud 고객 센터로 문의해 주시기 바랍니다.
[주의] 인증서 만료 주의 사항 NHN Cloud CDN에서 제공하는 인증서는 인증서 만료 전 자동으로 인증서를 갱신합니다. 자동으로 인증서를 갱신하려면 반드시 사용 중인 인증서가 CDN 서비스와 연동돼 있어야 합니다. CDN 서비스와 연동돼 있지 않으면 인증서 갱신 기간에 갱신되지 않아 인증서가 만료될 수 있습니다. 인증서 갱신은 인증서 관리의 목록에 표시된 인증서 갱신 시작일로부터 5일 이내 진행됩니다. 인증서가 만료되지 않도록 다음의 설정 사항을 항상 유지하시기 바랍니다.
- 인증서의 도메인은 CNAME 레코드로 연동할 CDN 서비스 도메인 주소로 위임해야 합니다.
- 연동할 CDN 서비스의 도메인 별칭에 인증서 도메인이 설정되어 있어야 합니다.
- 인증서가 연동된 CDN 서비스를 일시 정지하면 인증서를 갱신할 수 없습니다. 인증서 갱신 시작일 이전에 재시작하거나 다른 운영 중인 CDN 서비스에 인증서를 연동하시기 바랍니다.
- 인증서가 연동된 CDN 서비스를 삭제하면 인증서를 갱신할 수 없습니다. 삭제하기 전에 운영 중인 다른 CDN 서비스에 인증서를 연동하시기 바랍니다.
CDN 서비스 연동 작업이 완료되면 인증서 상태가 '정상'으로 표시됩니다.
[참고] 발급된 인증서 오류 발생 시 조치 사항 NHN Cloud CDN에서 제공하는 인증서의 Root 인증서 중 하나인 IdenTrust DST Root CA x3가 2021년 9월 30일에 만료되어, 일부 오래된 단말 또는 구형 브라우저에서 문제가 발생할 수 있습니다. 클라이언트에서 ERR_CERT_DATE_INVALID 오류로 문제가 발생하는 경우, 아래의 내용을 참고하여 OS 설정 변경 후 업데이트 또는 Root 인증서 수동 설치 등의 조치가 필요합니다. 1. ISRG x1 인증서 다운로드 링크: 다운로드 링크 2. Windows OS 설정 변경 참고 가이드: 링크 3. 크롬 브라우저 참고 가이드: 링크