1일차
퇴사 후 Coloso에서 1인 개발 강의를 듣기 시작했다. 데이터와 백엔드 개발 쪽에 관심이 많아져서 잘 모르지만 어쩐지 너무 재밌어서... 더듬더듬 강의 들으며 공부하려 한다. 이에 대한 이야기는 조만간 풀어봐야겠다.
우선은 AWS 가입을 했다. GCP는 살짝 써봤지만 AWS는 처음. 강의를 보며 따라하니까 EC2에 웹 서버 환경을 구성하는 것도 가능했다.
Ubuntu 기반 프리 티어 인스턴스를 생성해 키 발급, 초기 세팅으로는 Docker, Docker Compose 설치, 보안 그룹 포트 오픈(22, 80, 443)을 포함했다.
이후 도메인을 가비아에서 구매하여 A 레코드를 EC2 퍼블릭 IP로 연결하고, docker-compose.yml
을 작성해 Nginx와 certbot을 포함한 기본 HTTPS 구성을 시도했다.
그러나 인증서 발급 과정에서 certbot이 도메인 소유권 인증에 실패했다. DNS 전파가 완료되기 전 인증 요청이 들어간 것으로 추측. 전체적으로 인프라의 기본 구성 흐름을 재확인한 날이었다.
DNS 전파
- 도메인을 구매하고 IP 주소를 설정하면 이 정보가 전 세계 DNS 서버에 퍼지는 데는 수 분 ~ 수 시간 소요. 그래서 certbot 인증처럼 즉시 IP 확인이 필요한 작업은 실패할 수 있음
2일차
전날 certbot을 통한 인증서 발급이 실패했던 원인을 DNS 전파 지연으로 판단하고,
도메인 반영 여부를 확인한 뒤 인증을 재시도했다. 하지만 하루가 지났음에도 동일한 방식으로는 인증서를 발급받지 못했다.
인증서 발급 실패
- 현상: certbot 실행 시 도메인 인증 실패
- 기존 조치: DNS 전파 시간 대기 후 재시도 → 실패
가능 원인 및 점검 항목
- DNS 설정이 올바르지 않음 (A레코드가 IP를 정확히 가리키지 않음)
- DNS 전파는 되었으나 캐싱 문제로 아직 외부에서 조회 불가
- 포트 80/443이 열려 있지 않음 (보안 그룹/방화벽)
- certbot 실행 시 nginx가 포트 80을 점유 중
- certbot 명령어의 도메인(-d)이 실제 설정한 도메인과 불일치
컨테이너를 재기동하고 docker 네트워크를 정리했지만 상황은 개선되지 않았다. 여기에 더해 ubuntu 서버 연결이 끊어졌고 아래의 에러들도 발생했다.
오류: permission denied, 디렉터리 목록 조회 실패, no such file or directory
aws에서 인스턴스를 새로 만들고 ip도 재할당해서 다시 ubuntu를 연결했다. 이후에는 결국 강의자료에서 제공하는 인증서 파일(fullchain.pem
, privkey.pem
)을 경로에 직접 삽입하여 HTTPS 구성을 완료했다.
이 방식은 실습용으로는 유효하지만, 운영 환경에서는 자동 갱신이 불가능하므로 대체 방안이 필요하다. 우선은 진도를 나가야 한다고 생각해서 결제 붙이는 단계까지 사이클을 돌고 난 뒤에 복기할 예정이다.
📖 스터디
HTTPS와 certbot
HTTPS
HTTPS는 웹사이트 데이터 보안을 확보하기 위해 사용해야 하는 프로토콜이다. 처음에는 실습이고 에러 해결이 어려워 HTTP로 갈까 싶기도했지만 내 목표는 실제 운영환경으로 만들어보는 것이었기에 포기할 수 없었다. HTTPS를 써야 하는 이유는 몇 가지로 정리된다.
첫 번째는 암호화다. HTTPS는 SSL/TLS 프로토콜을 사용해서 서버와 클라이언트 간 데이터를 암호화해 준다. 덕분에 중간에서 누군가 네트워크를 가로채더라도 내용을 볼 수 없다. 로그인 정보나 카드번호 같은 민감한 데이터를 다룰 거라면 더욱 필수.
SSL/TLS 동작 흐름:
- 클라이언트가 서버에 연결 요청 (HTTPS 접속)
- 서버가 인증서(공개키 포함)를 보냄
- 클라이언트는 인증서를 검증, 대칭키 암호화를 위한 정보를 서버에 보냄
- 클라와 서버는 같은 암호화 키를 공유하게 되고, 이후부터는 해당 키로 통신
초기 통신은 공개키 기반, 이후 통신은 대칭키 기반으로 이루어지며, 덕분에 보안성과 속도 둘 다 챙길 수 있다.
HTTPS를 쓴다는 건 사실상 TLS 위에서 HTTP를 주고받는 것이다. 사용자는 “https://”만 보면 되지만 내부적으로는 SSL/TLS가 열심히 암호화와 인증을 처리하고 있다. 운영 환경에 HTTPS를 적용하려면 SSL 인증서가 필요. 그 인증서는 결국 TLS를 기반으로 작동한다.
두 번째는 데이터 무결성이다. 통신 도중에 데이터가 변조되었는지 아닌지를 검증할 수 있어서, 중간자 공격이나 악의적인 조작을 방지하는 데 도움이 된다. 예를 들어 스크립트가 삽입되거나, 콘텐츠가 중간에서 바뀌는 걸 막을 수 있다.
세 번째는 인증이다. HTTPS 인증서는 단순히 암호화를 넘어서, 해당 도메인이 진짜 맞는지 확인하는 역할도 한다. 사용자가 접속한 페이지가 진짜 운영 중인 사이트인지, 아니면 비슷하게 만든 피싱 사이트인지 구분하는 기준이 된다.
또 하나는 SEO와 사용자 경험인데, 구글은 HTTPS를 적용한 사이트에 대해 검색 순위에서 가산점을 준다고 명시하고 있다. 실사용에서도 HTTPS가 아닌 사이트는 “주의 요함” 같은 경고가 뜨고, 신뢰도가 확 떨어진다. 사용자 입장에서도 괜히 꺼려질 수밖에 없다.
요즘 브라우저 정책도 HTTPS를 전제로 하고 있다. 크롬이나 사파리 같은 브라우저는 HTTP 상태에서 폼 입력이 있거나 민감한 데이터가 오갈 경우 아예 경고를 띄우고, 앞으로는 더 제약이 심해질 가능성도 있다.
정리하자면, 보안과 신뢰도, 사용자 경험을 위해 HTTPS는 이제 선택이 아니라 기본이다. 개발 초반엔 귀찮게 느껴질 수 있지만, 한 번 세팅해두면 이후엔 큰 문제 없이 쓸 수 있다. 운영을 염두에 둔다면 초반부터 HTTPS를 고려해 두는 게 낫다.
certbot
HTTPS를 사용하려면 인증서가 필요한데, 이를 무료로 자동 발급해주는 도구가 바로 certbot이다.
1. 도메인 소유자임을 증명
certbot은 “이 도메인이 당신 것인가요?”를 확인하기 위해 인증 절차를 수행한다.
- HTTP-01 방식: 웹서버에 특정 파일을 생성
- DNS-01 방식: 도메인 DNS에 특정 TXT 레코드를 등록
2. 인증서 발급
도메인 소유가 확인되면, Let's Encrypt가 SSL 인증서를 발급한다. 이 인증서는 HTTPS를 위한 핵심 파일이다.
3. 서버 설정과 연결
발급된 인증서 파일(fullchain.pem
, privkey.pem
)을 웹서버(Nginx 등)에 적용하면
브라우저에서 HTTPS 연결이 활성화된다.
ssl_certificate /etc/letsencrypt/live/도메인/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/도메인/privkey.pem;
4. 자동 갱신 기능
Let's Encrypt의 인증서는 90일 유효기간을 가진다.
certbot은 cron
이나 systemd
를 통해 인증서를 자동 갱신할 수 있다.
certbot은 무료이고 자동화가 가능하다는 점에서 유용한 도구로 판단된다. 하지만 내부적으로 브라우저 의존성과 외부 네트워크 조건이 얽혀 있어 예상 외로 불안정한 상황이 종종 발생하는듯하다. 실 운영 환경에서는 대안 경로와 복구 전략을 함께 마련해두어야 할 것이다. 궁금해서 찾아본 대안 방식들은 아래와 같다.
대안 방식 | 내용 |
---|---|
ACM (AWS Certificate Manager) | AWS가 제공하는 인증서 서비스. ELB, CloudFront 연동 시 유리 |
Cloudflare Proxy | 서버는 HTTP로만 동작하고, HTTPS 처리는 Cloudflare가 대행 |
수동 인증서 삽입 | certbot이 실패할 경우, 외부에서 발급받은 인증서를 수동으로 적용 |
Fallback 처리 | 인증 실패 시 로그 기록, 재시도 로직, Slack 알림 등을 구성해 안정성 확보 |