Multi-Domain
목차
도메인 통합 #
8개의 도메인을 통합하면서 기록해 두었던 내용입니다.
가상계정을 이용하여 구성하였습니다.
로그인 id가 user1@domain2.com 형식으로 사용됩니다.
그동안 AI와 작업하면서 꼼꼼하게 기록한다고 했는데
아마도 빠진 부분이 있을 수 있습니다.
중요한 내용은 대부분 기록되었으니
혹시나 작업하다 막히는 부분은
AI의 도움을 받으면 쉽게 해결이 되리라 생각합니다.
초보 분들에게 도움이 되었으면 합니다.
이 글을 읽기 전에
이 글은 postfix/dovecot이 이미 설치돼 있다는 전제로, 그 위에 여러 도메인을 가상계정 방식으로 통합하는 설정만 다룹니다. 도메인·DNS· 네트워크 기초부터 처음 보시는 거라면 초보자를 위한 자체 메일서버 구축 기초 지식을 먼저 읽고 오시는 걸 추천합니다.
이 글에서 만드는 설정(도메인/계정을 텍스트 파일로 관리)은 시작 단계에 적합하고, 도메인·계정 수가 늘어나면 이후 MariaDB기반 MultiDomain 글에서 DB 기반으로 전환하는 과정을 다룹니다.
postfix/dovecot 기본 설치 (이미 돼 있다면 건너뛰기) #
sudo apt update
sudo apt install postfix dovecot-core dovecot-imapd dovecot-lmtpd -y
설치 중 postfix 설정 화면이 뜨면 Internet Site를 선택하고, 시스템 메일 이름은 나중에 어차피 이 글에서 다시 손보니 일단 아무 값이나 넣고 넘어가도 됩니다.
가상계정(virtual account) 방식이란 #
리눅스에는 원래 useradd user1 처럼 시스템 계정을 하나씩 만들어서
메일 계정으로 쓰는 방식이 있습니다. 하지만 도메인 8개, 계정 수십 개를
전부 시스템 계정으로 만들면 리눅스 로그인 계정이 어지러워지고 보안
관리도 힘들어집니다.
그래서 실제 리눅스 로그인 계정과 분리된 가상(virtual) 계정을 써서,
user1@domain1.com처럼 도메인이 포함된 형태의 메일 계정을 얼마든지
만들 수 있게 하는 방식입니다. 실제로는 vmail이라는 계정 하나가
모든 도메인의 메일 파일을 대신 소유하고, 각 사용자는 그 밑의 폴더
하나씩을 배정받는 구조입니다.
vmail 계정 확인 #
가상계정들의 메일 파일을 실제로 소유할 전용 시스템 계정입니다. 로그인 용도가 아니라 파일 소유권 관리용으로만 씁니다. 없으면 먼저 생성하세요.
id vmail
없다면:
sudo groupadd -g 1005 vmail
sudo useradd -g vmail -u 1005 vmail -d /var/mail/vhosts -m
Dovecot 핵심 설정 확인 #
sudo doveconf -n | sed -n '/userdb {/,/}/p'
반드시 아래가 있어야 합니다. 이게 없으면 메일이 도착해도 저장할 곳을 못 찾아서 LMTP temp_fail(임시 배달 실패)이 발생합니다.
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
%d는 도메인, %n은 로그인 id의 @ 앞부분을 뜻하는 Dovecot 변수라,
계정마다 폴더를 일일이 안 적어줘도 자동으로 도메인/계정명 경로가
만들어집니다.
/etc/dovecot/conf.d/10-auth.conf #
sudo nano /etc/dovecot/conf.d/10-auth.conf
아래 내용 입력 (중복은 삭제하거나 주석 처리하고, 없는 항목만 추가):
disable_plaintext_auth = no
auth_username_format = %Lu
auth_mechanisms = plain login
passdb {
driver = passwd-file
args = scheme=SHA512-CRYPT /etc/dovecot/passwd
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
passdb: 로그인 시 비밀번호를 어디서/어떻게 검증할지 (여기서는 텍스트 파일/etc/dovecot/passwd에 저장된 해시와 비교)userdb: 인증에 성공한 계정의 메일함이 실제로 어디 있는지
Postfix main.cf 설정 확인 #
sudo nano /etc/postfix/main.cf
아래 설정이 반드시 있어야 합니다.
# 가상 도메인 목록 (8개 도메인 리스트)
virtual_mailbox_domains = hash:/etc/postfix/virtual_domains
# 가상 사용자 목록 (user1@domain2.com ... 리스트)
virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox_maps
# Dovecot에게 배달을 맡기는 설정 (LMTP)
virtual_transport = lmtp:unix:private/dovecot-lmtp
# 메일이 저장되는 최상위 경로
virtual_mailbox_base = /var/mail/vhosts
LMTP가 뭔지: 메일을 최종적으로 사서함에 저장하는 배달 방식 중 하나입니다. Postfix는 메일을 “받는 것"까지만 담당하고, 실제 저장은 Dovecot에게 넘기는데, 이때 Postfix와 Dovecot이 서로 대화하는 통로가 LMTP입니다. 일반 SMTP보다 배달 실패 사유를 더 정확하게 주고받을 수 있어서, 가상계정 메일 서버에서는 LMTP를 쓰는 게 표준입니다.
main.cf 설정 연결 #
sudo nano /etc/postfix/main.cf
아래 내용을 순서대로 추가 또는 수정합니다.
# sender_login 보호 (주소 위조 방지) — 로그인한 계정과
# 실제 보낸사람(From) 주소가 일치하는지 검사하는 데 쓰임
smtpd_sender_login_maps = hash:/etc/postfix/sender_login_maps
smtpd_client_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_pipelining,
reject_unknown_client_hostname,
reject_rbl_client zen.spamhaus.org
smtpd_sender_restrictions =
reject_sender_login_mismatch,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
permit_sasl_authenticated,
permit_mynetworks
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_pipelining,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unknown_client_hostname,
reject_rbl_client zen.spamhaus.org,
reject_unauth_destination
각 옵션이 하는 일을 간단히 짚으면:
reject_sender_login_mismatch: 로그인한 계정과 실제 발신 주소가 다르면 거부 — 남의 이름으로 메일 보내는 걸 막는 핵심 방어reject_unknown_client_hostname: 접속해온 서버의 이름(PTR)이 아예 확인 안 되면 의심 — 지난 DNS 글에서 다룬 PTR이 여기서도 쓰입니다reject_rbl_client zen.spamhaus.org: 이미 스팸 발송지로 알려진 IP 블랙리스트(Spamhaus)에 걸려있으면 거부 (선택사항 — 없어도 동작은 하지만 스팸 방어력이 약해집니다)reject_unauth_destination: 인증 안 된 사람이 남의 도메인으로 메일을 릴레이하려는 시도 차단 — 이게 빠지면 내 서버가 스팸 중계지로 악용될 수 있어서 절대 빼면 안 되는 항목입니다
Dovecot LMTP 소켓 설정 #
sudo nano /etc/dovecot/conf.d/10-master.conf
아래 내용을 입력하세요. Postfix가 Dovecot에게 메일을 넘겨줄 때 쓰는 통로(소켓)를 만드는 설정입니다.
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
submission(587) 포트 설정 #
sudo nano /etc/postfix/master.cf
25번 포트는 서버끼리 메일을 주고받는 용도이고, 메일 클라이언트
(아웃룩, 썬더버드 등)가 인증해서 메일을 “제출"할 때 쓰는 포트는
따로 있습니다. 587은 STARTTLS로 암호화, 465(submissions)는
처음부터 암호화된 연결(TLS wrapper)로 붙는다는 차이만 있고 용도는
같습니다.
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
submissions inet n - y - - smtpd
-o syslog_name=postfix/submissions
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
smtpd_recipient_restrictions=permit_sasl_authenticated,reject는
“인증된 사용자만 이 포트로 메일 제출 가능, 그 외엔 무조건 거부"라는
뜻으로, 이 포트를 익명 중계로 악용하지 못하게 막는 안전장치입니다.
가상 도메인 파일 #
sudo nano /etc/postfix/virtual_domains
domain1.com OK
domain2.com OK
sudo postmap /etc/postfix/virtual_domains
postmap은 방금 만든 텍스트 파일을 Postfix가 빠르게 조회할 수 있는
이진(binary) 인덱스 파일로 변환하는 명령입니다. 텍스트 파일을
수정할 때마다 이 명령을 다시 실행해야 변경사항이 실제로 반영됩니다
(이후 나오는 virtual_mailbox_maps, sender_login_maps도 동일).
가상 사용자 매핑 #
sudo nano /etc/postfix/virtual_mailbox_maps
없으면 새로 만들고 아래처럼 계정을 추가하세요.
user1@domain1.com domain1.com/user1/
user1@domain2.com domain2.com/user1/
저장 후 반영:
sudo postmap /etc/postfix/virtual_mailbox_maps
발신자 로그인 매핑 #
sudo nano /etc/postfix/sender_login_maps
user1@domain1.com user1@domain1.com
user1@domain2.com user1@domain2.com
저장 후 Postfix가 읽을 수 있도록 바이너리 인덱스 파일 생성:
sudo postmap /etc/postfix/sender_login_maps
메일 저장 폴더 생성 #
sudo mkdir -p /var/mail/vhosts/domain2.com/user1
권한 설정:
sudo chown -R vmail:vmail /var/mail/vhosts
sudo chmod -R 750 /var/mail/vhosts
아래는 선택 (개별 사용자 권한을 더 엄격히 하고 싶을 때):
sudo chmod 700 /var/mail/vhosts/domain2.com/user1
sudo chmod g-s /var/mail/vhosts/domain2.com/user1
확인:
ls -ld /var/mail/vhosts
# drwxr-s--- vmail vmail
Dovecot 비밀번호 설정 #
비밀번호 해시 생성:
doveadm pw -s SHA512-CRYPT
비밀번호 입력 후 나온 결과({SHA512-CRYPT}... 형태)를 복사해두세요.
패스워드 파일 열기:
sudo nano /etc/dovecot/passwd
복사한 비밀번호 해시를 추가합니다:
user1@domain1.com:{SHA512-CRYPT}...:1005:1005::/var/mail/vhosts/domain1.com/user1
user1@domain2.com:{SHA512-CRYPT}...:1005:1005::/var/mail/vhosts/domain2.com/user1
여기 있는 1005:1005(uid:gid)가 실제 vmail 계정의 uid/gid와
반드시 같아야 합니다. 다르면 Dovecot이 이 계정으로 로그인은
시켜주는데, 정작 파일을 소유한 계정과 권한이 안 맞아서 메일 읽기/쓰기
가 실패하는 문제가 생깁니다.
id vmail
# uid=1005(vmail) gid=1005(vmail)
저장 후 권한 설정:
sudo chown root:dovecot /etc/dovecot/passwd
sudo chmod 640 /etc/dovecot/passwd
설정 점검 후 재시작 #
postfix check
sudo systemctl restart dovecot
sudo systemctl restart postfix
내부 인증 테스트 #
doveadm auth test user1@domain2.com 비밀번호
아래처럼 나오면 성공입니다.
passdb: user1@domain2.com auth succeeded
최종 설정 백업 #
지금까지 적용된 전체 설정값을 파일로 남겨두면, 나중에 뭔가 잘못됐을 때 “원래 정상이던 상태"와 비교하기 좋습니다.
sudo -i
postconf -n > /root/postfix_final.conf
doveconf -n > /root/dovecot_final.conf
exit
다음 단계 #
도메인/계정이 몇 개 안 될 때는 지금처럼 텍스트 파일로 관리해도
충분하지만, 도메인과 계정 수가 늘어나면 파일을 계속 손으로 고치고
매번 postmap을 돌리는 게 번거로워집니다. 그 다음 단계로 MariaDB기반
MultiDomain에서 지금
이 설정을 DB 기반으로 전환하는 과정을 다룹니다.