1. 도입 배경
현재 AWS로 EC2를 통해 API 프로젝트를 배포중이다.
Front에서 서버로 요청할 때, CORS 에러가 발생하였고 이를 해결하고 나니 브라우저에서 다음과 같은 에러가 발생하였다.
서버는 http이고 프론트에서는 https로 요청을 하는 상황인 것이다.
Https로 통신하다 http로 연결되는 통신이 발생하면 보안정책에 의해 Chrome 브라우저에서 block된다.
이를 해결하기 위해 서버를 SSL구성해 Https로 변경하여 해결하기로 했다.
다음과 같은 환경에서 진행하였다.
1. AWS EC2 Ubuntu 구축
2. nginx 설치
3. Spring boot 프로젝트는 8080 포트로 배포
4. 가비아에서 도메인 구입
2. letsencrypt 인증 적용하기
Https는 인증서가 필요하다.
Let's Encrpt는 사용자에게 무료로 SSL를 발급해주는 비영리기관이다.
일정 시간 후에 재갱신 해줘야한다.
2-1 cerbot 설치하기
$ sudo apt update
$ sudo apt upgrade
$ sudo apt-add-repository -r ppa:certbot/certbot
2-2 certbot의 nginx 설치하기
$ sudo apt install python3-certbot-nginx
2-3 SSL 인증서 받기
$ sudo certbot --nginx -d [도메인 이름] -d www.[도메인 이름]
2-4 Nginx 설정파일
인증서를 발급 받고 나면 certbot이 알아서 설정 파일을 작성해준다.
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
server {
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name www.gonggu-market.shop gonggu-market.shop; # managed by Certbot
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/gonggu-market.shop/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/gonggu-market.shop/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 = www.gonggu-market.shop) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = gonggu-market.shop) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name www.gonggu-market.shop gonggu-market.shop;
return 404; # managed by Certbot
}
도메인 입력 시 http, https 둘다 접속이 잘되는것을 확인할 수 있다.
3. 80 포트 8080 포트로 포워딩
기본적으로 80포트로 설정되어 있어 도메인으로 접속을 하면 nginx index.html 파일이 보여지고 있다.
Spring boot 프로젝트로 진입하기 위해선 아직도 'IPv4주소:8080' 으로 접속해야한다.
도메인으로 접속 시 바로 프로젝트로 연결되도록 설정해주기 위해 nginx 설정 파일을 다음과 같이 수정한다.
server {
...
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
proxy_pass http://IPv4주소:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
...
}