Nginx 임시 인증서 적용하기
RECOMMEND POSTS BEFORE THIS
1. Problem Context
현재 진행하는 프로젝트에서 react-qr-scanner라는 라이브러리를 사용했다. 이 라이브러리는 카메라를 사용해 QR 이미지를 스캔하는 기능을 제공한다. 적용하는데 다음과 같은 문제점이 있었다.
- 브라우저에서 QR 스캔을 위해 카메라를 실행하려면
HTTPS혹은localhost에서만 가능하다. - 기능 개발 후 PM(project manager)들이 테스트할 수 있는 환경을 구축해야 한다.
위의 문제들을 해결하기 위해 임시 인증서를 만들고 Nginx에 적용하여 HTTPS 서비스를 하는 방법에 대해 정리했다.
2. Make Temporal Certificate
OpenSSL를 사용하면 임시 인증서를 생성할 수 있다.
- 프로젝트에
ssl폴더를 생성한다. openssl req명령어를 통해 인증서를 생성한다.- PKCS#10 형식의 인증서 서명 요청(CSR, certificate Signing Request)을 생성한다.
- 테스트를 위해 루트(root) CA(certificate authority)로써 자체 서명 인증서를 생성할 수 있다.
- 다음과 같은 추가 설정들을 통해 인증서를 생성한다.
-x509-x509옵션을 통해 인증서 서명 요청이 아닌 인증서를 즉시 발급한다.- 테스트를 위한 인증서 발급 방법이다.
-days 30- 30일 동안 유효한 인증서를 생성한다.
-nodes- 만약 비공개 키를 생성한다면 암호화시키지 않는 옵션이다.
- OpenSSL 3.0부터 제거되었으며
-noenc옵션을 사용한다.
-newkey rsa:2048-key옵션이 지정되지 않은 경우 새로운 비공개 키를 생성하는데 사용된다.- 암호화 알고리즘을 함께 지정한다.
-keyout ssl/nginx-ssl.key- 비공개 키를 파일로 만드는 옵션이다.
-out ssl/nginx-ssl.crt- 인증서를 파일로 만드는 옵션이다.
CSR을 위한 정보를 입력한다.- 나라 - KR
- 지역 - Seoul
- 도시 - Seoul
- 기관 - VMWare
- 조직 - Tanzu Labs
- 인증 받을 도메인 주소 - nginx-ssl.host.com
- 이메일 주소 - test@test.com
ssl경로에 인증서nginx-ssl.crt와 비공개 키nginx-ssl.key가 생성된 것을 확인한다.
$ mkdir ssl
$ openssl req -x509\
-days 30\
-nodes\
-newkey rsa:2048\
-keyout ssl/nginx-ssl.key\
-out ssl/nginx-ssl.crt
Generating a 2048 bit RSA private key
...............................+++++
................................+++++
writing new private key to 'ssl/nginx-ssl.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:KR
State or Province Name (full name) []:Seoul
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) []:VMWare
Organizational Unit Name (eg, section) []:Tanzu Labs
Common Name (eg, fully qualified host name) []:nginx-ssl.host.com
Email Address []:test@test.com
$ ls -al ssl
total 16
drwxr-xr-x 4 junhyunk staff 128 Mar 25 19:59 .
drwxr-xr-x 15 junhyunk staff 480 Mar 25 19:58 ..
-rw-r--r-- 1 junhyunk staff 1310 Mar 25 19:59 nginx-ssl.crt
-rw-r--r-- 1 junhyunk staff 1704 Mar 25 19:59 nginx-ssl.key
3. Practice
도커 컨테이너(docker container)를 통해 서비스를 실행한다.
3.1. default.conf
우선 nginx 설정 파일을 살펴보자. 임시 인증서에 대한 설정을 명시한다. 앞서 만든 임시 인증서를 사용하도록 인증서, 인증서 키 경로를 등록한다.
- 80 포트로 접근하는 경우 443 포트로 리다이렉트(redirect)한다.
- 443 포트로 들어오는 요청에 이전 단계에서 생성한 임시 인증서를 적용한다.
ssl_certificate설정으로 인증서 경로를 지정한다.ssl_certificate_key설정으로 비공개 키 경로를 지정한다.
- 등록한 비공개 키는 인증서 내부에 포함된 공개 키에 대응되는 비대칭 키이다.
server {
listen 80;
server_name nginx-ssl.host.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name nginx-ssl.host.com;
ssl_certificate /ssl/nginx-ssl.crt;
ssl_certificate_key /ssl/nginx-ssl.key;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ = 404;
}
}
3.2. Dockerfile
애플리케이션 이미지를 만들 때 사용하는 도커 파일(Dockerfile)이다. nginx 컨테이너를 실행할 때 인증서가 담긴 ssl 디렉토리를 이미지 내부에 복사한다.
FROM node:16-buster-slim as builder
WORKDIR /app
COPY package.json .
RUN npm install --silent
COPY . .
RUN npm run build
FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf
COPY ssl /ssl
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
3.3. Add Host for Practice
nginx-ssl.host.com는 인증서 테스트를 위해 임시로 사용하는 호스트이므로 테스트 PC host 파일에 등록한다. 이미 발급 받은 도메인 주소를 사용해 이 포스트의 실습을 따라하는 경우에 이 작업은 불필요하다.
- AWS EC2 컨테이너를 사용해 공개 도메인 주소가 있는 경우
- 사전에 발급 받은 도메인 주소가 있는 경우
운영체제에 따라 호스트 파일을 관리하는 방법이 다르다. 본인은 맥(mac)에서 작업을 하고 있기 때문에 이를 기준으로 작성하였다.
- 로컬 호스트와 동일한
127.0.0.1IP에nginx-ssl.host.com도메인을 매칭한다.
$ sudo vi /etc/hosts
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
127.0.0.1 nginx-ssl.host.com
::1 localhost
# Added by Docker Desktop
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section
3.4. Run Application on Nginx
도커 이미지를 빌드한다.
$ docker build -t nginx-ssl .
...
=> => writing image sha256:6c9bcd2411fe0345cc861f21970ba2171297f8752a36e71e04e265957107fe35 0.0s
=> => naming to docker.io/library/nginx-ssl 0.0s
컨테이너를 실행한다. 외부에서 접근할 수 있도록 80, 443 포트를 모두 노출한다.
$ docker run -d\
-p 80:80\
-p 443:443\
--name nginx-ssl\
nginx-ssl
e856fc0cf3f3d3d6ca3a127646f4e6cdbe50544a822e1765b57195f0823de512
컨테이너 실행 결과를 살펴보자. 공인된 CA에서 발급한 인증서가 아니기 때문에 경고 메시지가 보여지지만, 인증서가 적용된 것을 확인할 수 있다.
- 안전하지 않은 이동을 눌러 사이트에 접속한다.
- 유효하지 않은 인증서를 사용했기 때문에 브라우저 주소창에 경고 메시지가 보인다.
- 인증서 정보를 살펴볼 수 있다. 인증서를 만들 때 작성한 정보들을 볼 수 있다.
CLOSING
이번 글에서 다룬 내용은 어디까지나 임시 테스트 환경을 구축하기 위한 인증서 적용 방법이다. 운영 환경을 위해 도메인, 인증서, 비공개 키 등을 이미 발급 받았다면 임시 인증서 생성을 제외하곤 프로젝트 상황에 맞게 적절하게 적용할 수 있다.
댓글남기기