Nginx에서 SSL 적용해서 https 로 접속 되게 해볼까?

김태웅·2020년 12월 20일
11

서버

목록 보기
1/1
post-thumbnail

SSL이 뭐지?

SSL 인증서는 클라이언트와 서버간의 통신을 제3자가 보증해주는 전자화된 문서

클라이언트가 서버에 접속한 직후에 서버는 클라이언트에게 이 인증서 정보를 전달한다.
클라이언트는 이 인증서 정보가 신뢰할 수 있는 것인지를 검증 한 후에 다음 절차를 수행하게 된다.
SSL과 SSL 디지털 인증서를 이용했을 때의 이점은 아래와 같다.

  • 통신 내용이 공격자에게 노출되는 것을 막을 수 있다.
  • 클라이언트가 접속하려는 서버가 신뢰 할 수 있는 서버인지를 판단할 수 있다.
  • 통신 내용의 악의적인 변경을 방지할 수 있다.

(생활코딩에서 찾았다)

잘 모르겠고 SSL을 통해 http 프로토콜 에서 https(보안이 강화된 http) 적용이 가능하도록 해주는 것, 개인정보가 포함되거나 보안에 민감한 서버라면 반드시 https설정이 필요하다는 것 이라고만 알고 있자... (자세한 것은 직접 찾아보도록..)

SSL 인증서를 구매해볼까

SSL인증서의 종류는 참말로 많다.
제공해주는 업체도 많고 심지어 무료도 있다!

Nginx에서 무료로 https 설정하기 위해 Let's Encrypt를 사용하는 방법은 이곳을 참고해보자.
정리를 잘 해주셨고 적용하기도 쉽다.(사실 따로 글쓰기는 귀찮음)

내가 많이 사용했던 호스팅 제공 업체 '가비아'
SSL 구매 및 적용 서비스도 제공하고 있다.

구매를 완료하면 [마이페이지] > [호스팅] 에 구매한 SSL 내역이 존재한다.
(해당 글에서는 AlphaSign의 인증서를 기준으로 작성하지만 Sectigo의 인증서 등록 절차도 비슷하였다)
해당 화면에서 CSR정보를 입력하면 된다.

CSR?

SSL 서버를 운영하는 회사의 정보를 암호화하여 인증기관으로 보내 인증서를 발급받게 하는 일종의 신청서

CSR 키를 만들고 만들 때 입력한 정보를 통해 SSL을 신청할 수 있다.
CSR을 만드는 방법은 CLI창에서 openssl 명령어를 통해 만들 수도 있고, 나는 조금 만들기 쉽게 요 사이트 를 사용한다.

국가코드(C)
시/도(영문) (ST)
구/군(영문) (L)
회사명(영문) (O)
담당부서(영문) (OU)
도메인
인증서 비밀번호

위 7가지 정보는 기억해 두는 것이 좋다. (나는 혹시 몰라 캡쳐해서 가지고 있는다)
도메인은 SSL을 구입할 때 작성한 도메인과 일치해야 한다.

위 정보를 모두 입력 후 생성을 하면 개인키CSR이 나온다.
CSR, 개인키는 반드시 복사하여 따로 저장해두자!

CSR, 개인키 두가지 모두 vi 편집기 등 터미널을 통해 바로 저장하는 것이 좋다.
노트패드 / 메모장 등에 옮겨 둔 뒤 다시 vi 편집기 등을 통해 저장하게 되면 오류(unable to load Private Key)가 발생한다.

mydomain_csr, mydomain_key와 같이 저장해 두었다.

이제 다시 가비아로 돌아가서, 위에서 얻은 CSR 키값과 CSR을 얻기 위해 사용한 정보를 입력하면 된다.

이메일 확인

등록 후 1~2일 이내로 가비아에서 입력한 이메일을 확인해보면 이메일이 하나 와있을 것이다.

(Sectigo사의 이메일만 남아있어 대체하였지만, AlphaSign이나 다른 인증서의 경우도 비슷하다.)
간단한 인증 절차를 거치게 되면 빠른 시일 이내에 이번엔 가비아에서 다시 한번 이메일이 온다.
zip파일이 들어있을 텐데, 이 안에 중요한 파일들이 있다.

  1. 도메인 인증서
  2. 체인 인증서
  3. 루트 인증서

정확한 이름이 맞는지는 모르겠지만.. 하여튼 세가지 파일 + 개인키 파일, CSR파일을 모두 서버에 올려두자.

Nginx 적용

이제 다 했다고 볼수 있다.
아래 명령어로 세가지 파일을 합치자.

cat [도메인인증서] [체인인증서] [루트인증서] > [도메인명.pem](원하는 이름)

가비아에서 발급 받은 경우, 체인 인증서와 루트인증서가 합쳐진 bundle 파일을 함께 전달해 주기 때문에 다음과 같이 사용하면 된다.

cat 신청한_도메인_명_cert.pem Chain_RootCA_Bundle.crt > [원하는 이름]

도메인인증서, 체인인증서, 루트인증서 는 각 파일명을 쓰면 되고 도메인명.pem은 원하는 이름을 지정하면 된다.

여기서 주의할점!

각 인증서 파일들은
-----BEGIN 000000----- 로 시작하고
-----END 00000----- 로 끝나게 되어있다.
cat 명령어를 통하여 세 파일을 모두 합치게 되면
중간에 BEGIN과 END가 한 줄에 있는 경우가 생기게 된다.

반드시 vi이나 vim 명령어 등 에디터를 통하여 아래와 같이 강제로 개행해주어야 한다.

위 사항을 모두 완료하면 이제 Nginx 설정 파일을 열어주자.

sudo vi /etc/nginx/site-available/default 

https 접속을 위한 서버 블록을 생성해 주고,
기존 80번 포트 서버 블록은 일단 주석처리 해 두자.(아래에서 변경 할테니 삭제는 하지 말자)

server {
        listen 443 ssl;
        server_name [도메인명];

        ssl on;
        ssl_certificate [세가지 인증서 합친 파일 경로];
        ssl_certificate_key [개인키 파일 경로];
        ssl_prefer_server_ciphers on;
        location / {
                proxy_pass http://127.0.0.1:3000;(노드 서버 실행을 위한 proxy_pass 설정)
        }
}

서버를 Node.js로 구축하엿기에 proxy_pass를 설정해 두었지만, 각 서버의 환경에 맞게 설정해 주면 된다.
중요한 것은

listen 443을 통하여 Https로 접속 할 수 있도록 하는 것,
CSR생성 및 SSL 생성을 위해 제출한 도메인명과 도메인명이 일치해야 하며,
ssl_certificate 항목에 서버에 옮겨 놓은 경로를 제대로 입력해야할 것(세가지 인증서 파일이 정상적으로 합쳐져 있다는 가정 하),
ssl_certificate_key 항목에 개인키의 경로를 제대로 입력해야 할 것

이다.

여기서 주의할 점!

이 글의 위 링크로 걸어 둔 자동 생성기를 통하여 CSR과 개인키를 생성했다면,
개인키가 -----BEGIN RSA PRIVATE KEY----- 와 같이 시작하게 되어 있을 것이다.
그렇다면 위 설정을 하기 전에 개인키 파일의 암호화를 풀어줘야 한다.
풀어주지 않고 Nginx 재시작 시 PEM_do_header:bad password read 오류가 난다.

openssl rsa -in [기존인증서파일] -out [새로운인증서파일]

기존인증서파일과 새로운인증서파일 이름을 동일하게 설정하면 덮어쓰기가 되므로 다른 이름을 통해 저장하자.

위 명령어 실행 후 다시 개인키를 확인해보면 -----BEGIN PRIVATE KEY----- 로 RSA가 사라진 것을 확인 할 수 있다.

또다시 주의 할 점!

위 openssl 명령어를 통해 private key를 복호화 하려고 했을때 unable to load Private Key 라고 오류가 발생한다면 vi등의 편집기를 통해 key 파일을 확인 해보자.

위 사진 처럼 중간에 공백이 잘 들어가있는지 확인 후 다시 위의 openssl 명령어를 통해 복호화 해보자.

이제 다시 위 Nginx 설정을 해주고, Nginx를 재시작 해보자

sudo service nginx restart

오류가 나지 않았다면 정상 재시작 되었을 것이고, https로 접속하면 정상 접속 되는 것을 확인 할 수 있을 것이다.

마지막으로 http로 접속 시 https로 리다이렉트 될 수 있도록 설정 해주자.

server {
        listen 80;

        server_name [도메인명];

        return 301 https://$host$request_uri;
}

위와 같이 기존 http로 들어오던 80번 포트의 서버블록을 바꿔주면 자동으로 https로 리다이렉트되는 것을 확인 할 수 있을 것이다.

끝!

profile
Everything Counts

0개의 댓글