실습 환경
- rocky1 : 메일 발신 서버 / DNS 서버 (koreait.com)
- rocky2 : 메일 수신 서버 (exam.com)
- MTA : Postfix
- Mail Access Server : Dovecot
- DNS : BIND
- Webmail : Roundcube
1. 메일 서버 구조 개념
DNS (MX record)
↓
Postfix (SMTP)
↓
Mailbox (/var/spool/mail)
↓
Dovecot (POP3 / IMAP)
↓
Mail Client (Evolution, Roundcube 등)
메일 전송 흐름은 다음과 같다.
- 사용자가 메일 발송
- 발신 메일 서버가 DNS 조회
- 수신 도메인의 MX 레코드 확인
- MX 레코드에 지정된 메일 서버 확인
- SMTP 25번 포트로 메일 전달
2. BIND DNS 서버 설정 (rocky1)
패키지 설치
yum install bind bind-utils -y
/etc/named.conf 수정
외부 클라이언트의 요청을 받을 수 있도록 아래 두 항목을 any로 변경한다.
listen-on port 53 { any; };
allow-query { any; };
Zone 정의 (/etc/named.rfc1912.zones)
파일 맨 아래에 추가한다.
zone "koreait.com" IN {
type master;
file "koreait.com.zone";
allow-update { none; };
};
Zone 파일 생성 (/var/named/koreait.com.zone)
cd /var/named/
cp -p named.localhost koreait.com.zone
vi koreait.com.zone
$TTL 1D
@ IN SOA @ rname.invalid. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
NS @
A 192.168.x.x
MX 10 mail.koreait.com.
mail IN A 192.168.x.x
서비스 시작 및 확인
systemctl restart named
nslookup mail.koreait.com 127.0.0.1
Address: 192.168.x.x 가 나오면 성공이다.
3. Postfix 설정
주요 설정 항목 (postconf -e)
postconf -e 'myhostname = mail.exam.com'
postconf -e 'mydomain = exam.com'
postconf -e 'myorigin = $mydomain'
postconf -e 'inet_interfaces = all'
postconf -e 'inet_protocols = ipv4'
postconf -e 'mydestination = $mydomain,localhost.$mydomain,localhost,/etc/postfix/local-host-names'
postconf -e 'smtpd_sasl_type = dovecot'
postconf -e 'smtpd_sasl_path = private/auth'
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_sasl_security_options = noanonymous'
postconf -e 'smtpd_sasl_local_domain = $myhostname'
postconf -e 'smtpd_client_restrictions = permit_mynetworks,permit'
postconf -e 'smtpd_recipient_restrictions = permit_mynetworks,permit_auth_destination,permit_sasl_authenticated,reject'
서비스 재시작
systemctl restart postfix dovecot
포트 확인
netstat -ntlp | grep :25 # SMTP
netstat -ntlp | grep :110 # POP3
4. 메일 큐 문제 해결 (핵심 트러블슈팅)
증상
rocky1에서 admin@exam.com으로 메일을 보냈는데 큐에 계속 쌓이고 전달이 안 됨.
postqueue -p
# 11개 메일이 계속 deferred 상태
원인 파악
tail -n 50 /var/log/maillog | grep -i "error\|connect\|refused\|timeout"
connect to exam.com[52.20.x.x]:25: Connection timed out
로컬 DNS에 exam.com MX 레코드가 없어서, Postfix가 인터넷에서 실제 exam.com 서버를 찾아 외부 IP로 메일을 보내려다 타임아웃이 발생한 것이었다.
dig MX exam.com
# ANSWER: 0 -> MX 레코드 없음
dig A mail.exam.com
# status: NXDOMAIN -> 도메인 없음
해결 방법 - transport_maps 설정
DNS를 건드리지 않고 Postfix에 직접 라우팅을 지정하는 방법이다.
postconf -e "transport_maps = hash:/etc/postfix/transport"
echo "exam.com smtp:[192.168.x.x]" > /etc/postfix/transport
postmap /etc/postfix/transport
systemctl restart postfix
# 큐에 쌓인 메일 재전송
postsuper -r ALL
postfix flush
결과 확인
tail -f /var/log/maillog
# status=sent (delivered to maildir) 가 나오면 성공
큐에 쌓여 있던 메일 11개가 한 번에 전송 완료되었다.
핵심 정리
로컬 메일 서버 간 통신 시 반드시 로컬 DNS에 MX 레코드가 등록되어 있어야 한다. 없으면 Postfix가 인터넷에서 해당 도메인을 찾아 엉뚱한 서버로 메일을 보낸다. transport_maps는 DNS 없이도 특정 도메인의 메일을 지정한 서버로 강제 라우팅하는 방법이다.
5. Roundcube 웹메일 구축
구조
웹브라우저
↓
웹서버 (Apache + PHP)
↓
Roundcube
↓
데이터베이스 (MariaDB)
↓
메일서버 (Postfix / Dovecot)
MariaDB 설정
mysql -u root -p
create user rcadmin@localhost identified by '비밀번호';
create database rcdb;
grant all privileges on rcdb.* to rcadmin@localhost;
PHP 및 Roundcube 설치
dnf module enable php:8.3
# wget으로 Roundcube 다운로드 후 압축 해제
tar xf roundcubemail-1.7-rc4.tar.gz
mv roundcubemail-1.7-rc4 rc
접속 주소
http://서버IP/rc/public_html/
구버전은 /rc로 끝나지만 신버전은 /rc/public_html/로 접속해야 한다.
6. NIC Bonding
개념
여러 개의 물리 NIC를 하나의 논리 인터페이스로 묶어 사용하는 기술이다. 네트워크 이중화(High Availability)와 대역폭 확장(Load Balancing)을 목적으로 사용한다.
bond0
|
+-- ens160 (현재 활성, 메인)
+-- ens192 (대기, 장애 시 자동 전환)
IP 주소는 bond 인터페이스에만 설정한다.
맥북(Apple Silicon)에서의 제약
VMware Fusion + M1/M2/M3 환경에서는 ARM 아키텍처 제한으로 GUI에서 NIC 추가가 불가능하다. vmx 파일 직접 수정이 필요하나, 파일 경로를 찾지 못하는 경우 VLAN으로 우회하는 방법을 사용할 수 있다.
VLAN으로 우회하여 Bonding 구성
물리 NIC가 1개뿐인 환경에서 VLAN 인터페이스 2개를 만들어 슬레이브로 사용하는 방법이다.
# VLAN 생성
nmcli con add type vlan con-name ens160.10 dev ens160 id 10 ipv4.method disabled ipv6.method disabled
nmcli con add type vlan con-name ens160.20 dev ens160 id 20 ipv4.method disabled ipv6.method disabled
# bond0 생성
nmcli con add type bond con-name bond0 ifname bond0 bond.options "mode=active-backup,miimon=100"
# 슬레이브 연결
nmcli con add type ethernet con-name bond-slave-1 ifname ens160.10 master bond0
nmcli con add type ethernet con-name bond-slave-2 ifname ens160.20 master bond0
# bond0 IP 설정
nmcli con mod bond0 \
ipv4.addresses 192.168.x.x/24 \
ipv4.gateway 192.168.x.x \
ipv4.dns 192.168.x.x \
ipv4.method manual
# 순서대로 활성화
nmcli con up ens160.10
nmcli con up ens160.20
nmcli con up bond-slave-1
nmcli con up bond-slave-2
nmcli con up bond0
결과 확인
cat /proc/net/bonding/bond0
Bonding Mode: fault-tolerance (active-backup)
Currently Active Slave: ens160.10
MII Status: up
Slave Interface: ens160.10 -> MII Status: up
Slave Interface: ens160.20 -> MII Status: up
두 슬레이브가 모두 up 상태이고 ens160.10이 활성으로 동작 중인 것을 확인할 수 있다.
장애 전환 테스트
# 활성 슬레이브 강제 다운
nmcli con down bond-slave-1
# ens160.20으로 자동 전환 확인
cat /proc/net/bonding/bond0
# Currently Active Slave: ens160.20 으로 변경되면 성공
오늘 실습 요약
항목 내용
| DNS | BIND 설치, Zone 파일 생성, MX 레코드 등록 |
| Postfix | SMTP 설정, SASL 인증, Dovecot 연동 |
| Dovecot | POP3/IMAP 설정, Postfix 인증 소켓 연동 |
| 트러블슈팅 | transport_maps로 메일 큐 문제 해결 |
| Roundcube | 웹메일 설치 및 MariaDB 연동 |
| Bonding | VLAN 우회로 active-backup 모드 구성 |
'리눅스' 카테고리의 다른 글
| Rocky Linux DNS 서버 구축 후 브라우저에서 도메인이 안 열릴 때 해결법 (0) | 2026.04.02 |
|---|---|
| [Linux] 리눅스 6주차 DNS, Apache, Nginx, SSL 수업정리 (0) | 2026.03.13 |
| [Linux: 5주차 2차시] Linux 네트워크 서비스 학습 정리 (Samba & DHCP 실습 트러블슈팅) (0) | 2026.02.13 |
| [Linux] 맥북 VMware Fusion에서 Port Forwarding 설정 완벽 가이드 (0) | 2026.02.03 |
| [Linux] 4주차 수업 정리 (디스크 쿼터, 백업, 방화벽, 쉘 스크립트) (0) | 2026.02.03 |