[CI/CD] Docker 와 Github Actions 를 활용한 CI/CD 환경 구축 - (3) HTTPS 설정과 NGINX

HJ·2024년 3월 20일
0

CI/CD

목록 보기
3/4
post-thumbnail

암호화 살펴보기

HTTPS

브라우저에서 서버로 데이터를 전송할 때 HTTP 를 사용하면 입력한 그대로 누구든 알아볼 수 있게 전달됩니다. 만약 로그인 정보가 위처럼 전달되면 보안 상 좋지 않습니다.

그래서 HTTPS 를 사용하는데 HTTPS 는 위처럼 서버로 전달하는 정보들을 암호화해서 보내기 때문에 다른 사람이 보더라도 알아볼 수 없습니다. 이때 정보를 암호화할 때는 대칭키 암호화 방식을 사용하는데 이는 아래에서 살펴보도록 하겠습니다.


대칭키 암호화

대칭키 암호화는 암호키와 복호화키가 동일하며, 대칭키는 통신 주체들 사이마다 필요합니다. 서버와 브라우저가 동일한 대칭키를 가지고 있어야 브라우저에서 대칭키로 암호화 한 정보를 서버에서 복호화할 수 있습니다.

만약 대칭키가 노출된다면 대칭키를 가진 누군가가 암호화 된 정보를 볼 수 있게 되기 때문에 통신 당사자 간 대칭키를 안전하게 공유하는데 많은 노력이 필요한데 이를 해결할 수 있는 것이 바로 DH( Diffie-Hellman ) 알고리즘이며, 안전하게 대칭키를 생성하기 위해 공개키 암호화 방식을 사용합니다.

아래에서 공개키 암호화 방식과 인증서를 살펴본 뒤, 공개키 암호화 방식을 이용해서 대칭키를 생성하는 방법에 대해 알아보도록 하겠습니다.


공개키 암호화

공개키 암호화 방식에는 암호화, 복호화에 두 가지 키가 사용됩니다. 하나는 공개키이고 다른 하나는 개인키인데 만약 공개키로 암호화하면 개인키로 복호화가 가능하고, 개인키로 암호화하면 공개키로 복호화할 수 있습니다.

예를 들어, 브라우저가 서버의 공개키로 암호화해서 전송하면 서버는 자신의 개인키로 이를 복호화해서 정보를 확인할 수 있게 됩니다.

추가적으로 개인키로 암호화하고, 자신의 공개키로 복호화할 수 있게 하는 것은 보통 송신자가 누구인지에 대한 정보가 필요할 때 사용하는데 대표적인 예시로 디지털 서명이 있습니다.


인증서

신뢰할 수 있는 기관에서 서버의 공개키를 검증해준다면 이를 기준으로 안전하게 서버를 이용할 수 있게 됩니다. 이를 위해서 사이트는 인증서가 필요합니다. 인증서란 인증기관( CA ) 에서 사이트에 발급하는 문서입니다.

인증서를 발급받기 위해 사이트에서 인증기관에 사이트 정보와 사이트의 공개키를 전달합니다. 인증 기관에서는 전달 받은 데이터를 검증하고, 검증이 완료되었다면 인증기관의 개인키로 서명을 하고 인증서를 생성합니다. 생성된 인증서는 사이트에 전달됩니다.

브라우저가 사이트에 접속하게 되면 사이트는 핸드쉐이크 과정을 거치면서 자신이 신뢰할 수 있는 사이트임을 증명하기 위해 브라우저에 사이트의 인증서를 전달합니다. 브라우저들은 이 CA 목록들이 내장되어 있고, 사이트로부터 전달받은 인증서를 CA 의 공개키로 복호화하여 진짜인지 가짜인지 판별할 수 있습니다.


공개키 방식으로 대칭키 생성하기

브라우저가 사이트에 접속할 때 핸드 쉐이크 과정을 거치면서 인증서를 전달한다고 했습니다. 인증서를 전달 받은 후에는 공개키 방식을 이용해 통신에 사용할 대칭키를 생성하게 되는데 이를 간단하게만 알아보도록 하겠습니다.

  1. 먼저 브라우저에서 임의로 난수를 생성해서 서버로 전달합니다.

  2. 서버도 임의로 난수를 생성한 뒤, 인증서와 함께 난수를 전달합니다.

  3. 서버에서 전달받은 인증서를 CA 의 공개키로 복호화합니다. 복호화를 하면 서버의 공개키가 나오게 됩니다.

  4. 브라우저는 자신이 생성한 난수와 서버가 전달한 난수를 조합해서 대칭키를 생성하고, 이를 서버의 공개키로 암호화하여 전달합니다.

  5. 서버는 자신의 개인키로 암호화된 대칭키를 복호화합니다.

  6. 핸드쉐이크가 종료되고, 생성된 대칭키로 HTTPS 통신이 시작됩니다.



HTTPS 설정하기

1. 인증서 발급

Let's Encrypt 라는 비영리 기관을 통해 무료로 인증서를 발급받을 수 있습니다. 3가지 방식으로 할 수 있다고 하는데 저는 standalone 방식을 사용하였습니다.

sudo certbot certonly --standalone -d {도메인}

위 명령어를 입력하면 이메일 입력하라 동의하라고 뜨는데 이미 이전에 다른 방식을 시도하면서 입력해서 그런가 뜨지 않았습니다. 명령어 수행 결과로 /etc/letsencrypt/live/{도메인명} 위치에 pem 파일이 생성됩니다.


2. NGINX 설정

docker-compose.yml 이 위치한 곳에서 data/nginx 디렉터리를 만들고 내부에 app.conf 파일을 작성합니다.

server {
        listen 80;
        server_name {도메인명};
        location / {
                return 301 https://$host$request_uri;
        }

}

server {
        listen 443 ssl;
        server_name {도메인명};

        ssl_certificate /etc/letsencrypt/live/{도메인명};/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/{도메인명};/privkey.pem;

        location / {
                proxy_pass  http://application:8080;
                proxy_set_header   Host                    $http_host;
                proxy_set_header   X-Real-IP               $remote_addr;
                proxy_set_header   X-Forwarded-For         $proxy_add_x_forwarded_for;
                proxy_set_header   X-Forwarded-Proto       $scheme;
        }
}

여기서 application 은 docker-compose.yml 에 작성한 스프링 애플리케이션의 이름입니다.



3. docker-compose.yml 작성

services:
  nginx:
    container_name: nginx
    image: nginx
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - /etc/letsencrypt:/etc/letsencrypt
    ports:
      - 80:80
      - 443:443
    depends_on:
      - application

작성한 내용 app.conf 를 nginx 의 /etc/nginx/conf.d 에 위치할 수 있도록 volumes 에 작성합니다. 또 인증 후 생성된 키를 연결하기 위해 /etc/letsencrypt 도 추가합니다.

profile
공부한 내용을 정리해서 기록하고 다시 보기 위한 공간

0개의 댓글