도메인 구매, DNS 적용, SSL 인증, 신규 도메인 추가(가비아, Oracle Cloud)

예진욱·2024년 10월 25일

Oracle Cloud

목록 보기
2/2

서버를 운영하는 과정에서 IP 주소의 직접적인 노출을 방지하고 보안을 강화하기 위해 도메인을 연결하고 HTTPS를 통해 SSL 인증을 설정하는 것은 필수라고 볼 수 있다.

이 포스팅에서는 각 개념을 설명하고 이러한 과정, 즉 클라우드 기반의 VM 서버를 도메인과 HTTPS로 연결하는 절차를 설명한다.



📜 도메인, DNS, 네임서버


도메인

도메인은 웹 사이트를 식별하기 위해 사용되는 주소로, 사람이 기억하고 입력하기 쉬운 형태로 만들어진다.
예를 들어 example.com과 같은 도메인은 특정 서버를 가리키며,
사용자가 브라우저에 도메인을 입력하면 해당 서버로 접속하게 된다.
이는 IP 주소와 같은 숫자들의 조합을 대신하는 역할을 한다.

도메인은 여러 구성 요소로 이루어져 있다. 주요 구성 요소는 다음과 같다:

  • 최상위 도메인(TLD, Top-Level Domain): .com, .net, .org와 같은 도메인의 마지막 부분이다. 이는 도메인의 목적이나 특성을 나타낸다.
  • 2차 도메인: example.com에서 example 부분이 2차 도메인이다. 사용자가 등록하는 부분이며, 브랜드나 사이트의 정체성을 표현한다.
  • 서브도메인(Subdomain): 2차 도메인 앞에 추가되는 요소로, www.example.com에서 www가 서브도메인이다. 주로 특정 서비스를 분리하여 운영할 때 사용된다.

DNS(Domain Name System)

DNS는 도메인 이름을 해당 서버의 IP 주소로 변환해 주는 시스템이다.
예를 들어 사용자가 example.com을 입력하면,
DNS는 이 도메인에 해당하는 서버의 IP 주소를 찾아 연결을 돕는다.
DNS는 여러 유형의 레코드를 통해 도메인과 관련된 정보를 관리한다:

  • A 레코드: 도메인 이름을 특정 IP 주소에 매핑하는 레코드이다.
  • CNAME 레코드: 도메인 이름을 다른 도메인 이름에 매핑하는 데 사용한다. 주로 서브도메인에 대한 리다이렉션을 위해 사용된다.
  • MX 레코드: 도메인에 대한 메일 서버 정보를 지정하는 레코드이다. 이메일 서비스와 관련된 설정에 필요하다.
  • TXT 레코드: 도메인에 대한 텍스트 정보를 저장하며, 도메인 소유 인증이나 보안 관련 정보를 포함할 수 있다.

네임서버(Nameserver)

네임서버는 DNS의 일부로, 도메인 이름을 IP 주소로 매핑하는 역할을 수행한다.
도메인을 구매한 후에는 해당 도메인의 네임서버 설정을 변경해야 한다.
일반적으로 도메인 등록 서비스 제공업체에서 기본 네임서버를 제공하지만,
AWS Route 53이나 Cloudflare와 같은 서비스로 네임서버를 관리할 수도 있다.
네임서버 설정을 통해 DNS 요청을 올바른 서버로 라우팅하고, 트래픽을 효과적으로 관리할 수 있다.



📜 HTTPS, SSL 인증서


HTTPS 가볍게 알아보기

HTTPS(HyperText Transfer Protocol Secure)는 HTTP의 보안 버전으로, 데이터를 암호화하여 서버와 클라이언트 간의 통신을 보호한다.
이를 통해 데이터가 제3자에 의해 도청되거나 변조되는 것을 방지할 수 있다.
특히, 금융 거래나 로그인 정보와 같은 민감한 데이터를 다루는 웹사이트에서는 HTTPS가 필수적이다.
HTTPS는 기본적으로 443 포트를 사용한다. 443 포트는 웹 트래픽을 암호화하여 안전하게 전달하기 위한 표준 포트로, SSL/TLS 통신이 이 포트를 통해 이루어진다.
반면 HTTP는 80번 포트를 사용한다. 443 포트를 열어두어야 클라이언트가 HTTPS로 서버에 안전하게 접속할 수 있다.

HTTPS 이해하기

HTTPS 는 상호 간 통신에 대칭/비대칭 키 알고리즘을 모두 사용한다.
대칭키는 가볍지만 암/복호화에 필요한 key 를 양측이 모두 가지고 있어 탈취 시 위험 리스크가 있다.

  • 클라이언트가 A 라는 키로 내용을 암호화해 보냈을 때, 대칭키가 탈취당한다면 내용을 복호화할 수 있는 위험이 존재한다.

비대칭키는 무겁지만 공개키와 비밀키가 서로 쌍을 이루어 복호화할 수 있으므로 리스크가 적다.
공개키 : 클라이언트에게 제공되는 암/복호화 key 값
비밀키 : 서버만이 가지고 있는 암/복호화 key 값
공개키로 암호화 된 것은 비밀키로만 복호화 가능하고, 비밀키로 암호화 된 것은 공개키로만 복호화 가능하다.
공개키는 탈취 가능성이 높은 반면, 비밀키는 서버만이 알고 관리하므로 탈취 가능성이 적다.

  • 클라이언트가 A 라는 키로 내용을 암호화해 보냈을 때, 그것을 복호화할 수 있는 건 서버의 B라는 비밀키 뿐이다. 이로 인해 탈취 당함에도 리스크가 적다.
  • 또한 서버가 B 라는 키로 내용을 암호화해 보냈을 때, 클라이언트는 본인이 가지고 있는 공개키로 복호화가 가능하다면 서버2, 서버3 이 아니며, 변조가 되지 않아 내가 원하는 서버와 통신하고 있다는 것을 인증할 수 있는 것이다.

다만 모든 통신 내용을 비대칭키로 관리한다면, 그 과정이 무거워 대칭/비대칭 키 알고리즘을 섞어 사용한다는 것이다.
일반적으로 대칭키로 내용을 공유하고, 대칭키를 주고받을 때 비대칭키를 사용한다.

HTTPS 깊게 알아보기

SSL/TLS 핸드셰이크로 시작하며, 핸드셰이크 과정에서 필요한 인증과 키 교환이 이뤄진다.
아래에 HTTPS의 핸드셰이크 과정과 대칭키/비대칭키 사용 순서에 대해 순서대로 자세히 설명해본다.

  1. Client Hello

    • 클라이언트가 서버에 연결을 시도하면서 클라이언트 헬로 메시지를 보낸다.
    • 이 메시지에는 클라이언트가 지원하는 TLS 버전, 사용할 수 있는 암호화 알고리즘 목록, 무작위 숫자 (Client Random) 등이 포함되어 있다.
  2. Server Hello

    • 서버는 클라이언트 헬로 메시지를 받고, 다음과 같은 정보로 응답한다
      - 사용할 TLS 버전과 암호화 알고리즘을 선택.
      - 서버가 생성한 무작위 숫자 (Server Random)
    • 서버의 디지털 인증서를 클라이언트에게 보낸다. 이 인증서에는 서버의 공개키가 포함되어 있다.
  3. 서버 인증서 검증

    • 클라이언트는 서버가 보낸 디지털 인증서를 통해 서버의 신뢰성을 확인한다.
    • 인증서는 공인된 인증 기관(CA)에 의해 서명된 것이며, 클라이언트는 이를 통해 서버가 신뢰할 수 있는 서버임을 확인한다.
  4. Pre-Master Secret 생성

    • 클라이언트는 새로운 난수인 Pre-Master Secret을 생성한다.
    • 이 Pre-Master Secret은 서버의 공개키로 암호화되어 서버로 전송된다. 이 단계에서 비대칭키 암호화가 사용된다.
    • 비대칭키 암호화를 사용하는 이유는 클라이언트가 생성한 Pre-Master Secret을 안전하게 서버로 전달하기 위함이다. 서버는 자신의 비밀키로 이를 복호화하여 Pre-Master Secret을 얻는다.
  5. 세션 키 생성

    • 서버와 클라이언트는 각각 Client Random, Server Random, Pre-Master Secret을 이용해 세션 키를 생성한다.
    • 이 세션 키는 대칭 키이며, 이후의 통신에서 사용된다.
    • 대칭키는 암호화와 복호화에 동일한 키를 사용하는 방식으로, 대칭키 암호화는 비대칭 암호화에 비해 훨씬 더 빠르다. 따라서 실제 데이터를 주고받을 때는 이 대칭키가 사용된다.
  6. 핸드셰이크 완료

    • 이제 클라이언트와 서버는 세션 키를 공유하게 되었고, 대칭키 암호화를 사용해 안전하게 데이터를 주고받을 수 있게 된다.
    • 클라이언트와 서버는 "Finished" 메시지를 교환하여 핸드셰이크가 완료되었음을 알린다. 이 메시지 또한 새롭게 생성된 세션 키로 암호화되어 전송된다.

요약하자면 아래와 같다.
초기 핸드셰이크 (비대칭키 암호화) :

  • 클라이언트는 서버의 공개키를 받아서 Pre-Master Secret을 암호화해 서버로 전송한다.
  • 이때 비대칭키 암호화를 사용하는 이유는 키 교환을 안전하게 하기 위함이다.

세션 키 생성 후 데이터 전송 (대칭키 암호화):

  • 클라이언트와 서버가 Pre-Master Secret을 기반으로 세션 키(대칭키) 를 생성한다.
  • 이후의 모든 데이터 통신은 이 세션 키를 사용하여 대칭키 방식으로 암호화된다.
  • 대칭키 암호화는 비대칭키에 비해 속도가 빠르기 때문에, 실시간 데이터 전송에 적합하다.

SSL 인증서와 TLS

SSL(Secure Sockets Layer)은 HTTPS를 구현하기 위해 사용되는 프로토콜로,
현재는 SSL의 후속 버전인 TLS(Transport Layer Security)가 널리 사용되고 있다.
SSL 인증서는 클라이언트와 서버 간의 안전한 통신을 보장하는 역할을 하며, 클라이언트가 서버의 신원을 확인하고 신뢰할 수 있게 한다.


# 서브도메인과 와일드카드 도메인

서브도메인은 메인 도메인의 앞에 추가되어 메인 도메인의 특정 하위 영역을 식별하는 역할을 한다.
예를 들어 blog.example.com, shop.example.com 등으로 서로 다른 서비스를 제공할 수 있다.

와일드카드 도메인은 *.example.com과 같이 정의되며, 모든 서브도메인을 허용하는 방식이다.
이를 통해 특정 도메인 하위에서 무제한의 서브도메인을 생성할 수 있다.
예를 들어, 와일드카드 도메인을 사용하면 app1.example.com, app2.example.com, anything.example.com 등의 주소를 자유롭게 사용할 수 있다.

SSL/TLS 인증서 플랫폼을 들여다보면 와일드카드 도메인 서비스를 많이 제공하는 것을 볼 수 있다.
와일드카드 도메인은 유연한 도메인 관리를 가능하게 하며,
특정 서비스가 다양한 하위 도메인에서 동일한 SSL 인증서를 사용할 수 있도록 해준다.


SSL/TLS 공인/사설인증서

사설인증서

공인된 인증 기관(CA)에서 발급받은 인증서가 아닌, 조직 또는 개인이 자체적으로 생성하여 사용하는 인증서.
일반적으로 내부 네트워크, 테스트 환경 또는 외부 사용자를 필요로 하지 않는 비공개 서비스에서 사용된다.

  • 발급 주체 : 조직 내에서 신뢰할 수 있는 서버나 개인 컴퓨터에서 생성하며, 자체적으로 인증서 발급을 관리
  • 신뢰도: 사설 인증서는 공인 인증 기관에서 발급받지 않으므로, 외부에서 신뢰되지 않는다. 예를 들어, 브라우저나 시스템에서는 기본적으로 경고 메시지가 표시된다.
  • 사용 용도: 내부 시스템에서 암호화된 통신을 유지하거나 테스트 서버의 HTTPS 통신을 설정하는 데 주로 사용된다.
  • 설치: 사설 인증서를 사용하는 각 클라이언트는 인증서를 수동으로 신뢰하도록 설정해야 한다.
  • 사용 예시 : 회사 내부 네트워크 보안 / 개발 및 테스트 환경 / VPN 및 원격 서버
  • 장점 : 자체 생성이라 무료 / 조직 내부에서 관리할 수 있어 편리함
  • 단점 : 공인되지 않아 브라우저에서 경고 표시 / 외부 네트워크에는 부적합
  • 대표적인 도구로 openssl 이 있음.

회사가 무료 공인 인증서(예: Let’s Encrypt) 대신 유료 공인 인증서를 사용하는 데는 몇 가지 중요한 이유가 있다.
주요 이유는 보안 수준, 신뢰성, 추가 기능 지원과 관련이 있다.

공인인증서

공인된 인증 기관(CA)에서 발급받은 인증서들을 말한다.
회사가 무료 공인 인증서(예: Let’s Encrypt) 대신 유료 공인 인증서를 사용하는 데는 몇 가지 중요한 이유가 있다. 주요 이유는 보안 수준, 신뢰성, 추가 기능 지원과 관련이 있다.

  • 일부 산업 규제나 법적 요건(예: PCI DSS, HIPAA)은 검증 수준이 높은 인증서를 요구하는 경우가 많다. 무료 공인인증서는 이들을 만족하지 못한다.
  • Extended Validation (EV)와 Organization Validation (OV) 같은 인증서는 유료 인증 기관에서만 발급 가능하며, 무료 인증서에서는 DV 만을 제공한다.



✏️ 1. 도메인 구매 및 DNS 설정

먼저, 도메인을 구매해야 한다.
도메인 등록은 GoDaddy, Namecheap, AWS Route 53 등 다양한 도메인 등록 서비스 제공업체를 통해 용이하게 이루어질 수 있다.

이 포스팅에서는 가비아(Gabia) 라는 도메인 제공 업체를 통해 진행한다.
국내 IT 인프라 및 웹 서비스업계에서 굴지의 기업으로, 한국어 지원과 통합적인 도메인·호스팅·보안 서비스를 제공하여 관리가 쉽고 편하다.


🔗 1-1. 도메인 구매

https://www.gabia.com/ 에 진입해 원하는 SLD (Second Level Domain) 도메인을 입력해보자.

그러면 아래와 같이 사용 가능한 최상위 도메인 목록을 나열해준다.
한국 뿐 아니라 해외 국가 코드 도메인도 사용 가능하다.

2024년 10월 기준 .com 이라는 최상위 도메인을 1년간 부가세 포함 20,900 원에 이용 가능했다.

다음 과정을 거치기 위해선 네임서버를 등록해야 한다.



🔗 1-2. DNS 레코드 및 Nameserver 설정


내 서버는 개인용으로 쓸만한 프리티어를 제공해주는 Oracle Cloud(OCI, Oracle Cloud Infrastructure)에 올라가 있어, Oracle Cloud 기준으로 설명한다.
다만 프리티어는 리전 할당 받기가 매우 힘들어 몇 개월 이상 소요되고 문의를 넣어 겨우 받았으니 급한 사람들은 다른 클라우드 플랫폼을 이용하자.

좌측 상단 메뉴의 Networking > DNS management > Zones 에 진입한다.
그러면 아래와 같은 화면이 뜨는데, 우선 zone 을 생성해보자.

Zone name 에는 내가 등록하고자 하는 도메인 명을 입력한다.

그러면 아래와 같이 Nameserver 가 생성된 것을 볼 수 있다.

이후 Records 탭에 들어가 recode 를 등록해야 한다.

Type 과 TTL 을 지정한 후 Address 는 매핑할 서버의 IP 를 입력한다.

이후 하단의 Publish changes, Confirm publish changes 를 적용해 recode 등록을 확정하자.

그러면 다시 가비아로 돌아와 네임서버를 입력한다.
IP 주소는 네임서버의 IP 를 입력한다. (nslookup 으로 확인 가능)

아래 결제를 마친 모습.

이제 도메인 등록이 될 때 까지 여유있게 하루를 기다렸다가 SSL 설정을 마무리해보자.




✏️ 2. SSL/TLS 인증

여유있게 24시간이 지나 도메인 연결이 완료되면 이제 HTTPS를 설정해야 한다.
HTTPS는 SSL/TLS 인증서를 사용하여 웹 트래픽을 암호화함으로써 사용자와 서버 간의 통신을 보호한다.

SSL/TLS 인증서는 Let's Encrypt와 같은 무료 발급 기관에서 발급받을 수 있으며, 유료 인증서를 구매하는 것도 가능하다.
물론 가비아에서도 높은 신뢰도를 보장하는 SSL/TLS 인증서를 제공한다.
이번 포스팅에서는 내 개인서버를 구축하는 데 주력해, Let's Encrpyt 라는 무료 TLS 공인 인증서를 적용한다.

우선 nslookup 으로 record 등록이 잘 됐는지 확인하자.
Address 에 내가 지정한 IP 가 잘 등록된 것이 확인된다.

이제는 도메인으로 직접 웹으로 접속해보자.
Oracle Cloud 프리티어 A1 인스턴스 생성 + 고정 public IP 생성
의 가장 아래에 방화벽 open, Nginx 설치 및 IP 로 접속하는 방법을 설명해 두었으니 참고하길 바란다.

도메인 연결이 잘 된것을 확인할 수 있다.
이제 Nginx 로 HTTPS 를 설정하고, SSL 인증을 적용해보도록 하자.



🔗 2-1. Let's Encrypt 설치, Nginx 반영

도메인명은 mud-cookie.com 과 같이 본인이 구매한 도메인과
도메인명나열은 mud-cookie.com www.mud-cookie.com 와 같이 TLS 인증을 적용할 서브도메인을 포함한 도메인 리스트를 작성한다.

# Let's Encrypt 를 적용하기 위한 certbot 설치
sudo apt update
sudo apt install certbot python3-certbot-nginx -y

# certbot 에 도에민 반영 및 nginx 재시작
sudo certbot --nginx -d 도메인명나열

# nginx 설정 파일 업데이트
sudo vi /etc/nginx/sites-available/도메인명.conf
# /etc/nginx/sites-available/도메인명.conf
server {
    # HTTP 요청을 HTTPS로 리디렉션
    listen 80;
    server_name 도메인명;
    return 301 https://$host$request_uri;
}

server {
    # HTTPS 설정
    listen 443 ssl;
    server_name 도메인명나열;

    # SSL 인증서 파일 경로
    ssl_certificate /etc/letsencrypt/live/mud-cookie.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mud-cookie.com/privkey.pem;

    # SSL 설정 추가
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 루트 디렉토리와 인덱스 파일 설정
    root /var/www/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
    
    # 8000 포트로 프록시 설정 예시 (Optional)
#    location / {
#        proxy_pass http://localhost:8000;
#        proxy_set_header Host $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;
#    }
}
# 심볼릭 링크로 설정 파일을 활성화
sudo ln -s /etc/nginx/sites-available/도메인명.conf /etc/nginx/sites-enabled/

# nginx 설정 테스트
sudo nginx -t

# nginx 재시작
sudo systemctl restart nginx\

이제 https 접속을 테스트해보자.
웹으로도 가능하다.

curl -I http://도메인명

🔗 2-2. 인증서 자동 갱신


Let's Encrypt 의 인증서는 90일 주기로 만료되므로, 일정 주기마다 갱신이 필요하다.
갱신을 일일이 챙기기 힘드므로, 자동으로 갱신되도록 해보자.
crontab 을 활용해 매일 새벽 3시에 갱신되고, nginx 를 reload 하자.
restart 는 재기동이고, reload 는 설정을 다시 반영한다는 것이니 참고하자.

# crontab 설정 진입
crontab -e

# 아래 명령어를 적용한다.
0 3 * * * /usr/bin/certbot renew --quiet && /bin/systemctl reload nginx

# crontab 적용 확인
crontab -l



✏️ 3. 서브 도메인을 추가해 포트를 매핑하려면?


서비스가 확장되어 서버내 application을 8080 포트로 띄웠다고 가정해보자.
이 서비스는 test.mud-cookie.com 과 같은 host 를 요청했을 때 위 인스턴스로 매핑시키는 작업을 해보자.

🔗 3.1 신규 도메인 DNS 레코드 등록


1-2. DNS 레코드 및 Nameserver 설정을 참고해 record 를 등록하자.


🔗 3.2 신규 도메인 인증서 발급, Nginx 프록시 적용


# test.mud-cookie.com 인증서 등록
sudo certbot --nginx -d test.mud-cookie.com

# test.mud-cookie.com 도메인 Nginx 설정 진입
sudo vi /etc/nginx/sites-available/test.mud-cookie.com.conf
# /etc/nginx/sites-available/test.mud-cookie.com.conf

server {
    # HTTP 요청을 HTTPS로 리디렉션
    listen 80;
    server_name test.mud-cookie.com;
    return 301 https://$host$request_uri;
}

server {
    # HTTPS 설정
    listen 443 ssl;
    server_name test.mud-cookie.com;

    # SSL 인증서 파일 경로
    ssl_certificate /etc/letsencrypt/live/mud-cookie.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mud-cookie.com/privkey.pem;

    # SSL 설정 추가
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 프록시 설정
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $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;
    }
}
# /etc/nginx/sites-available/test.mud-cookie.com.conf 파일 심볼릭으로 활성화
sudo ln -s /etc/nginx/sites-available/test.mud-cookie.com.conf /etc/nginx/sites-enabled/

# nginx 설정 확인
sudo nginx -t
# nginx 재기동
sudo systemctl restart nginx

서버는 이미 springboot application 을 8080 포트에 띄운 상태이다.
아래처럼 접속해보자.
실제로는 https:// 로 redirect 된 상태이고, 404 페이지는 url 매핑을 하지 않았을 뿐 host 에 정상적으로 라우팅 되었음을 알 수 있다.

profile
Spring 백엔드 개발자

0개의 댓글