우분투에 직접 메일 서버를 구축하기

Postfix, Dovecot, Rspamd, Roundcube 메일 서버 구축 작업

 

1. 사전 준비

1.1 서버 요구사항

  • OS: Ubuntu 20.04 LTS 또는 22.04 LTS
  • 최소 사양: 2 CPU, 4GB RAM, 20GB 스토리지
  • 고정 IP 주소
  • 정방향/역방향 DNS 설정 (메일 서버 IP에 대한 PTR 레코드 필수)

1.2 도메인 준비

  • 메일 서버용 도메인 확보 (예: mail.example.com)
  • 다음 DNS 레코드 설정:
    • A 레코드: mail.example.com → 서버 IP 주소
    • MX 레코드: example.com → mail.example.com (우선순위 10)
    • SPF 레코드: example.com TXT “v=spf1 mx a ip4:서버IP -all”
    • DKIM/DMARC 레코드 (rspamd 설정 후 추가)

1.3 포트 오픈

  • 필수 포트: 25 (SMTP), 465 (SMTPS), 587 (Submission), 993 (IMAPS), 80/443 (HTTP/HTTPS)
  • 방화벽 설정:
    bash
    sudo ufw allow 22/tcp
    sudo ufw allow 25/tcp
    sudo ufw allow 465/tcp
    sudo ufw allow 587/tcp
    sudo ufw allow 993/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable

2. 시스템 기본 설정

2.1 시스템 업데이트

bash
sudo apt update
sudo apt upgrade -y
sudo apt install -y software-properties-common curl wget gnupg2 ca-certificates lsb-release apt-transport-https

2.2 호스트명 설정

bash
sudo hostnamectl set-hostname mail.example.com
echo "127.0.0.1 mail.example.com mail" | sudo tee -a /etc/hosts

2.3 시간 동기화 설정

bash
sudo apt install -y ntp
sudo systemctl enable ntp
sudo systemctl start ntp

3. SSL 인증서 설정

3.1 Certbot 설치

bash
sudo apt install -y certbot

3.2 인증서 발급

bash
sudo certbot certonly --standalone --preferred-challenges http -d mail.example.com

3.3 인증서 자동 갱신 설정

bash
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

4. Postfix 설치 및 설정

4.1 Postfix 설치

bash
sudo apt install -y postfix postfix-mysql
  • 설치 중 “Internet Site” 선택
  • 시스템 메일 이름: mail.example.com 입력

4.2 Postfix 기본 설정

bash
sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.bak

sudo bash -c 'cat > /etc/postfix/main.cf << EOF
# 기본 설정
smtpd_banner = $myhostname ESMTP $mail_name
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 2

# TLS 파라미터
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtp_tls_security_level = may
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_ciphers = high
smtp_tls_ciphers = high

# 일반 설정
myhostname = mail.example.com
myorigin = example.com
mydomain = example.com
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

# SMTP 인증 및 릴레이
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

# 메일함 설정
virtual_transport = lmtp:unix:private/dovecot-lmtp
virtual_mailbox_domains = example.com
virtual_mailbox_base = /var/mail/vhosts
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_minimum_uid = 100
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

# Rspamd 설정
milter_protocol = 6
milter_default_action = accept
smtpd_milters = inet:127.0.0.1:11332
non_smtpd_milters = inet:127.0.0.1:11332
EOF'

4.3 Postfix 가상 메일박스 설정

bash
sudo mkdir -p /var/mail/vhosts/example.com
sudo groupadd -g 5000 vmail
sudo useradd -g vmail -u 5000 vmail -d /var/mail/vhosts -m
sudo chown -R vmail:vmail /var/mail/vhosts

sudo bash -c 'cat > /etc/postfix/vmailbox << EOF
user1@example.com example.com/user1/
user2@example.com example.com/user2/
EOF'

sudo postmap /etc/postfix/vmailbox

4.4 Postfix master.cf 설정

bash
sudo cp /etc/postfix/master.cf /etc/postfix/master.cf.bak

sudo bash -c 'cat > /etc/postfix/master.cf << EOF
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
# ==========================================================================
smtp inet n - y - - smtpd
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
pickup unix n - y 60 1 pickup
cleanup unix n - y - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - y 1000? 1 tlsmgr
rewrite unix - - y - - trivial-rewrite
bounce unix - - y - 0 bounce
defer unix - - y - 0 bounce
trace unix - - y - 0 bounce
verify unix - - y - 1 verify
flush unix n - y 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - y - - smtp
relay unix - - y - - smtp
showq unix n - y - - showq
error unix - - y - - error
retry unix - - y - - error
discard unix - - y - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
anvil unix - - y - 1 anvil
scache unix - - y - 1 scache
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
EOF'

5. Dovecot 설치 및 설정

5.1 Dovecot 설치

bash
sudo apt install -y dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql

5.2 Dovecot 기본 설정

bash
sudo cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.bak

sudo bash -c 'cat > /etc/dovecot/dovecot.conf << EOF
# Dovecot 기본 설정
protocols = imap lmtp
listen = *
mail_privileged_group = mail
mail_location = maildir:/var/mail/vhosts/%d/%n

# 디렉토리 설정
mail_home = /var/mail/vhosts/%d/%n

# 사용자 설정
first_valid_uid = 5000
first_valid_gid = 5000

# SSL 설정
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2
ssl_prefer_server_ciphers = yes

# 인증 설정
auth_mechanisms = plain login
disable_plaintext_auth = yes
auth_username_format = %n
EOF'

5.3 Dovecot 서비스 설정

bash
sudo cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.bak

sudo bash -c 'cat > /etc/dovecot/conf.d/10-master.conf << EOF
service imap-login {
inet_listener imap {
port = 0
}
inet_listener imaps {
port = 993
ssl = yes
}
}

service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}

service imap {
}

service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}

unix_listener auth-userdb {
mode = 0600
user = vmail
group = vmail
}

user = dovecot
}

service auth-worker {
user = vmail
}
EOF'

5.4 Dovecot 메일 설정

bash
sudo cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.bak

sudo bash -c 'cat > /etc/dovecot/conf.d/10-mail.conf << EOF
mail_location = maildir:/var/mail/vhosts/%d/%n
namespace inbox {
inbox = yes
}

mail_privileged_group = mail
first_valid_uid = 5000
first_valid_gid = 5000

mail_home = /var/mail/vhosts/%d/%n
EOF'

5.5 Dovecot 인증 설정

bash
sudo cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.bak

sudo bash -c 'cat > /etc/dovecot/conf.d/10-auth.conf << EOF
auth_mechanisms = plain login
disable_plaintext_auth = yes
auth_username_format = %n

!include auth-passwdfile.conf.ext
EOF'

5.6 Dovecot 비밀번호 파일 설정

bash
sudo mkdir -p /etc/dovecot/private
sudo touch /etc/dovecot/private/passwd
sudo bash -c 'cat > /etc/dovecot/conf.d/auth-passwdfile.conf.ext << EOF
passdb {
driver = passwd-file
args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/private/passwd
}

userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}
EOF'

# 사용자 추가 (비밀번호는 적절히 변경)
sudo bash -c "echo 'user1@example.com:{SHA512-CRYPT}password_hash:5000:5000::/var/mail/vhosts/example.com/user1::' > /etc/dovecot/private/passwd"
sudo bash -c "echo 'user2@example.com:{SHA512-CRYPT}password_hash:5000:5000::/var/mail/vhosts/example.com/user2::' >> /etc/dovecot/private/passwd"

# passwd 파일 권한 설정
sudo chown dovecot:dovecot /etc/dovecot/private/passwd
sudo chmod 600 /etc/dovecot/private/passwd

6. Rspamd 설치 및 설정

6.1 Rspamd 저장소 추가 및 설치

bash
sudo apt install -y lsb-release wget gnupg2
CODENAME=`lsb_release -c -s`
wget -O- https://rspamd.com/apt-stable/gpg.key | sudo apt-key add -
echo "deb [arch=amd64] http://rspamd.com/apt-stable/ $CODENAME main" | sudo tee /etc/apt/sources.list.d/rspamd.list
sudo apt update
sudo apt install -y rspamd redis-server

6.2 Rspamd 기본 설정

bash
sudo mkdir -p /etc/rspamd/local.d/
sudo mkdir -p /etc/rspamd/override.d/

# 로컬 설정
sudo bash -c 'cat > /etc/rspamd/local.d/worker-proxy.inc << EOF
bind_socket = "127.0.0.1:11332";
EOF'

sudo bash -c 'cat > /etc/rspamd/local.d/redis.conf << EOF
servers = "127.0.0.1";
EOF'

sudo bash -c 'cat > /etc/rspamd/local.d/logging.inc << EOF
level = "info";
type = "file";
filename = "/var/log/rspamd/rspamd.log";
EOF'

# DKIM 설정
sudo mkdir -p /var/lib/rspamd/dkim
sudo bash -c 'cat > /etc/rspamd/local.d/dkim_signing.conf << EOF
domain {
example.com {
path = "/var/lib/rspamd/dkim/example.com.key";
selector = "dkim";
}
}
EOF'

# DKIM 키 생성
sudo rspamadm dkim_keygen -s dkim -b 2048 -d example.com -k /var/lib/rspamd/dkim/example.com.key > /tmp/example.com.dkim.txt
sudo chown -R _rspamd:_rspamd /var/lib/rspamd/dkim
sudo chmod 440 /var/lib/rspamd/dkim/example.com.key

6.3 DKIM, DMARC DNS 설정 안내 생성

bash
echo "DNS 설정에 아래의 TXT 레코드를 추가하세요:"
echo "DKIM 레코드:"
cat /tmp/example.com.dkim.txt
echo ""
echo "DMARC 레코드:"
echo "_dmarc.example.com. IN TXT \"v=DMARC1; p=quarantine; rua=mailto:postmaster@example.com\""

7. Roundcube 설치 및 설정

7.1 필수 패키지 설치

bash
sudo apt install -y apache2 php php-fpm php-mysql php-mbstring php-xml php-curl php-zip php-gd php-intl php-imagick mariadb-server

7.2 MariaDB 설정

bash
sudo mysql_secure_installation
sudo mysql -e "CREATE DATABASE roundcube CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mysql -e "CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'StrongPassword';"
sudo mysql -e "GRANT ALL PRIVILEGES ON roundcube.* TO 'roundcube'@'localhost';"
sudo mysql -e "FLUSH PRIVILEGES;"

7.3 Roundcube 다운로드 및 설치

bash
cd /tmp
wget https://github.com/roundcube/roundcubemail/releases/download/1.6.0/roundcubemail-1.6.0-complete.tar.gz
tar -xvzf roundcubemail-1.6.0-complete.tar.gz
sudo mv roundcubemail-1.6.0 /var/www/roundcube
sudo chown -R www-data:www-data /var/www/roundcube

7.4 Roundcube 설정

bash
cd /var/www/roundcube/config
sudo cp config.inc.php.sample config.inc.php

# 설정 파일 편집
sudo sed -i "s|\$config\['db_dsnw'\] =.*|\$config\['db_dsnw'\] = 'mysql://roundcube:StrongPassword@localhost/roundcube';|" config.inc.php
sudo sed -i "s|\$config\['default_host'\] =.*|\$config\['default_host'\] = 'localhost';|" config.inc.php
sudo sed -i "s|\$config\['smtp_server'\] =.*|\$config\['smtp_server'\] = 'localhost';|" config.inc.php
sudo sed -i "s|\$config\['smtp_port'\] =.*|\$config\['smtp_port'\] = 587;|" config.inc.php
sudo sed -i "s|\$config\['smtp_user'\] =.*|\$config\['smtp_user'\] = '%u';|" config.inc.php
sudo sed -i "s|\$config\['smtp_pass'\] =.*|\$config\['smtp_pass'\] = '%p';|" config.inc.php
sudo sed -i "s|\$config\['des_key'\] =.*|\$config\['des_key'\] = '$(openssl rand -base64 24)';|" config.inc.php

7.5 Roundcube 데이터베이스 초기화

bash
cd /var/www/roundcube
sudo mysql roundcube < SQL/mysql.initial.sql

7.6 Apache 가상 호스트 설정

bash
sudo bash -c 'cat > /etc/apache2/sites-available/roundcube.conf << EOF
<VirtualHost *:80>
ServerName mail.example.com
DocumentRoot /var/www/roundcube
ErrorLog ${APACHE_LOG_DIR}/roundcube_error.log
CustomLog ${APACHE_LOG_DIR}/roundcube_access.log combined

<Directory /var/www/roundcube>
Options -Indexes
AllowOverride All
Require all granted
</Directory>

Redirect permanent / https://mail.example.com/
</VirtualHost>

<VirtualHost *:443>
ServerName mail.example.com
DocumentRoot /var/www/roundcube
ErrorLog ${APACHE_LOG_DIR}/roundcube_error.log
CustomLog ${APACHE_LOG_DIR}/roundcube_access.log combined

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/mail.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mail.example.com/privkey.pem

<Directory /var/www/roundcube>
Options -Indexes
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
EOF'

sudo a2ensite roundcube.conf
sudo a2enmod ssl rewrite
sudo systemctl restart apache2

8. 서비스 활성화 및 시작

bash
sudo systemctl enable postfix dovecot rspamd redis-server apache2
sudo systemctl restart postfix dovecot rspamd redis-server apache2

9. 테스트 및 검증

9.1 서비스 상태 확인

bash
sudo systemctl status postfix
sudo systemctl status dovecot
sudo systemctl status rspamd
sudo systemctl status apache2

9.2 로그 확인

bash
sudo tail -f /var/log/mail.log
sudo tail -f /var/log/rspamd/rspamd.log
sudo tail -f /var/log/apache2/roundcube_error.log

9.3 SMTP 연결 테스트

bash
telnet localhost 25
openssl s_client -connect localhost:465
openssl s_client -connect localhost:587 -starttls smtp

9.4 IMAP 연결 테스트

bash
openssl s_client -connect localhost:993

9.5 메일 전송 테스트

10. 보안 강화 설정

10.1 Fail2ban 설치 및 설정

bash
sudo apt install -y fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

sudo bash -c 'cat > /etc/fail2ban/jail.d/mail-auth.conf << EOF
[postfix]
enabled = true
port = smtp,submission,smtps
filter = postfix
logpath = /var/log/mail.log
maxretry = 5
findtime = 600
bantime = 3600

[dovecot]
enabled = true
port = imap,imaps
filter = dovecot
logpath = /var/log/mail.log
maxretry = 5
findtime = 600
bantime = 3600
EOF'

sudo systemctl restart fail2ban

10.2 추가 보안 설정

  • 암호화 강화 및 불필요한 서비스 비활성화
bash
sudo apt purge -y xinetd telnet rsh-server
sudo apt autoremove -y

11. 관리 및 백업 설정

11.1 로그 로테이션 설정

bash
sudo bash -c 'cat > /etc/logrotate.d/mail-logs << EOF
/var/log/mail.* {
daily
rotate 14
compress
delaycompress
notifempty
missingok
create 0640 syslog adm
postrotate
reload rsyslog >/dev/null 2>&1 || true
endscript
}
EOF'

11.2 백업 스크립트 설정

bash
sudo bash -c 'cat > /usr/local/bin/mail-backup.sh << EOF
#!/bin/bash
# 날짜 포맷 설정
DATE=$(date +%Y-%m-%d)
BACKUP_DIR=/var/backups/mail
MAIL_DIR=/var/mail/vhosts
CONFIG_DIRS="/etc/postfix /etc/dovecot /etc/rspamd /etc/letsencrypt"

# 백업 디렉토리 생성
mkdir -p $BACKUP_DIR/$DATE

# 설정 파일 백업
for dir in $CONFIG_DIRS; do
tar -czf $BACKUP_DIR/$DATE/$(basename $dir)_conf.tar.gz $dir
done

# 메일 데이터 백업
tar -czf $BACKUP_DIR/$DATE/mailboxes.tar.gz $MAIL_DIR

# Roundcube 데이터베이스 백업
mysqldump --single-transaction roundcube | gzip > $BACKUP_DIR/$DATE/roundcube_db.sql.gz

# 오래된 백업 삭제 (14일 이상)
find $BACKUP_DIR -type d -mtime +14 -exec rm -rf {} \\;
EOF'

sudo chmod +x /usr/local/bin/mail-backup.sh

11.3 자동 백업 설정 (Cron)

bash
sudo bash -c 'echo "0 1 * * * root /usr/local/bin/mail-backup.sh" > /etc/cron.d/mail-backup'

12. 문제해결 가이드

12.1 일반적인 문제

Postfix 문제

  • 설정 확인: sudo postconf -n
  • 로그 확인: sudo tail -f /var/log/mail.log
  • 메일 큐 확인: sudo mailq
  • 메일 큐 비우기: sudo postsuper -d ALL

Dovecot 문제

  • 설정 확인: sudo doveconf -n
  • 로그 확인: sudo tail -f /var/log/mail.log | grep dovecot
  • 테스트: sudo doveadm user user1@example.com

Rspamd 문제

  • 설정 확인: sudo rspamd -t
  • 로그 확인: sudo tail -f /var/log/rspamd/rspamd.log
  • 통계 보기: sudo rspamdadm stat

Roundcube 문제

  • 로그 확인: sudo tail -f /var/log/apache2/roundcube_error.log
  • 권한 문제: sudo chown -R www-data:www-data /var/www/roundcube
  • PHP 버전 확인: php -v

13. 유지보수 및 관리

13.1 정기 유지보수 작업

  • 시스템 업데이트: sudo apt update && sudo apt upgrade -y
  • SSL 인증서 갱신: sudo certbot renew
  • 로그 검토: sudo journalctl -u postfix,dovecot,rspamd
  • 디스크 사용량 확인: sudo df -h
  • 메일 큐 상태 확인: sudo mailq

13.2 이메일 사용자 관리

사용자 추가

bash
# 메일박스 디렉토리 생성
sudo mkdir -p /var/mail/vhosts/example.com/newuser
sudo chown -R vmail:vmail /var/mail/vhosts/example.com/newuser

# Postfix 가상 메일박스 업데이트
echo "newuser@example.com example.com/newuser/" | sudo tee -a /etc/postfix/vmailbox
sudo postmap /etc/postfix/vmailbox

# Dovecot 사용자 추가 (비밀번호 해시는 doveadm pw 명령으로 생성)
sudo doveadm pw -s SHA512-CRYPT
# 출력된 해시를 사용하여 사용자 추가
echo "newuser@example.com:{SHA512-CRYPT}생성된_해시:5000:5000::/var/mail/vhosts/example.com/newuser::" | sudo tee -a /etc/dovecot/private/passwd

사용자 삭제

bash
# Dovecot 사용자 삭제
sudo sed -i '/newuser@example.com/d' /etc/dovecot/private/passwd

# Postfix 가상 메일박스에서 삭제
sudo sed -i '/newuser@example.com/d' /etc/postfix/vmailbox
sudo postmap /etc/postfix/vmailbox

# 메일박스 삭제 (선택 사항)
sudo rm -rf /var/mail/vhosts/example.com/newuser

14. 완료 및 확인

  1. 모든 서비스가 정상적으로 실행 중인지 확인
  2. Roundcube 웹 인터페이스에 접속하여 로그인 테스트
  3. 이메일 송수신 테스트
  4. DKIM 서명 확인 테스트
  5. 스팸 필터링 테스트

 

15. 참고 사항 (계속)

  • 모든 예제 코드에서 “example.com”을 실제 도메인으로 변경해야 합니다.
  • 비밀번호 해시는 실제 값으로 대체해야 합니다. Dovecot 비밀번호 해시는 doveadm pw -s SHA512-CRYPT 명령으로 생성할 수 있습니다.
  • 방화벽 설정은 네트워크 환경에 따라 조정이 필요할 수 있습니다.
  • 메일 서버 설정은 도메인 환경에 따라 세부 조정이 필요할 수 있습니다.
  • DNS 설정은 반드시 사전에 완료되어야 하며, 변경사항이 전파되는데 시간이 걸릴 수 있습니다.

16. 성능 최적화

16.1 Postfix 성능 최적화

bash
sudo bash -c 'cat >> /etc/postfix/main.cf << EOF
# 성능 관련 설정
default_process_limit = 100
smtp_destination_concurrency_limit = 20
local_destination_concurrency_limit = 2
minimal_backoff_time = 300s
maximal_backoff_time = 3000s
EOF'

sudo systemctl restart postfix

16.2 Dovecot 성능 최적화

bash
sudo bash -c 'cat > /etc/dovecot/conf.d/15-mailboxes.conf << EOF
namespace inbox {
mailbox Drafts {
special_use = \\Drafts
auto = subscribe
}
mailbox Junk {
special_use = \\Junk
auto = subscribe
}
mailbox Trash {
special_use = \\Trash
auto = subscribe
}
mailbox Sent {
special_use = \\Sent
auto = subscribe
}
mailbox "Sent Items" {
special_use = \\Sent
}
}
EOF'

sudo bash -c 'cat > /etc/dovecot/conf.d/20-imap.conf << EOF
protocol imap {
mail_plugins = $mail_plugins imap_quota
mail_max_userip_connections = 20
}
EOF'

sudo systemctl restart dovecot

16.3 Rspamd 성능 최적화

bash
sudo bash -c 'cat > /etc/rspamd/local.d/worker-normal.inc << EOF
# 일반 작업자 설정
workers = 2;
EOF'

sudo bash -c 'cat > /etc/rspamd/local.d/worker-proxy.inc << EOF
# 프록시 작업자 설정
clients_max = 1024;
EOF'

sudo systemctl restart rspamd

16.4 MySQL/MariaDB 성능 최적화 (Roundcube용)

bash
sudo bash -c 'cat > /etc/mysql/mariadb.conf.d/99-mail-optimizations.cnf << EOF
[mysqld]
innodb_buffer_pool_size = 256M
query_cache_size = 32M
query_cache_limit = 2M
key_buffer_size = 64M
max_connections = 100
EOF'

sudo systemctl restart mariadb

17. 모니터링 설정

17.1 기본 모니터링 스크립트

bash
sudo bash -c 'cat > /usr/local/bin/mail-monitor.sh << EOF
#!/bin/bash
# 메일 서버 상태 모니터링 스크립트

LOG_FILE="/var/log/mail-monitor.log"
ADMIN_EMAIL="admin@example.com"

echo "$(date): 메일 서버 상태 점검 시작" >> $LOG_FILE

# 서비스 상태 점검
services=("postfix" "dovecot" "rspamd" "apache2" "mariadb" "redis-server")
failed_services=()

for service in "${services[@]}"; do
if ! systemctl is-active --quiet $service; then
failed_services+=($service)
echo "$(date): 서비스 $service 중지됨" >> $LOG_FILE
fi
done

# 디스크 사용량 점검
DISK_USAGE=$(df -h / | awk '\''NR==2 {print $5}'\'' | sed '\''s/%//'\')
if [ $DISK_USAGE -gt 90 ]; then
echo "$(date): 디스크 공간 부족 ($DISK_USAGE%)" >> $LOG_FILE
echo "디스크 공간 부족 ($DISK_USAGE%)" | mail -s "메일 서버 경고: 디스크 공간 부족" $ADMIN_EMAIL
fi

# 메일 큐 점검
QUEUE_SIZE=$(mailq | grep -c "^[A-F0-9]")
if [ $QUEUE_SIZE -gt 100 ]; then
echo "$(date): 메일 큐 크기가 큼 ($QUEUE_SIZE)" >> $LOG_FILE
echo "메일 큐 크기: $QUEUE_SIZE" | mail -s "메일 서버 경고: 큰 메일 큐" $ADMIN_EMAIL
fi

# 실패한 서비스가 있으면 알림
if [ ${#failed_services[@]} -gt 0 ]; then
echo "실패한 서비스: ${failed_services[*]}" | mail -s "메일 서버 경고: 서비스 중지됨" $ADMIN_EMAIL
# 서비스 자동 재시작 시도
for service in "${failed_services[@]}"; do
echo "$(date): $service 재시작 시도" >> $LOG_FILE
systemctl restart $service
done
fi

echo "$(date): 메일 서버 상태 점검 완료" >> $LOG_FILE
EOF'

sudo chmod +x /usr/local/bin/mail-monitor.sh
sudo bash -c 'echo "*/15 * * * * root /usr/local/bin/mail-monitor.sh" > /etc/cron.d/mail-monitor'

18. 추가 기능 설정

18.1 메일 전달 설정

bash
# 사용자 이메일 전달 설정 (예: user1@example.com → external@gmail.com)
sudo bash -c 'cat > /etc/postfix/virtual << EOF
user1@example.com external@gmail.com
EOF'

sudo postmap /etc/postfix/virtual
sudo bash -c 'echo "virtual_alias_maps = hash:/etc/postfix/virtual" >> /etc/postfix/main.cf'
sudo systemctl restart postfix

18.2 SPF, DKIM, DMARC 확인 설정

bash
sudo bash -c 'cat > /etc/rspamd/local.d/spf.conf << EOF
spf_symbols {
symbol_allow = "R_SPF_ALLOW";
symbol_deny = "R_SPF_FAIL";
symbol_softfail = "R_SPF_SOFTFAIL";
symbol_neutral = "R_SPF_NEUTRAL";
symbol_none = "R_SPF_DNSFAIL";
symbol_temperror = "R_SPF_TEMPERROR";
symbol_permerror = "R_SPF_PERMERROR";
}
EOF'

sudo bash -c 'cat > /etc/rspamd/local.d/dkim_verification.conf << EOF
try_fallback = true;
use_domain = "header";
EOF'

sudo bash -c 'cat > /etc/rspamd/local.d/dmarc.conf << EOF
actions = {
quarantine = "add_header";
reject = "reject";
}
EOF'

sudo systemctl restart rspamd

19. 보안 감사 및 강화

19.1 TLS 설정 검증

bash
# Postfix TLS 검증
sudo postconf -d | grep -i tls

# Dovecot TLS 검증
sudo doveconf -n | grep -i ssl

# 실제 TLS 연결 테스트
openssl s_client -connect mail.example.com:465 -showcerts
openssl s_client -connect mail.example.com:993 -showcerts

19.2 추가 보안 설정

bash
# AppArmor 프로필 적용
sudo apt install -y apparmor-utils
sudo aa-enforce /etc/apparmor.d/usr.sbin.dovecot
sudo aa-enforce /etc/apparmor.d/usr.sbin.postfix

# SMTP 속도 제한 설정
sudo bash -c 'cat >> /etc/postfix/main.cf << EOF
# SMTP 속도 제한
smtpd_client_message_rate_limit = 50
anvil_rate_time_unit = 60s
smtpd_client_connection_rate_limit = 20
EOF'

sudo systemctl restart postfix

20. 문서화 및 관리 가이드

20.1 관리자 문서 작성

bash
sudo bash -c 'cat > /root/mail-server-docs.md << EOF
# 메일 서버 관리자 가이드

## 서버 정보
- 호스트명: mail.example.com
- IP 주소: [서버 IP]
- OS: Ubuntu 20.04/22.04 LTS

## 설치된 구성 요소
- Postfix (SMTP 서버)
- Dovecot (IMAP 서버)
- Rspamd (스팸 필터링)
- Roundcube (웹메일)
- MariaDB (데이터베이스)
- Let\'s Encrypt SSL 인증서

## 중요 파일 위치
- Postfix 설정: /etc/postfix/
- Dovecot 설정: /etc/dovecot/
- Rspamd 설정: /etc/rspamd/
- 메일박스: /var/mail/vhosts/
- SSL 인증서: /etc/letsencrypt/live/mail.example.com/

## 일반 관리 작업
1. 사용자 추가:
\`\`\`bash
# 메일박스 생성
sudo mkdir -p /var/mail/vhosts/example.com/newuser
sudo chown -R vmail:vmail /var/mail/vhosts/example.com/newuser

# 가상 메일박스 맵 업데이트
echo "newuser@example.com example.com/newuser/" | sudo tee -a /etc/postfix/vmailbox
sudo postmap /etc/postfix/vmailbox

# 비밀번호 해시 생성
sudo doveadm pw -s SHA512-CRYPT

# 사용자 추가
echo "newuser@example.com:{SHA512-CRYPT}생성된_해시:5000:5000::/var/mail/vhosts/example.com/newuser::" | sudo tee -a /etc/dovecot/private/passwd
\`\`\`

2. SSL 인증서 갱신:
\`\`\`bash
sudo certbot renew
\`\`\`

3. 로그 확인:
\`\`\`bash
sudo tail -f /var/log/mail.log
sudo tail -f /var/log/rspamd/rspamd.log
\`\`\`

4. 메일 큐 관리:
\`\`\`bash
# 큐 확인
sudo mailq

# 특정 메일 삭제
sudo postsuper -d QUEUE_ID

# 모든 메일 삭제
sudo postsuper -d ALL
\`\`\`

## 문제 해결
1. 서비스 상태 확인:
\`\`\`bash
sudo systemctl status postfix dovecot rspamd apache2
\`\`\`

2. 서비스 재시작:
\`\`\`bash
sudo systemctl restart postfix dovecot rspamd apache2
\`\`\`

3. 설정 테스트:
\`\`\`bash
sudo postfix check
sudo dovecot -n
sudo rspamd -t
\`\`\`

## 백업 및 복원
- 백업 스크립트: /usr/local/bin/mail-backup.sh
- 백업 위치: /var/backups/mail/
- 백업 내용: 설정 파일, 메일박스, 데이터베이스
- 복원 예제:
\`\`\`bash
# 설정 파일 복원
sudo tar -xzf /var/backups/mail/DATE/postfix_conf.tar.gz -C /

# 메일박스 복원
sudo tar -xzf /var/backups/mail/DATE/mailboxes.tar.gz -C /

# 데이터베이스 복원
gunzip -c /var/backups/mail/DATE/roundcube_db.sql.gz | sudo mysql roundcube
\`\`\`
EOF'

20.2 최종 확인 체크리스트

bash
# 최종 확인 스크립트
sudo bash -c 'cat > /root/final-check.sh << EOF
#!/bin/bash
echo "==== 메일 서버 설정 확인 ===="
echo ""

echo "1. 서비스 상태 확인"
systemctl status postfix dovecot rspamd apache2 mariadb redis-server | grep active

echo ""
echo "2. 포트 확인"
netstat -tulpn | grep -E ":(25|465|587|993|80|443)"

echo ""
echo "3. SSL 인증서 확인"
certbot certificates

echo ""
echo "4. DNS 레코드 확인"
dig MX example.com
dig TXT example.com
dig TXT dkim._domainkey.example.com

echo ""
echo "5. 로그 확인 (오류 메시지 검색)"
grep -i "error\|warn\|fail" /var/log/mail.log | tail -20

echo ""
echo "6. 스팜 필터 상태 확인"
rspamdadm stat

echo ""
echo "==== 확인 완료 ===="
EOF'

sudo chmod +x /root/final-check.sh