ImageUs-https

codakcodak·2023년 3월 9일
0

ImageUs

목록 보기
17/17
post-thumbnail

문제상황

  • 일반적인 http요청은 데이터가 암호화되지 않아 보안상으로 위험하다.

  • 일반적인 브라우저들은 https를 권장하여 http요청으로 보낼 경우 위험표시가 뜨게 되어 미관상으로도 안좋은 인식이 생긴다

해결방법

  • docker환경에서 certbot이라는 컨테이너를 이용하여 무료로 ssl인증서를 발급하는 Lets Encrypt로 ssl을 발급받는다.

  • 이미 구축된 이미지인 certbot은 사실 ssl인증서를 갱신하는 역할이기 때문에 초기에 ssl을 쓰기위해 미리 발급받는다.

적용과정

1.nginx>defualt.conf설정

upstream imageus_back {
    server imageus_back:4000;
}

upstream imageus_image {
    server imageus_image:4001;
}

server {
	#기본적으로 브라우저에서 요청하는 포트를 받는다.
    listen 80;
    server_name codakcodak.site;
    server_tokens off;
	
    #ssl을 발급 및 갱신 하기위한 url
    location /.well-known/acme-challenge/ {
        allow all;
        root /var/www/certbot;
    }
	#위의 url을 제외한 모든 url을 443포트를 사용하는 https로 redirect한다.
    location / {
        return 301 https://$host$request_uri;
    }    
}

server {
        listen 443 ssl;
        server_name codakcodak.site;
        server_tokens off;
		
        
        #ssl로 발급받은 공개키와 비밀키 명시
        ssl_certificate /etc/letsencrypt/live/codakcodak.site/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/codakcodak.site/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
		#프론트 라우팅
        location / {
                root /usr/share/nginx/html;
                index index.html;
                try_files $uri $uri/ /index.html;
        }
		#스웨거 라우팅
        location /swaggerui {
                proxy_pass http://imageus_back;
                proxy_set_header  X-Real-IP $remote_addr;

                proxy_connect_timeout 5;
                proxy_send_timeout 5;
                proxy_read_timeout 5;
                send_timeout 5;
        }
		#백서버 라우팅
        location /backapi {
                proxy_pass http://imageus_back;
                proxy_set_header  X-Real-IP $remote_addr;

                proxy_connect_timeout 5;
                proxy_send_timeout 5;
                proxy_read_timeout 5;
                send_timeout 5;
        }
		#이미지서버 라우팅
        location /imageapi {
                proxy_pass http://imageus_image;
                proxy_set_header  X-Real-IP $remote_addr;

                proxy_connect_timeout 10;
                proxy_send_timeout 10;
                proxy_read_timeout 10;
                send_timeout 5;

        }
}

2.docker-compose.yml설정

  certbot:
    container_name: certbot
    image: certbot/certbot
    restart: unless-stopped
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
  
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
    container_name: elasticsearch
    environment:
      - cluster.name=es-docker
      - node.name=node1
      - bootstrap.memory_lock=true
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
    ports:
      - 9200:9200
    restart: always
    platform: linux/amd64
    healthcheck:
      test: curl -u elastic:elastic -s -f elasticsearch:9200/_cat/health >/dev/null || exit 1
      interval: 20s
      timeout: 5s
      retries: 100

*certbot을 통해 인증서를 발급 및 갱신하므로 nginx의 폴더와 공유를 해야 niginx가 발급받은 ssl을 쓸 수 있다.

3.첫 ssl 발급

https://github.com/wmnnd/nginx-certbot/blob/master/init-letsencrypt.sh

  • 위의 링크의 init-letsencrypt.sh을 받고 도메인,이메일,발급받을 path를 입력
  • 기존에 작성해 놓았는 docker-compose로 이미지를 빌드
  • init-letsenscrypt.sh실행
  • path/conf/live/도메인에 발급받은 ssl파일들 확인
    (cert.pem,chain.pem,fullchain.pem,privkey.pem)

4.docker-compose 가동

  • docker-compose up

어려웠던 개념

  • nginx의 /well-known/acme-challenge/ 라우팅 용도

    • ssl발급을 위해서는 ca(ssl을 발급하는 회사)에게 서버가 보내는 ip와 도메인이 일치하는지 확인해야 그 서버가 신뢰할 수 있다.

    • 초기 ssl을 발급하는 init-letsencrypt.sh와 certbot의 내부적으로 보면
      nginx에서 root경로 였던 /var/www/certbot에 서버에서 생성한 토큰을 /well-known/acme-challenge/토큰이름(파일)으로 저장한다.
      그리고 삽입해놨던 이메일과 도메인주소와 위의 토큰이름을 ca회사에게 보내면 ca회사는 전달받은 도메인으로 토큰이름이 있는 도메인/var/www/certbo/well-known/acme-challenge/토큰이름(파일)
      요청을 보내어 파일이 실제로 존재하는지 확인한다.
      이때 확인이 되었다면 결국 서버는 자신의 도메인 안에서 자원을 만든것을 직접 ca회사에게 확인시켜준 것이므로 이로서 서버는 신뢰할 수 있다고 판단하고 ssl인증서를 발급한다.

  • https의 실제 통신 방식
    * 클라이언트와 서버가 실제로 데이터가 오가기 전에 서버에서 먼저 ssl인증서를 준다.

    • ssl인증서에는 서버의 공개키와 ca의 인증정보들이 있다.
    • 클라이언트는 자신만의 대칭키를 생성하고 이를 서버의 공개키로 암호화하여 서버에 보낸다.
    • 클라이언트에서 보낸 암호화된 대칭키는 오직 공개키를 보낸 서버만이 해독할 수 있다.
    • 클라이언트와 서버에서 대칭키로 암호화된 데이터를 주고 받는다.
    • 위의 과정에 따르면 오직 주고 받는 클라이언트와 서버외에는 암호화된 데이터들을 풀 수 없다.

    결과

  • 브라우저에서 경고메세지가 보이지 않아 서비스가 쾌적해보인다.

  • 클라이언트와의 암호화된 데이터들을 안전하게 주고받아 보안적으로 강화되었다.

profile
숲을 보는 코더

0개의 댓글