본문 바로가기
개발 💻/메모

가비아 & letsencrypt & Nginx 로 개인서버에 도메인 붙여보기

by 감사로봇 2025. 1. 7.

개요

최근에 구하게 된 PC를 개인서버로 만들어서 이것저것 개발하다보니, 도메인을 붙이고 싶다는 생각이 들었다.

원래 AWS를 이용해서는, Route 53에서 도메인을 구매하고, SSL을 먹이기 위해서 ACM 인증서를 설정해서, 운용하는 EC2에 붙인 ALB에 싹 설정하는 방법만 알고 있었다.

그런데 이번 기회에 직접 붙여보는 것이 해보고 싶어 직접 시도해 보았다.

  1. 가비아에서 도메인을 구매하고
  2. letsencrypt 로 SSL 인증서를 다운로드하고
  3. Nginx 로 서버에 SSL 인증서를 적용 및 프록시까지 설정한

내역에 대해서 설명하고자 한다.

letsencrypt 와 Nginx 는 Ubuntu 서버 내에서 진행하였다.

 

1. 가비아에서 도메인 구매

여기저기서 저렴한 도메인, SSL 가격을 알아보았지만, 얼추 계산했을 때 최소 연에 5만원 가까이 깨질 것 같았다.
내 용돈으로 그렇게 비싼 것을 지불할 수 없었기 때문에, 저렴한 방법들을 모색해야 했다.

우리나라에는 대표적으로 가비아랑 카페24가 있고 해외에서 제공하는 사이트들이 몇개 있었는데, 나는 애국자니까 국내의 것을 이용하기로 생각했다. 게다가 가비아에서 .xyz 도메인을 이벤트로 1년 2,500원에 해준다길래 냉큼 구매했다.

하지만 부가세가 별도여서 결제는 2,750원이었다.

그래서 .xyz 도메인을 구매했다. 그러면 가비아에서 할 일이 끝났는가? 아니다.
레코드 설정을 해줘서 소위 이야기하는 도메인 네임을 지정/연결해 주어야 한다.

레코드 설정은 해당 도메인에서 들어오는 통신 호스트 등을 기반으로 어디로 보내주면 될지 결정하는 정보이다. 방식으로 A 레코드, CNAME, MX, TXT 등등이 있는데 메일서버나 뭐 이런거 이용하지 않는 이상 거의 A 아님 CNAME 설정이다. A 레코드는 진짜 IP 를 이용해서 전달 위치를 지정하는거고, CNAME 은 별칭 등을 이용한다고 가볍게 생각하면 된다.

나는 개인서버에 할당된 공인 IP 에 해당 도메인을 연결할 것이므로, A 레코드를 설정하는게 맞다.
가비아를 기준으로 다음과 같이 레코드를 설정했다. 다른 사이트도 크게 다르진 않다. 맥락이 그렇다.

 

"My가비아" 메뉴로 들어가서 저기 "이용중인 서비스"의 "도메인"을 눌러 들어간 다음

 

뜨는 화면에서 "DNS 관리툴"로 들어간다.

 

그럼 우리가 구매한 도메인이 노출되고, 그에 대한 설정들을 할 수 있는 메뉴가 보이는데, 가차없이 "DNS 설정"을 클릭한다.

 

초기에는 아무런 목록이 없을텐데, 이런 목록이 나오면서 여기에 "레코드 추가" 버튼을 누르면 레코드를 추가할 수 있다.

위 사진에서 보이다시피 나는 이미 2개를 등록했기 때문에 저렇게 목록이 나오며, 이는 2개의 서브도메인별 도메인 주소가 각각 원하는 IP 위치로 전달된다는 뜻이다.

서브 도메인? 도메인 앞에 붙는 구분자라고 생각하면 된다.
도메인은 뒤에서부터 앞으로 상위 > 하위 개념으로 가진다.

예를 들어, 도메인은 abc.com 이라고 하는 형태를 띄는데,
"abc" 는 내가 갖고 싶은 이름인거고, ".com" 은 세계적으로 두루두루 쓰는 약속된 이름인거다.

우리는 도메인을 구매한다! 라고 하면 이 2개를 결정해서 기본 도메인 명을 얻게 되는거고,
거기에 한칸 더 앞에 api, www, dev 등등을 붙여 서브도메인으로 디테일한 주소를 만들어내는거다.

직접적인 예시로,
나는 위에서 "(심도있는 고민이 필요한 도메인 이름).xyz" 이렇게 2,750원의 가치를 지불했을 때,
"api.(도메인 이름).xyz" 또는 "www.(도메인 이름).xyz" 등으로 설정할 수 있는 것이다.

 

그럼 저 목록을 보면, 호스트는 서브도메인을 지정하는거고, 값/위치는 실제 전달될 위치를 지정하는 것이다.

가비아는 "@" 값을 비우는 것으로 지정하기로 했나보다. 예시로, 내 개인서버 IP 를 123.123.123.123 이라고 가정하자.

A @.abc.com 123.123.123.123
A api.abc.com 123.123.123.123

이렇게 하면?
누가 abc.com 입력하면 123.123.123.123 으로, 누가 api.abc.com 으로 입력하면 123.123.123.123 으로 보내란 뜻이 된다.

근데 이러면 도메인은 서브도메인으로 분기를 해두고 왜 IP 를 동일한 곳에 보내냐고 생각할 수 있다. 이건 이제 HTTPS/443 이나 HTTP/80 같은 (별도 포트를 붙이지 않아도 돼서 아름다운) 위치로 보낸 다음에, 접근서버 내부에서 Nginx 등의 프록시 서버를 운용하여 분기를 쳐주기 때문에 이렇게 설정한다.

이제 여기까지 설정했으면, 더 이상 가비아는 안녕이다. 다만, 내년부터는 .xyz 가 원가로 돌아가니까 그때는 돌아가야만 한다.

 

2. letsencrypt 로 SSL 인증서 다운로드

도메인이 있으면, 기본적으로는 HTTP 프로토콜을 제공한다.
그러면 무슨 일이 벌어지냐, 멋이 없어진다. 보안체계가 없기 때문이다.

우리는 HTTPS 라고 하는 안전한 보안체계를 가진 프로토콜을 쓸 수 있는 멋진 방식이 있으므로 이를 추구해야 한다.

SSL 제공하는 많은 업체들이 있는데 이것들을 구매하고 다운로드 받아 설정하면 HTTPS/443 접근을 이용할 수 있게 되고, 온전하고 드러낼 수 있는 도메인 주소를 얻게 되는 것이다. 그게 멋지다.

하지만 내 멋짐은 만 원을 넘지 않기 때문에, 얼추 4만원이나 하는 SSL 을 구매할 수 없다.
고로 무료 SSL 을 이용하기로 했다.

 

letsencrypt 는 아주 유명한 무료 SSL 이다. 다만, 번거롭게도 3개월마다 갱신하라고 한다. 그래도 무료는 기쁘다.

letsencrypt 를 이용하여 SSL 인증서를 발급하는 방법에는 여러 가지가 있다. SSL 인증서는 기본적으로 설정 후 검증까지 수행해야 한다. 이건 뭐냐, SSL 제공업체의 입장에서 특정 도메인에 설정한 SSL 인증서가 있다고 할 때, 너가 정말 도메인(사이트)의 주인이 맞냐는 것을 확인하는 것이다.

여러 방법이 있지만, 나는 아주 아무것도 없는 상태에서 하는 것이므로 standalone 방식으로 진행했다.

 

letsencrypt 에서 제공하는 SSL 을 다운로드하기 위해서는 certbot 이라는 도구를 이용한다.

sudo apt update
sudo apt-get install letsencrypt

Ubuntu 답게 APT 업데이트로 시작해주고, 필요한 letsencrypt 를 설치한다.
당연히 중간에 나오는 질문들에는 YES 로 화답하자.

 

standalone 방식은 특이하게도 SSL 인증서 다운로드 및 검증 시에 직접 80 포트에 웹서버를 띄워 인증서를 발급/검증해준다.
그러면 80 포트에 뭔가 떠있으면 안 되므로, 미리 꺼주도록 한다.

 

이제 certbot 명령어를 통해 SSL 인증서를 다운로드한다.

sudo certbot certonly --standalone -d 당신의.도메인 -d 또다른.당신의.도메인

예시로, 내가 구매하고 설정한 도메인(레코드 설정까지 고려해서)들을 -d 옵션으로 나열해주면 된다.

명령어를 입력했을 때, 나는 아래와 같은 오류가 났다.
이미지에서 가린 것들은 모두 나의 구매한 도메인 명들이다.

가비아에서 이미 도메인을 구매했고 레코드 설정까지 했는데 뭔가 오류가 나면서 SSL 인증서가 안 받아졌다. 80 포트에 뭐가 떠있나 싶어서 확인했는데도 없었다.

보니까 가비아에서 도메인은 구매했는데, 글로벌 DNS에 등록이 안 돼서, 구매 안 된거 아냐? 같은 에러였다.

 

도메인이 등록됐나~ 하고 검사해보고 싶으면 nslookup 명령어를 이용해볼 수 있다.

nslookup naver.com # 예시

등록된 도메인이면 이렇게 IP 주소가 노출된다. 가지고 있는 도메인이 잘 나오는지 확인해보자.

 

결론적으로, 기다렸다가 하니까 잘 됐다.
친절한 가비아는 설정완료되면 문자도 보내주니까, 문자 받고 수행하는게 마음 편할 수도 있다.

 

다운로드가 완료되면 친절하게 인증서 파일과 키 파일의 위치를 출력해준다. 이를 기억해두도록 하자. 메모할 자신이 없다면.

신난다. 무료 SSL 인증서가 생겼다. 이제 등록만 하면 멋진 HTTPS 프로토콜을 사용할 수 있다.

 

3. Nginx 운용

나의 기준 Ubuntu 가 22.04 버전이므로, 이를 기준으로 설치하였다.

sudo apt update
sudo apt install nginx

Ubuntu 국룰 APT 업데이트로 시작하고, nginx 를 설치한다.

 

Ubuntu 는 UFW 방화벽 정책을 기본적으로 이용하는데, 만약 자신의 방화벽이 Enabled 되어 있다면, Nginx 를 등록해줘야 할 것 같지만, Nginx 는 스스로 자신이 주로 운용하는 443, 80 포트를 서비스로서 등록해준다. 친절하다.

sudo ufw status

 

위 명령어로 UFW 방화벽을 체크해보고,

sudo ufw app list

위 명령어로 UFW 방화벽의 서비스(앱) 목록에 Nginx 가 존재하는지 확인한다. 뭐가 신나게 나오는데, 443, 80 포트를 방화벽에 등록했습니다~하는거다.

 

이제 Nginx 가 잘 실행되었는지 확인해보자.

sudo systemctl status nginx

 

로그 같은게 잔뜩 나오면서 Nginx 서비스의 상태를 나타내는데, 중간에 떡하니 "active (running)" 이라고 하는 문구가 녹색으로 빛나고 있다면 Nginx 가 실행중인 상태인 것이다.

 

여기까지 왔다면, Nginx 가 80 포트에 Serve 하고 있는 것이고, 우리는 앞서 도메인과 레코드 설정을 모두 마쳤기 때문에, 자신의 도메인 이름을 브라우저(크롬이나 사파리 등)에 입력하여 Nginx 기본 사이트가 뜨는 것을 볼 수 있다.



이제 Nginx 에 다운로드한 SSL 인증서를 먹여보자!

먼저, Nginx 에 원하는 도메인에 대한 설정 영역을 만들어주자.

cd /etc/nginx/sites-available
sudo vim 당신의.도메인

왜 이렇게 하냐면, 기존 설정을 건드리지 않은 상태에서 내가 관리하는 도메인 별로 설정파일들을 만들어두고 갈아끼우기 위함이다. 그래서 자신이 지금 등록하려는 도메인의 이름으로 설정 파일을 작성하는 것이다.

 

이제 해당 파일에 아래와 같은 골자로 Nginx 설정들을 적어준다.
구체적으로 원하지 않는 설정이 있거나, 필요한 설정이 있으면 과감하게 가감하면 된다.

server {
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
        client_max_body_size 60M;

        ssl_certificate "/etc/letsencrypt/live/당신의.도메인/fullchain.pem";
        ssl_certificate_key "/etc/letsencrypt/live/당신의.도메인/privkey.pem";

                server_name 당신의.도메인;
        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header X-Real-IP $remote_addr;

                proxy_pass http://localhost:3000;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        client_max_body_size 60M;

        ssl_certificate "/etc/letsencrypt/live/당신의.도메인/fullchain.pem";
        ssl_certificate_key "/etc/letsencrypt/live/당신의.도메인/privkey.pem";

        server_name api.당신의.도메인;
        location / {
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header X-Real-IP $remote_addr;

                proxy_pass http://localhost:8000;
        }
}

server {
        listen 80;
        server_name 당신의.도메인;
        return 301 https://당신의.도메인$request_uri;
}

server {
        listen 80;
        server_name api.당신의.도메인;
        return 301 https://api.당신의.도메인$request_uri;
}

예시를 보여주려다 보니, 서브도메인을 드러내어 버리고 말았다.

 

전자의 2가지는 무엇이냐.

다운로드된 letsencrypt 의 SSL 인증서의 파일 경로를 지정함으로써, SSL 을 적용하여 HTTPS/443 을 이용하겠다는 뜻이다.

그리고 또한, 각각 서브도메인에서 HTTPS 프로토콜로 요청이 왔을 때! 해당 server_name 이 무엇으로 요청되었느냐에 따라 어떤 위치로 요청을 전달할 것이냐를 결정하는 것이다.

프록시, 전달과 관련한 체계로는, 첫번째는 "당신의.도메인"으로 접근하면 로컬호스트의 3000번에 켜진 앱으로 넘기겠다는거고, 두번째는 "api.당신의.도메인"으로 접근하면 로컬호스트의 8000번에 켜진 앱으로 넘기겠다는 뜻이 된다.

나머지는 클라이언트 바디 사이즈 설정(이거 때문에 가끔 피를 본다)과 SSL 설정 등에 대한 것으로 매우매우 예시이다.

 

후자의 2가지는 무엇이냐.

아래는 Redirection 에 대한 이야기로, 80 포트로 접근하면 자동으로 443 포트로 보내주겠다는 뜻이다. 아름답지 않고 아쉬운 HTTP/80 포트에 대한 접근도 깔쌈하게 HTTPS/443 포트로 보내주는 친절함이다.

 

위의 내용을 작성하였으면, 이제 ":wq" 를 입력해서 저장하고 나오자.
그리고 이제 실제 Nginx 설정파일로 연결하기 위해 심볼릭 링크를 지정하자. (파일 Move를 하는 것과 같다고 보면 된다.)

sudo ln -s /etc/nginx/sites-available/당신의.도메인 /etc/nginx/sites-enabled/

 

자, 이제 Nginx 설정 파일의 문법 오류를 검사한 뒤, 문제가 없다면 Nginx 를 재실행 해준다.

sudo nginx -t
sudo nginx -s reload

 

문제 없이 Nginx 가 잘 실행되었다면, 모든 설정이 완료되었다.

 

우리는 이제 멋쟁이 HTTPS 프로토콜로 반응하는 도메인 주소를 갖게 되었다! 엄연한 도메인을 가진 서버의 주인이 되었다.