초보자를 위한 자체 메일서버 구축 기초 지식 (도메인 · DNS · 네트워크 편)
목차
이 글은 누구를 위한 글인가 #
이 글은 “postfix 설치 명령어"를 알려주는 글이 아닙니다. 그 명령어를 치기 전에, 왜 그렇게 해야 하는지 몰라서 막히는 부분을 정리한 글입니다.
저도 리눅스 폴더 구조도 잘 모르고, 코드는 AI 도움을 받아 복붙하는 수준으로 시작했습니다. 그런데 메일서버는 코드보다 **“개념을 모르면 아예 시작을 못 하는 부분”**이 먼저 있습니다. 도메인, DNS, 공인IP, 포트포워딩 같은 것들인데, 이걸 모르고 postfix 설치부터 하면 100% 중간에 막힙니다. 이 글은 그 부분만 따로 떼어서, 실제 서버 설정 명령어 없이 개념과 준비물만 다룹니다.
(postfix/dovecot 설치 자체는 다른 글에서 다루니, 이 글을 먼저 읽고 넘어가시는 걸 추천합니다.)
큰 그림부터: 메일서버가 되려면 뭐가 필요한가 #
메일서버를 완성하는 데 필요한 걸 크게 나누면 이렇습니다.
- 도메인 —
snsoz.com같은 내 이름표 (이게 없으면 이메일 주소 자체가 안 나옴) - DNS 레코드 — “이 도메인 메일은 이 서버가 처리한다"고 전 세계에 알리는 설정
- 공인 IP + 네트워크 설정 — 외부에서 내 서버로 실제 접속이 가능해야 함
- VMware 가상머신 네트워크 설정 — VM이 인터넷에 직접 나갈 수 있게 얹혀 있어야 함
- 우분투 서버 기본 설정 — 여기서부터 실제 postfix/dovecot 설치로 이어짐
이 중 1~4번을 빼먹고 5번부터 시작하는 게 초보자가 가장 흔히 하는 실수입니다. 순서대로 짚어보겠습니다.
1. 도메인 등록 #
도메인이 왜 필요한가 #
shadow@내IP주소 같은 이메일은 있을 수 없습니다. 이메일 주소는 반드시
이름@도메인 형태여야 하고, 이 도메인은 내가 소유권을 등록한 것이어야
합니다. 남의 도메인으로는 당연히 메일서버를 못 만듭니다.
어디서 사는가 #
가비아, 후이즈, 카페24 같은 국내 등록대행사나, Namecheap, Cloudflare
Registrar 같은 해외 업체에서 구매합니다. .com, .net 기준 연 1만원대부터
시작합니다.
초보자가 놓치는 부분: 도메인을 “사는 것"과 “그 도메인의 DNS를 관리하는 것"은 별개의 서비스일 수 있습니다. 도메인은 A업체에서 사고, DNS는 B업체 (예: Cloudflare)에서 관리하는 조합도 흔합니다. 이 글에서는 편의상 “도메인 등록대행사가 제공하는 DNS 관리 화면을 그대로 쓴다"고 가정하겠습니다.
메인 도메인 vs 서브도메인 #
snsoz.com 자체를 메일서버 이름으로 쓸 수도 있지만, 보통은
mail.snsoz.com처럼 서브도메인을 메일서버 전용 이름(호스트네임)으로
따로 만듭니다. 이렇게 하면:
- 나중에
www.snsoz.com(홈페이지),mail.snsoz.com(메일서버)을 서로 다른 서버에 둬도 됩니다. - 메일서버 하나가 문제가 생겨도 다른 서비스에 영향이 적습니다.
이메일 주소 자체(shadow@snsoz.com)는 메인 도메인을 쓰면서, 메일서버의
“이름표"만 mail.snsoz.com으로 따로 두는 구조가 일반적입니다.
2. DNS 기초: 메일서버에 필요한 레코드 5종 #
DNS는 “도메인 이름 ↔ 실제 정보"를 연결해주는 전화번호부입니다. 메일서버를 만들려면 아래 5가지 레코드를 반드시 이해하고 있어야 합니다. 이 중 하나만 빠져도 메일이 스팸함으로 가거나, 아예 발송/수신이 안 됩니다.
① A 레코드 — 이름을 IP로 연결 #
mail.snsoz.com A 203.0.113.10
mail.snsoz.com이라는 이름이 실제로 어떤 IP 주소를 가리키는지 알려주는
가장 기본적인 레코드입니다. 이게 없으면 아무도 내 서버를 못 찾습니다.
② MX 레코드 — 이 도메인 메일을 어디로 보낼지 #
snsoz.com MX 10 mail.snsoz.com
“@snsoz.com으로 온 메일은 mail.snsoz.com(위에서 만든 A 레코드)으로
보내라"는 뜻입니다. 메일서버를 만든다면 절대 빠뜨릴 수 없는 핵심 레코드
입니다. 숫자(10)는 우선순위인데, 서버가 하나뿐이면 신경 안 쓰셔도 됩니다.
초보자가 놓치는 부분: MX 레코드는 A 레코드처럼 IP를 직접 적는 게 아니라, 반드시 도메인 이름(호스트네임)을 적어야 합니다.
MX 10 203.0.113.10처럼 IP를 바로 적는 실수를 은근히 많이 합니다.
③ PTR 레코드 (역방향 DNS) — 가장 많이 빼먹는 것 #
이건 지금까지와 반대 방향입니다: “이 IP는 어떤 이름을 가진 서버인가"를 알려주는 레코드입니다.
203.0.113.10 → mail.snsoz.com
이게 없으면 Gmail, 네이버 같은 큰 메일서비스들이 내가 보낸 메일을 스팸 취급하거나 아예 거부합니다. 스팸 발송 서버들은 보통 이게 제대로 안 돼 있기 때문에, PTR이 없다는 것 자체가 “의심스러운 서버"라는 신호로 읽힙니다.
가장 중요한 함정: PTR 레코드는 도메인 등록대행사나 내가 직접 설정할 수 없습니다. 이 IP를 실제로 소유한 인터넷 회사(ISP, 통신사)에 요청해야만 설정됩니다. 즉 KT, SKB, LG유플러스 같은 곳에 “이 고정 공인IP의 PTR을 mail.snsoz.com으로 설정해달라"고 요청하는 절차가 필요합니다. 이 신청 없이는 아무리 서버 설정을 잘해도 메일이 계속 스팸함으로 갑니다.
④ SPF 레코드 — “이 IP만 내 메일이다” #
snsoz.com TXT "v=spf1 mx ~all"
“snsoz.com에서 온다고 주장하는 메일은, MX 레코드에 등록된 서버에서 와야
정상이고, 그게 아니면 의심하라"는 선언입니다. mx 부분에 내 메일서버가
자동으로 포함됩니다.
⑤ DKIM / DMARC 레코드 — 서명과 정책 #
- DKIM: 서버에서
opendkim-genkey같은 명령으로 키를 만들면, 그 결과로 나온 공개키 문자열을 DNS TXT 레코드로 등록합니다. (이 키 생성 자체는 서버 설정 단계라 이 글의 범위 밖입니다.) - DMARC:
SPF/DKIM 둘 다 실패한 메일을 어떻게 처리할지(격리/거부/통과) 정하는 정책입니다. 처음엔_dmarc.snsoz.com TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@snsoz.com"p=none(통과, 로그만 수집)으로 시작해서, 문제없는 걸 확인한 뒤quarantine(격리) →reject(거부) 순으로 강도를 올리는 게 안전합니다.
DNS 전파 시간 #
레코드를 바꾸면 즉시 적용되는 게 아니라, 전 세계 DNS 서버에 퍼지는 데 보통 몇 분에서 최대 48시간까지 걸릴 수 있습니다. 설정 바꾸고 바로 테스트했는데 안 된다고 당황하지 마시고, 30분~1시간 정도는 기다려보세요. 확인은 아래 명령으로 할 수 있습니다.
dig MX snsoz.com
dig TXT snsoz.com
dig -x 203.0.113.10 # PTR 확인
3. 네트워크: 공인 IP가 왜 절대적으로 필요한가 #
유동 IP로는 안 되는 이유 #
집/사무실 인터넷은 보통 유동 IP(접속할 때마다 또는 며칠마다 IP가 바뀜)입니다. 그런데 위에서 만든 A 레코드, PTR 레코드는 고정된 IP 주소를 전제로 합니다. IP가 바뀌면 DNS에 등록해둔 주소가 틀린 정보가 되어버립니다.
일반 홈페이지라면 DDNS(동적 DNS, IP 바뀔 때마다 자동으로 도메인 갱신)로 어느 정도 우회할 수 있지만, 메일서버는 PTR 레코드 때문에 DDNS로 우회가 안 됩니다. PTR은 ISP가 그 IP에 대해 직접 설정해주는 것이라, IP가 바뀌면 그때마다 ISP에 재신청해야 하는데 현실적으로 불가능합니다.
결론: 메일서버를 제대로 하려면 ISP에서 고정 공인 IP를 받아야 합니다. (가정용 회선은 보통 안 되고, 비즈니스/고정IP 옵션 회선 가입이 필요한 경우가 많습니다. 통신사에 “고정 공인 IP + PTR 설정 가능 여부"를 먼저 문의해보세요.)
포트 25번, 어디서 막힐 수 있는지 정확히 구분하기 #
메일서버끼리 주고받는 기본 포트는 25번인데, 이게 막혀있으면 아무리 서버 설정을 완벽히 해도 다른 서버로 메일을 보내는 것 자체가 안 됩니다. 다만 “어디서 막느냐"는 두 종류를 구분해야 합니다.
- 클라우드/VPS 업체(AWS, Linode, DigitalOcean, GCP 등): 스팸 발송 서버 남용을 막기 위해 기본적으로 거의 확실하게 막혀 있습니다. 신규 계정으로 서버를 만들면 25번 아웃바운드가 처음부터 차단돼 있고, 고객센터에 별도로 신청해야 풀어줍니다 (실제로 이 방식으로 운영 중인 VPS가 많습니다).
- 국내 가정용 회선(KT/SKB/LGU+ 등): 과거 스팸봇 방지 목적으로 통신사 차원에서 25번을 막던 정책이 있었지만, 실제로는 통신사·상품· 회선 종류에 따라 제각각이라 확실히 막혀 있다고 단정할 수 없습니다. 유동IP 회선에서도 문제없이 메일이 오간 사례처럼, 안 막혀 있는 경우도 흔합니다.
확인 방법: 클라우드/VPS를 쓴다면 처음부터 “25번 포트 아웃바운드가 기본 차단돼 있는지, 신청 절차가 어떻게 되는지"부터 확인하고 시작하는 게 맞습니다. 가정용 회선이라면 미리 겁먹지 말고, 실제로 서버를 만든 뒤 아래처럼 직접 테스트해보는 게 가장 정확합니다.
telnet gmail-smtp-in.l.google.com 25
연결이 되면(Connection refused가 아니라 SMTP 배너가 뜨면) 25번은 열려 있는 겁니다. 막혀 있는 게 확인되면 그때 통신사 고객센터에 문의하세요.
필요한 포트 목록 #
아래 포트들이 실제로 인터넷 쪽에서 서버까지 열려 있어야 메일서버가 동작합니다. (어떤 방식으로 열어야 하는지는 본인 네트워크 구조에 따라 다음 챕터에서 갈립니다.)
| 포트 | 용도 |
|---|---|
| 25 | SMTP (서버 간 메일 주고받기) |
| 587 | SMTP 제출(Submission, 메일 클라이언트에서 보낼 때) |
| 993 | IMAPS (메일 클라이언트에서 받은편지함 조회) |
| 995 | POP3S (POP3 쓸 경우) |
| 443 | HTTPS (웹메일/관리 대시보드를 외부에 열 경우) |
공유기(NAT)를 거치는 구조라면: 포트포워딩 필요 #
일반적인 가정집처럼 “모뎀 → 공유기(NAT) → 내부 LAN” 구조라면, 공유기가 외부에서 들어오는 요청을 서버로 전달해주지 않는 이상 아무 소용없습니다. 공유기 관리 화면에서 위 표의 포트들을 서버(VM)의 내부 IP로 포워딩해줘야 합니다.
초보자가 놓치는 부분: 포트포워딩을 할 때 “포워딩 대상 IP"는 VM의 내부(LAN) IP를 적어야 합니다. 공인IP를 적는 게 아닙니다. 그리고 이 내부 IP가 재부팅할 때마다 바뀌면 포워딩이 깨지니, VM에 고정 내부 IP를 부여해두는 게 먼저입니다 (공유기의 “IP 예약/고정 할당” 기능 이용).
모뎀에 직접 물려서 공인IP를 직접 받는 구조라면: 포트포워딩 불필요 #
반면 모뎀이 공유기 없이 공인IP를 여러 개 직접 나눠주는 회선 (고정IP 1개 + 유동IP 여러 개를 함께 제공하는 상품 등)이라면, VM이 이미 공인IP를 직접 갖고 있는 셈이라 포트포워딩 자체가 필요 없습니다. 전달해줄 “내부 IP"라는 개념 자체가 없는 구조이기 때문입니다. 이 경우엔 VM 안에서 직접 고정IP를 설정하는 절차가 필요한데, 이건 다음 챕터에서 다룹니다.
본인이 어느 구조인지 모르겠다면, 통신사에 “지금 쓰는 회선이 모뎀이 공인IP를 직접 나눠주는 구조인지, 아니면 공유기가 NAT를 하고 있는 구조인지” 문의해보시면 가장 정확합니다.
4. VMware 네트워크 설정 (브릿지 모드) #
브릿지 모드가 뭔가 #
VMware의 네트워크 모드는 크게 NAT, 브릿지(Bridge) 두 가지를 많이 씁니다.
- NAT 모드: VM이 호스트(내 PC/서버) 뒤에 숨어서, 호스트를 거쳐서만 외부와 통신합니다. VM은 ISP 회선에 직접 안 보이는 상태입니다.
- 브릿지 모드: VM의 가상 네트워크 카드가 호스트의 물리 랜카드를 그대로 통해서, ISP 모뎀에 직접 연결된 것처럼 동작합니다. 가정용 공유기를 거치는 구조가 아니라, 모뎀이 직접 공인IP를 나눠주는 회선 (예: KT 등에서 고정IP 1개 + 유동IP 여러 개를 함께 제공하는 상품)이라면, VM이 그 공인IP 중 하나를 그대로 받아서 인터넷에 직접 노출됩니다.
가정용 공유기 환경과의 차이: 흔한 가정집처럼 “모뎀 → 공유기(NAT) → 내부 LAN"으로 구성된 환경에서는, 브릿지 모드를 써도 결국 공유기의 사설 LAN IP를 받게 되고, 이 경우엔 앞에서 설명한 “공유기 포트포워딩"이 그대로 필요합니다. 반면 **모뎀이 여러 개의 공인IP를 직접 뿌려주는 회선(비즈니스/고정IP 상품 등)**이라면, 공유기 없이 모뎀에 VM을 직접 물려서 브릿지 모드로 공인IP를 그대로 받는 구성도 가능합니다 — 이 경우 포트포워딩 자체가 필요 없어집니다(이미 공인IP를 직접 갖고 있으므로). 어느 쪽이든 메일서버는 반드시 브릿지 모드를 써야 합니다. NAT 모드는 VM의 존재 자체가 외부/공유기에 안 보이는 구조라, 공인IP를 직접 받는 것도 포트포워딩을 받는 것도 둘 다 불가능합니다.
브릿지 모드는 똑같이 켜고, “IP 고정 방법"만 갈린다 #
여기서부터 헷갈리기 쉬운 부분이라 표로 정리합니다. 브릿지 모드를 켜는 것 자체는 아래 두 경우 다 동일하게 필요합니다. 브릿지 모드 안에서 “그 IP를 어떻게 고정하느냐"만 구조에 따라 방법이 달라지는 것뿐입니다.
| 경우 A: 모뎀 → 공유기(NAT) → VM | 경우 B: 모뎀 → VM (공유기 없이 직결) | |
|---|---|---|
| VMware 네트워크 모드 | 브릿지 (동일) | 브릿지 (동일) |
| VM이 받는 IP 종류 | 공유기가 주는 사설 LAN IP | 모뎀이 주는 공인 IP |
| IP 고정 방법 | 공유기 관리화면에서 “IP 예약” 버튼 클릭 | 우분투 안에서 netplan 설정파일을 직접 편집 |
| 손이 가는 정도 | 쉬움 (클릭 몇 번) | 상대적으로 번거로움 (설정 직접 입력) |
| 외부 접속 시 포트포워딩 | 필요함 | 필요 없음 (이미 공인IP 직접 보유) |
shadow님 환경은 경우 B(모뎀 직결)이므로, 아래 netplan 설정이 맞는 방법입니다.
netplan으로 고정 공인IP 설정하기 #
모뎀에 직접 물려서 공인IP를 직접 받는 구조라면, VM이 받을 공인IP를
고정으로 쓰기 위해 우분투 안에서 직접 설정해줘야 합니다. 최신 우분투는
네트워크 설정을 netplan으로 관리합니다.
(공유기를 거치는 구조라면 이 과정 대신, 공유기의 “IP 예약/고정 할당” 기능으로 VM의 내부 IP만 고정하면 됩니다 — 그쪽이 훨씬 간단합니다.)
먼저 네트워크 인터페이스 이름을 확인하세요 (환경마다 다릅니다, 보통
ens160, ens33, eth0 중 하나):
ip a
설정 파일을 엽니다:
sudo nano /etc/netplan/50-cloud-init.yaml
아래처럼 고정IP, 게이트웨이(모뎀 IP), DNS를 직접 지정합니다. 실제 값은 ISP가 안내해준 대로 넣으세요:
network:
version: 2
ethernets:
ens160: # 위에서 확인한 실제 인터페이스명으로 교체
dhcp4: no
addresses:
- 203.0.113.10/29 # 할당받은 고정 공인IP/서브넷
routes:
- to: default
via: 203.0.113.1 # 모뎀(게이트웨이) IP
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
저장 후 적용:
sudo netplan apply
주의: 오타가 있으면 서버 네트워크 자체가 끊길 수 있습니다. 콘솔 (VMware 화면 직접 접근)로 접속 가능한 상태에서 작업하시고, 원격 SSH로만 접근 가능한 상태라면
sudo netplan try명령으로 120초 안에 정상 접속되는지 확인 후 적용하는 방법도 있습니다.
다른 기기가 같은 IP를 가져가지 못하게 막기 #
가정용 공유기는 보통 기기별 MAC 주소로 IP를 “예약"해주는 기능이 있지만, 모뎀이 여러 공인IP를 그냥 나눠주는 구조는 이런 MAC 바인딩이 없는 경우가 많습니다. 즉 모뎀 입장에서는 “이 IP는 누구 것"이라는 개념이 없고, 그 밑에 물린 어떤 기기든 그 IP 대역 중 하나를 정적으로 설정해버리면 그대로 충돌이 날 수 있습니다.
이런 구조에서는 아래처럼 관리하는 게 안전합니다.
- 사용 중인 IP를 문서(메모)로 기록해두기 — 어떤 기기가 어떤 공인IP를 쓰는지 목록을 만들어두고, 새 기기를 연결할 때마다 그 목록부터 확인.
- 할당 전에 실제로 비어있는지 확인: 다른 PC나 서버에서 아래
명령으로 그 IP에 이미 응답하는 기기가 있는지 먼저 확인합니다.
응답이 없어야 안전하게 쓸 수 있는 IP입니다.
ping -c 3 203.0.113.10 arping -c 3 203.0.113.10 - IP 충돌 발생 시 우분투가 알려줌: 이미 설정한 IP를 다른 기기가
동시에 쓰기 시작하면, 로그에 “duplicate address detected” 류의
경고가 남습니다. 평소에도 가끔
로 확인해보는 습관을 들이면 좋습니다.
journalctl -k | grep -i duplicate - 가능하면 모뎀 관리 화면에서 직접 확인: 통신사 모뎀에 관리자 페이지가 있다면, 현재 연결된 기기/IP 목록을 보여주는 기능이 있는 경우가 많습니다. ISP 고객센터에 관리자 페이지 접근법을 문의해보는 것도 방법입니다.
5. 우분투 서버, 최소한의 준비 #
이 글은 postfix 설치를 다루지 않지만, 그 전 단계에서 확인해둬야 할 기본기만 짚고 넘어가겠습니다.
호스트네임을 미리 도메인과 맞춰두기 #
서버의 호스트네임(hostname)이 나중에 postfix 설정, DKIM, PTR과 전부
연결됩니다. 처음부터 실제 쓸 이름(예: mail.snsoz.com)으로 맞춰두는 게
나중에 헷갈릴 일이 없습니다.
sudo hostnamectl set-hostname mail.snsoz.com
시간 동기화(NTP)는 꼭 켜두기 #
시간이 서버끼리 크게 어긋나 있으면, DKIM 서명 검증이 실패하거나 TLS 인증서 관련 문제가 생길 수 있습니다. 우분투는 보통 기본으로 켜져 있지만 확인은 해두는 게 좋습니다.
timedatectl status
System clock synchronized: yes인지 확인하세요.
방화벽(ufw) 기본 개념 #
우분투 기본 방화벽인 ufw는, 공유기 포트포워딩이나 모뎀 직결 여부와 별개로 서버 내부에서 한 번 더 포트를 열어줘야 하는 존재입니다. 바깥쪽 네트워크 경로(공유기든 모뎀이든)만 열어두고 서버 방화벽을 안 열면(또는 그 반대) 여전히 접속이 안 됩니다. 둘 다 맞춰야 한다는 점을 꼭 기억하세요.
sudo ufw allow 25/tcp
sudo ufw allow 587/tcp
sudo ufw allow 993/tcp
sudo ufw allow 443/tcp
sudo ufw allow OpenSSH
sudo ufw enable
초보자가 특히 자주 놓치는 것 7가지 (요약) #
- PTR 레코드는 내가 못 정한다 — ISP에 직접 신청해야 함. 이걸 모르고 서버 설정만 계속 만지다가 며칠을 낭비하는 경우가 제일 흔합니다.
- 25번 포트는 업체마다 다르다 — 클라우드/VPS는 기본 차단이
거의 확실하니 신청 절차부터 확인, 가정용 회선은 실제로 열려있는
경우도 흔하니 겁먹지 말고
telnet ... 25로 직접 테스트부터. - 유동 IP로는 메일서버가 사실상 불가능하다 — 고정 공인 IP 필수.
- VMware는 반드시 브릿지 모드 — NAT 모드로는 공인IP를 직접 받든 포트포워딩을 받든 둘 다 애초에 불가능함.
- VM의 IP를 고정해둬야 한다 — DHCP로 계속 바뀌면 안 됨. 공유기를
거치는 구조라면 공유기의 IP 예약 기능으로, 모뎀에 직접 물린 구조라면
netplan고정IP 설정으로 해결. - 공유기를 거치는 구조라면 포트포워딩 + 서버 방화벽(ufw) 둘 다 열어야 한다 — 모뎀에 직접 물린 구조라면 포트포워딩은 필요 없고 ufw만 열면 됨. 본인 환경이 둘 중 어느 쪽인지부터 먼저 파악할 것.
- DNS는 바로 반영 안 된다 — 설정 바꾸고 최소 30분~1시간은 기다려보고 판단할 것.
다음 단계 #
이 글에서 다룬 도메인/DNS/네트워크 준비가 다 끝났다면, 그다음은:
- postfix + dovecot + MariaDB로 실제 메일 송수신 서버 구축
- OpenDKIM/OpenDMARC/SPF 검증기로 스팸 방지 체계 완성
- mail-tester.com, MXToolbox로 최종 점검
순서로 이어집니다. 이 글에서 준비물만 제대로 갖춰두면, 실제 서버 설정 과정에서 “왜 안 되지?“로 헤매는 시간이 크게 줄어듭니다.