SSL 인증서 적용

BinaryHyeok·2023년 3월 27일
0
post-thumbnail

시작하면서

Let's Encrypt를 통해서 무료로 SSL 인증서를 발급합니다.

1. SSL 인증서 발급 및 Nginx 적용

EC2에서 다음 명령어로 Nginx용 Certbot을 설치합니다.

sudo apt update
sudo apt upgrade -y
sudo apt install certbot python3-certbot-nginx

Let's Encrypt SSL 인증서 발급에는 4가지 방법이 있습니다.

  1. webroot : 사이트 디렉토리 내에서 인증서 유효성을 확인할 수 있는 파일을 업로드하여 인증서를 발급하는 방법
    • 실제 작동하고 있는 웹서버의 특정 디렉토리의 특정 파일 쓰기 작업을 통해서 인증
    • nginx를 중단시킬 필요가 없음
    • 인증 명령에 하나의 도메인 인증서만 발급 가능
  1. 웹서버
    • Nginx나 아파치와 같은 웹서버에서 직접 SSL 인증을 실시하고 웹서버에 맞는 SSL 세팅값을 부여
    • 발급이나 갱신을 위해 웹서버를 중단시킬 필요가 없음
    • 인증서 갱신 시 상황에 맞게 세팅을 자동으로 업데이트
    • 사용자가 세팅을 변경할 수 있지만 자동 업데이트 시 반영되지 않음

  1. Standalne : 사이트 작동을 멈추고 이 사이트의 네트워킹을 이용해 사이트 유효성을 확인해 Let's Encrypt SSL 인증서를 발급하는 방식
    • 80포트로 가상 standalone 웹서버를 띄워 인증서를 발급
    • 여러 도메인 발급 가능
    • 인증서 발급 전에 Nginx를 중단하고 발급 완료 후 Nginx 다시 시작

  1. DNS : 도메인을 쿼리해 확인되는 TXT 레코드로 사이트 유효성을 확인하는 방법
    • 와일드 카드 방식으로 인증서를 발급 가능
    • 이 방법은 서버 관리자가 도메인 DNS를 관리/수정할 수 있어야 한다.
    • 인증서 갱신 시마다 DNS에서 TXT값을 변경해야 하므로 외부에서 TXT 레코드를 입력할 수 있도록 DNS가 API를 제공하는 경우만 갱신 과정을 자동으로 처리

Nginx를 종료하지 않고 인증서를 발급받기 위해 웹서버를 통한 방법을 사용합니다.

이전의 글에서 Nginx를 설치하고 난 뒤 /etc/nginx/conf.d/ 디렉토리 아래에 설정파일을 만들었습니다.
이 설정파일에서 server_name [도메인 또는 ip]; 와 같이 설정하였습니다.

이제 nginx가 제대로 작동하고 있는지 다음 명령어를 통해 확인합니다.
sudo nginx -t

이전의 Nginx 설치에서 방화벽에서 HTTPS 허용은 했으니 넘어가겠습니다.

동작하고 있다면 SSL 인증서를 발급받습니다.

sudo certbot --nginx -d [도메인]

이 후 /etc/letsencrypt/ 디렉토리 아래에 자동 SSL 적용 옵션을 제안해줍니다.
자동으로 옵션을 적용하도록 수락하였습니다.

이제 /etc/nginx/conf.d/아래의 설정파일에 SSL 인증에 대한 내용이 포함되었을 것입니다.

server {
        server_name [도메인];

        location / {
                proxy_pass http://[도메인]:3000;
        }

        location /api {
                proxy_pass https://[도메인]:9999;
        }

        location /test {
                proxy_pass https://[도메인]:8888;
        }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/[도메인]/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/[도메인]/privkey.pem; # managed by Certbot
#    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
#    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
        if ($host = [도메인]){
                return 301 https://$host$request_uri;
        }

        listen 80;
        server_name [도메인];
        return 404; # managed by Certbot
}

80포트에서는 http로 요청이 들어오게되면 https로 리턴하여 443포트가 요청을 받도록 합니다.

하지만 이 상태에서 서버에 API요청을 보내면 서버가 Https를 받지 못해 에러가 발생합니다.
이를 해결하기 위해서 Springboot에도 SSL인증을 합니다.

2. SpringBoot SSL 적용

SpringBoot는 내장 Tomcat을 사용하고 있는데 톰캣은 JKS, PKCS11, PKCS12 포맷의 keystore를 이용한 SSL/TLS 설정을 지원합니다.
따라서 발급받은 인증서를 PKCS12 형식으로 변환합니다.

/etc/lentsencrypt/live/[도메인]/ 디렉토리 아래에 인증서 pem 키가 있습니다.
이 인증서가 위치한 경로에서 다음 명령어를 입력해 keystore.p12 파일을 생성합니다.

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name ttp -CAfile chain.pem -caname root

password를 입력하라는 말이 나오면 원하는 password를 입력합니다.
이 password는 springboot 설정에서 사용합니다.

이후 이 keystore을 내 pc로 가져와서 Springboot프로젝트의 resource 디렉토리 아래에 넣어줍니다.

keystore 가져오기

scp -i [ssh pem키 경로] -r [ec2사용자명]@[ec2아아피/도메인]:[keystore 경로] [keystore를 가져올 경로] 

저는 SSL폴더를 하나 생성하여 keystore를 넣어줬습니다.

이제 Springboot 설정파일에서 ssl 설정을 추가해줍니다.
yml파일에 작성하였습니다.

다음과 같이 입력하면 설정완료입니다.

3. Jenkins reverse proxy 설정

nginx에 SSL을 적용한 후에는 젠킨스의 포트인 8080으로 직접 접근할 수 없게되었습니다.
그래서 jenkins도 nginx를 통해 리버스 프록시 설정을 해주었습니다.

우선 jenkins의 context path를 수정하기 위해 jenkins docker-compose 파일을 수정하였습니다.
기존에 작성된 파일에서 다음 옵션을 추가했습니다.

--prefix 옵션을 통해서 context path를 추가하였습니다.

이제 nginx 설정에서 /jenkins로 요청이 들어오면 8080포트로 이동하도록 설정하였습니다.

리버스 프록시 설정이 끝났다면 jenkins 페이지에서 경로를 수정해줍니다.
DashboardSystem SettingJenkins Location 에서 Jenkins URL을 수정합니다.
https://[도메인]/jenkins/ 와같이 설정하였습니다.

마지막으로 설정해놨던 webhook들의 주소도 변경합니다.
GitlabSettingsWebhooks 에서 설정해놨던 웹훅들의 주소도 변경합니다.
httphttps
:8080//jenkins/ 로 변경하였습니다.

마치면서

처음에는 Nginx에만 SSL 인증서를 적용하면 될 줄 알았는데, 생각보다 변경해야 될 부분이 많았습니다.


[참고]

0개의 댓글