단일 IP주소에서 수신을 대기하는 두 개 이상의 https 서버를 구성할 때는 몇가지 문제가 발생할 수 있다.
nginx 공식 문서
우리는 이전글에서 서술한 것처럼 백엔드와 프론트엔드 서버를 하나의 인스턴스 내에 합치는 중이다.
이전에 각 인스턴스에 하나의 서버를 사용할 때는 몰랐던 문제가 발생했다.
단일 IP 주소에서 수신 대기하는 두 개 이상의 HTTPS 서버를 구성했다면 아래와 같은 문제가 발생할 수 있다.
브라우저는 기본 서버의 인증서를 받는다.

HTTPS 통신에서는 TLS 핸드셰이크 시점에서 아직 서버가 HTTP 헤더를 읽을 수 없기 때문에 서버가 HTTP host 헤더를 읽어 어떤 인증서를 보낼지 선택하는 작업이 불가능하다.
그러다보니, 기본 서버의 인증서를 제공한다.
내 인스턴스의 경우에는, /etc/nginx/conf.d 폴더 내에 두 개의 파일이 있다.

frontend.conf는 프론트엔드 서버용, myapp.conf는 백엔드 서버용이다.
Nginx는 nginx.conf 파일과 그 안에 포함된 다른 설정 파일들을 순서대로 로드하고 처리한다.
이 과정에서 동일한 listen 지시어(예: listen 443 ssl;)를 사용하는 여러 server 블록이 있다면, Nginx는 첫 번째로 만나는 server 블록을 기본 서버로 간주할 수 있다.
나의 경우에는 이전 게시글에서 frontend server를 분리하면서 dev.co-kkiri.com이 frontend.conf의 첫번째 서버가 되었다.
그리고 frontend.conf의 f는 myapp.conf의 m보다 앞이기 때문에 nginx가 dev.co-kkiri.com 서버를 기본 서버로 간주하고, 그 곳에 설정된 인증서를 사용한 것이다.
nginx 공식 문서에서는 몇가지의 해결 방법을 제시하고 있었다.
HTTPS 서버에 모두 다른 IP를 부여하는 방법이다.
EC2에서는 AWS에서 제공하는 Elastic IP를 사용해서 새 IP를 할당받은 후 인스턴스의 프라이빗 주소 중 하나에 연결해서 사용할 수 있다.
다만 인스턴스에 따라 연결할 수 있는 EIP에 제한이 있다.
EC2 당 붙일 수 있는 EIP 개수
EIP는 인스턴스를 중지해놓거나 하면 비용이 나가기 때문에, 혹시 모르는 상황을 방지하고자 이 방법은 사용하지 않기로 했다.
하나의 SSL 인증서에서 여러 다른 도메인 이름을 커버할 수 있도록 발급받는 방법이다.
이 방법은 애초에 도메인을 발급받을 때 Subject Alternative Name 필드에 여러 도메인을 추가했어야 한다.
certbot nginx -d 1번도메인 -d 2번도메인 -d 3번도메인 ...
하지만 우선 이렇게 발급받지 않았고, 인증서 하나에 모든 호스트명을 다 구겨넣으려면 사전에 호스트명을 모두 알고 있어야 하는데 이는 사실상 대형 프로젝트에서는 불가능한 방법이라 생각해서 사용하지 않았다. (물론 나는 소소소소소소규모 프로젝트다)
하위 도메인까지 커버하도록 인증서를 발급받는 방법이다.
위의 방법과는 조금 다른게, 이 방법은 특정 도메인 하위의 모든 도메인을 허용한다.
certbot certonly --manual -d *.도메인 --preferred-challenges dns
이 방법은 우선 귀찮다. 나는 Route53에서 구매했으므로 Route53에서 호스팅 영역에서 설정을 해야하는데, 소유권 인증을 하고 나서도 전파에 시간이 걸리다보니 사용하지 않기로 했다.
최신 브라우저에서는 제일 일반적인 해결법이다.
TLS 서버 이름 표시 확장이라는 개념인데, SSl 핸드셰이크 시점에 서버 이름을 전달해서 서버를 식별할 수 있는 기능이다.
이를 이용하면 같은 IP 주소와 TCP 포트 번호를 가진 서버로 여러 개의 인증서를 사용할 수 있게 되고, 따라서 모든 사이트가 같은 인증서를 사용하지 않아도 동일한 아이피로 여러 HTTPS 웹사이트(또는 TLS 상에서 돌아가는 다른 서비스)를 운영할 수 있게 된다고 한다.
사용법도 간단하다.
conf의 서버 블록 내에서 server_name에 연결하려는 도메인 이름을 추가해주면 된다.
server_name 호스팅도메인명;
api.co-kkiri.com을 conf 파일의 server 블록 내에서 server_name 에 추가해주었다.server{
...
server_name api.co-kkiri.com;
...
}
sudo systemctl restart nginx

이제 정상적으로 인식하는 것을 볼 수 있다.
Nginx뿐만이 아니라, 서버를 운영한다는 것에 대한 개념 자체를 잘 모르고 필요에 의해 사용하다보니 문제가 많았다.
앞으로도 많은 삽질을 하게 되겠지만, 하나의 인스턴스 내에서 여러 도메인을 서버에 잘! 연결하는 방법은 잊지 않을 것이다.