Nginx SpringBoot Https 적용 [2] (Nginx Https 설정)

10000DOO·2023년 3월 21일
1

YouHaveTo

목록 보기
9/12
post-thumbnail

1편에서 이어지는 내용입니다.

운영체제는 RedHat 기반의 RockyLinux 9.1을 사용했습니다.
기본적으로 80포트는 개방되어 있어야합니다.
// 80포트 개방
firewall-cmd --permanent --zone=public --add-port=80/tcp
//방화벽 재가동
firewall-cmd –-reload
(네트워크 포트 포워딩은 시리즈 게시글 중에 있습니다)

📌 SSL 인증서 발급

1. YUM epel저장소 추가

yum install epel-release

EPEL은 Extra Packages for Enterprise Linux 의 약자로 RHEL/CentOS 에 포함되지 않은 여러 패키지들을 설치할 수 있는 community 기반의 저장소입니다.
EPEL 은 fedora 에서 관리하고 있으며 제공되는 패키지들은 IT Automation 도구인 ansible, 성능 수집 도구인 collectd, Message Broker 인 RabbitMQ 등이 있습니다.

2. YUM cerbot 설치

yum install certbot
cerbot은 SSL 인증서를 유료로 발급받을 수 있도록 도와주는 라이브러리입니다.
cerbot과 Let's Encrypt를 사용해서 무료로 SSL을 받을 수 있습니다.

https://letsencrypt.org

3. 443 방화벽 오픈

firewall-cmd --permanent --add-service=https
firewall-cmd --reload
https는 기본적으로 443포트를 사용합니다. 포트는 사용자가 변경할 수 있지만 저는 그대로 443을 사용하겠습니다.

4. Nginx 종료

docker stop 컨테이너 ID or 컨테이너 이름
–standalone 옵션으로 인증서 생성 시 오류가 나기 때문에 잠깐 nginx를 꺼야 합니다.
저는 도커를 사용하기 때문에 컨테이너를 종료시켰습니다.

5. Letsencrypt 인증서 생성

# 1. 도메인이 한개일때
certbot certonly --standalone -d 생성할 도메인

# 2. 도메인이 여러개일때
certbot certonly --standalone -d 생성할 도메인1 -d 생성할 도메인2
모두 yes를 입력하고 넘어갑니다.
발급이 완료되면  /etc/letsencrypt/live/도메인 이름 폴더가 생성되고 그 안에는 .pem 키들이 있는 것을 확인하실 수 있습니다.

📌 Nginx 설정

1. options-ssl-nginx.conf 파일 생성

/etc/letsencrypt/ 위치에 options-ssl-nginx.conf파일을 생성합니다.
vim options-ssl-nginx.conf

아래 내용을 넣습니다.

# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file. Contents are based on https://ssl-config.mozilla.org

ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

2. Nginx 설정 파일 작성

nginx 설정을 위해 nginx 컨테이너와 연결된 볼륨을 만들고 거기에 설정 파일을 작성해 준다.
# 볼륨 생성
docker volume create 사용할 볼륨 이름
ex) docker volume create nginx

# 볼륨 주소 확인
docker volume inspect 볼륨 이름
ex) docker volume inspect nginx

#결과
[
    {
        "CreatedAt": "2023-03-19T00:54:55+09:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/nginx/_data",
        "Name": "nginx",
        "Options": null,
        "Scope": "local"
    }
]

# 볼륨 위치로 이동
cd /var/lib/docker/volumes/nginx/_data

# 설정 파일 생성
vim default.conf


# 파일 내용
upstream app {
	least_conn;
	server 서버 ip주소:포트 번호;
    server 서버 ip주소:포트 번호;
}

server {
	listen 443 ssl;
	server_tokens off;
	server_name 도메인 이름;

	ssl_certificate /etc/letsencrypt/live/you-have-to.duckdns.org/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/you-have-to.duckdns.org/privkey.pem;
	include /etc/letsencrypt/options-ssl-nginx.conf;

	location / {
		proxy_pass https://app;
		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;
	}
}
저는 로드밸런싱을 해주느라 
upstream app {
	least_conn;
	server 서버 ip주소:포트 번호;
	server 서버 ip주소:포트 번호;
}
내용이 추가되었습니다.
로드밸런싱을 하지 않는다면 proxy_pass에 https://서버 ip주소:포트 번호를 적어주시면 됩니다.

3. Nginx 실행

docker run --name nginx -d -p 443:443 -e TZ=Asia/Seoul -v nginx:/etc/nginx/conf.d/ -v /etc/letsencrypt:/etc/letsencrypt nginx

-p는 포트 번호 입니다.
-e TZ=Asia/Seoul는 컨테이너의 시간대를 한국으로 맞춥니다.
-v nginx:/etc/nginx/conf.d/ nginx설정 파일을 적용시키기 위해 아까 만들었던 볼륨과 컨테이너 내부의 설정파일 위치를 연결합니다.
-v /etc/letsencrypt:/etc/letsencrypt ssl 인증서 위치를 nginx에 적용시키기 위해 컨테이너 밖에 있는 ssl 인증서 위치와 컨테이너 내부 ssl 인증서가 있어야 될 위치를 연결합니다.

4. 자동 갱신 설정

ssl 인증서는 3개월의 유효기간을 가지기 때문에 그전에 재발급이 필요합니다.
리눅스의 crontab을 활용해서 매월 재발급하도록 설정하겠습니다.
crontab -e

0 4 1 * * /bin/bash -l -c 'certbot renew --force-renew --cert-name 도메인 이름'

해당 명령어는 매월 1일 새벽 4시에 ssl 인증서를 재발급하는 명령어입니다.
--force-renew 옵션은 유효기간이 남은 인증서가 있더라도 강제로 재발급되도록 해줍니다.
기본적으로는 유효기간이 1달 이내일 때 재발급이 가능합니다.

📚 참고 자료

https://jinsiri.tistory.com/605#recentComments
https://www.lesstif.com/system-admin/epel-yum-100205250.html

profile
iOS 개발자 지망생 https://github.com/10000DOO

0개의 댓글