Generating and Verifying a Presigned URL
한국어 원문으로 표시합니다.
목표
프리사인드 URL 을 만들고 써 보고 만료시켜 보면서, 바이트를 앱 서버로 통과시키지 않고 접근 권한만 위임하는 방식을 손에 익힌다.
왜 중요한가
사용자 파일 다운로드를 앱 서버가 중계하는 구현은 소규모에서는 잘 돕니다. 문제는 500MB 동영상 100개가 동시에 요청될 때입니다. 앱 서버가 50GB 를 중계하면서 워커가 묶이고, 대역폭이 앱 서버 스펙에 갇히고, 버퍼링을 잘못하면 OOM 이 납니다. 프리사인드 URL 은 이 구조를 뒤집습니다 — 앱은 권한을 판단해 몇 바이트짜리 서명된 URL 만 만들고, 실제 전송은 클라이언트와 스토리지 사이에서 직접 일어납니다. 7번 스텝에서 URL 을 분해해 보면 왜 이것이 안전한지가 보입니다. 서명은 시크릿 키로 만들어졌지만 시크릿 키 자체는 URL 어디에도 없습니다. 그래서 URL 이 새어도 그 객체, 그 동작, 그 만료 시간까지만 노출됩니다.
단계
local/lab-media/private/secret.txt에/opt/fixtures/s3/readme.txt를 올린다.- 서명 없이
curl -o /dev/null -w '%{http_code}' http://127.0.0.1:9000/lab-media/private/secret.txt를 실행하고/root/ps/anon.txt에status=403을 적는다. /root/ps/presign.py로 만료 300초의 프리사인드 GET URL 을 만들어/root/ps/get_url.txt에 한 줄 저장한다. URL 에X-Amz-Signature와X-Amz-Expires가 있어야 한다.- 그 URL 로 내려받아
/root/ps/downloaded.txt를 만든다. 원본과 내용이 같아야 한다. - 만료 1초짜리 URL 을 만들고 3초 기다린 뒤 사용한다.
/root/ps/expired.txt에status=403을 적는다. - 만료 300초의 프리사인드 PUT URL 로
/opt/fixtures/s3/sales.csv를local/lab-media/upload/direct.csv에 올린다.mc stat으로 존재를 확인한다. /root/ps/sig.md에 마크다운 표를 쓴다. 행 제목은X-Amz-Algorithm,X-Amz-Credential,X-Amz-Date,X-Amz-Expires,X-Amz-SignedHeaders,X-Amz-Signature여섯 개이고 각 행에 그 파라미터의 뜻을 적는다. 파일에 시크릿 키 값이 들어 있으면 안 된다.
참고
- URL 을 셸에서 쓸 때는 반드시 따옴표로 감싸세요 —
&가 백그라운드 실행으로 해석됩니다. - 만료는 짧을수록 안전합니다. 다운로드는 몇 분, 업로드는 몇십 분이 보통입니다.
- 흔한 실수 1: 프리사인드 PUT 에 크기와 Content-Type 제한을 걸지 않는 것 — 클라이언트가 무엇이든 올릴 수 있게 됩니다.
- 흔한 실수 2: 프리사인드 URL 을 로그에 그대로 남기는 것 — 만료 전까지 누구나 쓸 수 있습니다.
비공개 객체 준비하기
local/lab-media/private/secret.txt 에 /opt/fixtures/s3/readme.txt 를 올린다.
앞 실습의 버킷을 그대로 쓰거나 새로 만듭니다. 기본 버킷은 익명 접근이 막혀 있습니다.
익명 접근이 거부되는지 확인하기
서명 없이 curl -o /dev/null -w '%{http_code}' http://127.0.0.1:9000/lab-media/private/secret.txt 를 실행하고 /root/ps/anon.txt 에 status=403 을 적는다.
서명 없이 그냥 URL 로 접근해 봅니다. 상태 코드가 무엇인지 기록하세요.
프리사인드 GET URL 만들기
/root/ps/presign.py 로 만료 300초의 프리사인드 GET URL 을 만들어 /root/ps/get_url.txt 에 한 줄 저장한다. URL 에 X-Amz-Signature 와 X-Amz-Expires 가 있어야 한다.
만료 시간을 함께 지정합니다. URL 에 서명 관련 쿼리 파라미터가 붙어 있어야 정상입니다.
프리사인드 URL 로 실제 받아 보기
그 URL 로 내려받아 /root/ps/downloaded.txt 를 만든다. 원본과 내용이 같아야 한다.
따옴표로 감싸지 않으면 셸이 앰퍼샌드를 백그라운드 실행으로 해석합니다.
만료된 URL 이 거부되는지 확인하기
만료 1초짜리 URL 을 만들고 3초 기다린 뒤 사용한다. /root/ps/expired.txt 에 status=403 을 적는다.
아주 짧은 만료로 만들고 잠시 기다린 뒤 써 봅니다. 거부 상태 코드를 기록하세요.
프리사인드 PUT 으로 직접 업로드하기
만료 300초의 프리사인드 PUT URL 로 /opt/fixtures/s3/sales.csv 를 local/lab-media/upload/direct.csv 에 올린다. mc stat 으로 존재를 확인한다.
클라이언트가 스토리지에 직접 올립니다. 앱 서버를 거치지 않는 것이 핵심입니다.
서명 요소 분석하기
/root/ps/sig.md 에 마크다운 표를 쓴다. 행 제목은 X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders, X-Amz-Signature 여섯 개이고 각 행에 그 파라미터의 뜻을 적는다. 파일에 시크릿 키 값이 들어 있으면 안 된다.
URL 의 쿼리 파라미터를 분해해 각각이 무슨 제약인지 적습니다. 시크릿 키가 URL 에 없다는 점을 확인하세요.