리눅스

[Linux 7주차 수업정리] Linux 메일 서버 + NIC Bonding 구축 실습 정리

palantirops 2026. 3. 8. 17:43

실습 환경

  • 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 등)

메일 전송 흐름은 다음과 같다.

  1. 사용자가 메일 발송
  2. 발신 메일 서버가 DNS 조회
  3. 수신 도메인의 MX 레코드 확인
  4. MX 레코드에 지정된 메일 서버 확인
  5. 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 모드 구성