개요
프론트엔드의 서버가 API 서버의 http 문제로 인해 API 통신이 되질 않는다.
어차피 언젠가는 해야될 SSL 인증, 이번 기회에 해보자는 마음에 이 글을 작성하려 한다.
이 글은 NginX를 이용한 웹 서버에 SSL 인증서를 적용하는 방법을 다룬다.
✅ 같이 보면 좋을 글
SSL 인증서가 왜 필요할까?
SSL 인증서는 웹사이트와 사용자 사이에 오가는 정보를 암호화하여 안전하게 보호하는 역할을 한다.
쉽게 말해, 웹사이트와 사용자 사이에 보안 터널을 만들어주는 것이다.
이 터널을 통해 개인정보, 금융 정보 등 중요한 데이터가 보다 안전하게 전송될 수 있다.
또한, SSL 인증서를 적용하면 아래와 같은 이점이 발생한다.
- 방문자 입장에서는 SSL 인증서가 없는 웹 사이트는 브라우저 자체에서 경고 문구가 뜨기 때문에 불안할 수 있다. 보안이 강화된 웹사이트는 신뢰감을 줄 수 있다.
- 구글을 비롯한 검색 엔진들은 https 프로토콜을 사용하는 웹사이트를 더 높이 평가하기 때문에 SEO(검색 엔진 최적화) 효과를 누릴 수 있다.
- SSL 인증서는 웹사이트 해킹 및 개인정보 유출을 예방하는 가장 기본적인 방법으로 사용된다. 때문에 웹 보안의 가장 첫 단계라고도 볼 수 있다.
SSL 인증 기관으로 Let's Encript를 선택한 이유
무엇보다 가장 큰 이유는 무료이기 때문이다.
Let's Encrypt는 비영리 기관에서 운영되기 때문에 누구나 무료로 SSL 인증서를 발급받을 수 있다.
또한 복잡한 절차 없이 자동화된 시스템을 통해 손쉽게 인증서를 발급받고 설치할 수 있다.
구글, 페이스북, 모질라 재단 등 글로벌 기업들이 후원하는
공인된 인증기관이라는 점에서도 신뢰성이 매우 믿음직하다고 볼 수 있는 기괸이다.
Let's Encript기관은 ACME 프로토콜을 사용하여
SSL 인증서의 유무 및 갱신 시기를 확인하고 자동으로 갱신하도록 해주고 있다.
✅ 여기서 ACME 프로토콜은 뭘까?
ACME (Automated Certificate Management Environment)의 준말이다.
도메인 유효성 검사, 설치 및 관리를 자동화하기위한 표준 프로토콜이다.
ACME 프로토콜은 인증서 자동화 솔루션으로 널리 사용되고 있다. (출처 SSL.com)
SSL 인증서 발급을 위한 도구 - Certbot
윈도우즈는 2024년 2월부터 지원을 중단했다.
검색하면 윈도우에서 Certbot을 사용하여 SSL을 발급받는 것이 많이 나오는데...
지금으로서는 사용이 어렵다고 보면 된다.
Certbot 개발자분의 말에 의하면 윈도우용은 지금도 사용은 가능하다고는 하는데,
자동 갱신은 안된다는 말을 하였다. 그리고 또한, 이 시점 이후로는 또 어떻게 될지 잘 모르겠다.
SSL 인증서 발급을 위한 도구 - win-acme
윈도우용으로 사용하기 위해서 win-acme툴을 선택하였다.
종류가 여러가지가 있던데 내 눈에는 딱 이게 눈에 들어오더라.
다른 종류를 사용해볼 의향이 있다면 letsencript 홈페이지에서 종류를 확인해보고 선택해서 진행해도 된다.
단, 이 글은 win-acme에 대한 설명만을 담고있기 때문에 다른 종류의 SSL 설치 방법은 이 글 내용과 해당하지 않는다.
윈도우즈용 ACME 다운로드
win-acme 사이트로 접속해서 다운로드를 받을 수 있다.
- Download - 버전 (recommended) 선택
SSL 인증서 발급받기
이 글은 윈도우 운영 체제를 기반으로 하였다.
또한 사용되는 툴은 win-acme를 사용하여 진행한다.
명령 프롬프트(CMD)를 열어 win-acme를 다운로드 받은 폴더로 경로를 이동한다.
wacs.exe 파일을 열면 정해진 순서에 맞게 진행하는 방법과
명령어를 통해 SSL 인증서를 발급받는 방법이 있다.
1) wacs.exe 파일을 실행하여 절차에 맞게 SSL 인증서를 발급받는 방법
win-acme 2.2.9.1701 버전을 기준으로 차례대로 아래와 같이 입력한다.
- M: Create certificate (full options)
- 2: Manual input
- Host: SSL 인증서를 적용할 도메인
- 1: Separate certificate for each domain (e.g. *.example.com)
- 1: [http] Save verification files on (network) path
- Path: 웹 루트 디렉토리
- N: Copy default web.config before validation? (y/n*) - no
- 2: RSA key
- 2: PEM encoded files (Apache, nginx, etc.)
- 1: None
- 5: No (additional) store steps
- 3: No (additional) installation steps
아래와 같이 뜨면 정상적으로 ssl 인증서 파일(pem)이 생성된 것이다.
2) 명령어를 통해 SSL 인증서를 발급받는 방법
아래의 명령어를 자신에 맞게 고친 후, 실행하면 된다.
wacs.exe --target manual --host HOSTNAME --webroot C:\dev\nginx-1.26.1\html --store pemfiles --pemfilespath C:\dev\nginx-1.26.1\ssl
- --target manual : 수동으로 인증서를 발급받겠다는 의미이다.
- --host HOSTNAME : 인증서를 발급받을 도메인 이름을 HOSTNAME 부분에 입력한다.
- --webroot : ACME 챌린지 파일을 저장할 웹 서버의 루트 디렉토리로 지정한다. nginx의 경우 \html 경로로 설정해두면 된다.
- --store pemfiles : 발급받을 인증서를 PEM 파일 형식으로 저장하겠다는 의미이다.
- --pemfilepath PATH : PEM 파일을 저장할 경로 PATH를 지정한다. nginx 디렉토리 내의 편의상 SSL 폴더를 만들어 사용하는 것이 편하다.
실행을 하면 다음과 같이,
Certificate [Manual] HOSTNAME created라고 뜰 것이다.
그럼 정상적으로 SSL 인증서가 발급된 것이다.
- 명령어의 installation 부분은 내가 스크립트를 잘못 작성하였기 때문에 나타나는 에러로 무시해도 된다.
내가 지정한 경로에 PEM 파일이 생성된 것을 확인할 수 있다.
nginx에 SSL 적용하기
nginx가 설치되어 있는 디렉토리에서 conf 폴더로 이동한다.
nginx.conf 파일을 열어 아래와 같이 server 블록을 수정 및 추가해준다.
기존 도메인 server 블록 수정하기
SSL을 적용하면 http의 요청을 https로 바꿔서 응답해주어야 한다.
listen의 80은 기본 http 요청의 기본 포트를 의미한다.
아래의 코드는 nginx의 nginx.conf 파일 내용 중,
80 포트로 들어오는 http 도메인의 주소를 https 주소로 리다이렉트 시키도록 하는 것이다.
중요한 것은 return 301 부분을 추가하고, location = / 부분은 삭제하면 된다.
server {
listen 80; # Flask Babychat
server_name babychat.xyz;
return 301 https://$server_name$request_uri; # 이 부분 추가
# https로 리다이렉트하기 때문에 location / 부분은 삭제
#location / {
# proxy_pass http://192.168.0.78:3999;
#}
}
SSL이 인증된 도메인 server 블록 추가하기
SSL 인증서를 포함하여 HTTPS 요청을 받을 수 있도록 해주는 코드이다.
443은 HTTPS 포트의 기본 포트를 의미한다.
ssl 인증을 적용하기 위해서는 win-acme 도구를 통해 생성된 pem 형식의 파일을 이용한다.
새롭게 생성된 pem 형식의 파일(key, crt, chain)을 상황에 맞게 자신의 서버 블록에 넣어주면 된다.
nginx의 버전 별로 설정 부분이 나뉘긴 하는데, 내용은 아래와 같다.
- 참고 : sslcert.co.kr - 'NginX SSL 인증서 설치/적용 가이드'
server {
listen 443; (1.15 버젼 부터는 listen 443 ssl; 형식으로 변경됨)
ssl on; (1.15 버젼 부터는 옵션 지원 종료)
server_name www.sslcert.co.kr sslcert.co.kr; (지정한 서버인증서에 포함(지원)된 도메인)
ssl_certificate_key /파일경로/www.sslcert.co.kr.key.pem; (개인키 파일 지정)
ssl_certificate /파일경로/www.sslcert.co.kr.all.crt.pem; (서버인증서+체인+루트 통합 unified 파일 지정)
ssl_protocols TLSv1.2; (서버 환경에 따라 선택적 적용)
location /
root path
}
}
나의 경우, 현 시점의 nginx 안정 버전인 1.26.1 버전을 사용하여 아래와 같이 구상하였다.
server {
listen 443 ssl;
server_name babychat.xyz;
ssl_certificate C:/dev/nginx-1.26.1/ssl/babychat.xyz-crt.pem;
ssl_certificate_key C:/dev/nginx-1.26.1/ssl/babychat.xyz-key.pem;
ssl_trusted_certificate C:/dev/nginx-1.26.1/ssl/babychat.xyz-chain.pem;
location / {
proxy_pass http://192.168.0.78:3999;
}
}
80 포트와 443 포트에 대한 서버 블록 코드를 추가 및 수정이 완료되었다면,
이제 nginx를 실행해서 HTTPS로 정상적으로 접속이 되는지 확인해보면 된다.
# (nginx 설치 경로에서 명령 프롬프트 실행)
# nginx 실행
nginx
# 만약 nginx가 실행되어 있다면 재시작
nginx -s reload
HTTPS 적용 확인을 위한 사이트 접속
https로 정상적으로 잘 접속이 된다!
오류: 트러블 슈팅
win-acme 인증서 발급 중 오류1
Error: this may be because of insufficient rights or a non-Microsoft webserver using port 80
An error occured while commiting validation configuration
Authorizing using http-01 validation (SelfHosting)
Unable to activate listener,
this may be because of insufficient rights or a non-Microsoft webserver using port 80
An error occured while commiting validation configuration:
다른 프로세스가 파일을 사용 중이기 때문에 프로세스가 액세스 할 수 없습니다.
An error occured during post-validation cleanup: Cannot access a disposed object.
Object name: 'System.Net.HttpListener'.
Deactivating pending authorization
Create certificate failed
80포트가 이미 사용중이기 때문에 win-acme(wacs)가 접근을 할 수 없다는 의미이다.
현재 80포트를 사용중인 서비스를 종료한다.
nginx를 사용중이라면 nginx가 80포트를 사용할 확률이 매우 높다.
nginx를 종료하고 다시 진행해보자.
win-acme 인증서 발급 중 오류2
Error: Timeout during connect (likely firewall problem)
Authorizing...
Authorizing using http-01 validation (SelfHosting)
Authorization result: invalid
{"type":"urn:ietf:params:acme:error:connection",
"detail":"xx.xxx.xxx.xxx: Fetching http://example.com/.well-known/acme-challenge/3ew_599WKxgh28LFE9hEPIM0rZ2tCg_cCo_gOcrYw8Q:
Timeout during connect (likely firewall problem)","status":400,"instance":null}
Deactivating pending authorization
Create certificate failed
시간이 초과될 때까지 접속을 하지 못했다는 소리다.
오류 내용에서 유추할 수 있듯이 80 포트가 닫혀있을 가능성이 있다.
인바운드로 들어오는 80포트를 사용할 수 있도록 열어주자.
- 시작 - 고급 보안이 포함된 Windows Defender 방화벽 실행
- 인바운드 규칙 - 이름(BranchCache 호스트 캐시 서버(HTTP-In)) 더블 클릭
- 이름과 설명 및 사용함 체크
- 확인
포트를 열고 다시 진행하면 된다.
HTTPS 접속 오류: 사이트에 연결할 수 없음
nginx에서 SSL 설정을 다했는데도 http는 정상적으로 처리되는데 https만 사이트 연결이 되지 않은 경우가 있다.
이럴 경우는 위와 같이 'win-acme 인증서 발급 중 오류2'와 같은 이유로 방화벽에서 차단되었을 수도 있지만,
인터넷 공유기 때문일 확률이 매우 높다.
인터넷 공유기는 자체 네트워크 설정을 지니는데,
포트 포워딩에서 허용되지 않는 포트는 접속을 차단하기 때문이다.
포트 포워딩을 허용해주려면 아래의 글을 참고하는 것이 좋다.
내용이 워낙 길어져서 링크로 대체하겠다. 외부에서 로컬 DB에 접속하는 방법을 다룬 글인데,
글 내용 중 외부에서 접속을 허용하기 위한 방법도 같이 기재되어 있다.
☞ MySQL - 외부에서 로컬 DB 서버 접속하기 (DB 서버 구축)
✅ 확인해야할 챕터
- 내부 포트 열기 (방화벽 해제)
- 외부 포트 허용하기 (포트 포워딩)