서버개발

메일서버 만들기 – 우분투 16.04LTS 기준 –

  1. postfix + dovecot + mysql 을 기준으로 만들겠습니다.

일단 공인 아이피가 필요합니다.

 

FQDN(Fully Qualified Domain Name) 을 설정하겠습니다.

sudo vim /etc/hosts 에 들어가서 다음과 같이 셋팅합니다.

127.0.0.1	localhost.localdomain	localhost
127.0.1.1	hostname.yourdomain.tld	hostname
공인아이피	hostname.yourdomain.tld	hostname
sudo hostname NEW_NAME_HERE 라고 하면 vim /etc/hostname 에서 확인할 수 있습니다.

restart 없이 적용하려면 다음과 같이 합니다.

systemctl restart systemd-logind.service (저는 안먹히네요...)

패키지를 설치합니다.

apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql

인터넷사이트를 선택합니다.

 

다음은 데이터베이스를 생성 및 설정 하도록 하겠습니다.

여기서는 데이터베이스 이름을  servermail 이라고 하겠지만, 원하는 것으로 만들어 주시면 됩니다….한글특수기호같은거 넣지마세요..:)

데이터베이스 생성합니다.

mysqladmin -p create servermail

루트 계정으로 들어갑니다.

mysql -u root -p

아래 화면이 보입니다.

mysql >

아래 처럼 디비에 접근할 유저 계정을 생성하면서  비밀번호도 같이 설정해 줍니다..

mysql > GRANT SELECT ON servermail.* TO 'usermail'@'127.0.0.1' IDENTIFIED BY 'mailpassword';

데이터베이스에 적용시킵니다.

mysql > FLUSH PRIVILEGES;

이제 DB를 사용하겠다고 명령합니다.

mysql> USE servermail;

특정 도메인을 권한 승인된 도메인으로써 인식되도록 해주는 테이블을 생성할 것입니다.

CREATE TABLE `virtual_domains` (
`id`  INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

다음은 유저정보를 갖고있는 테이블을 만들겁니다. 여기에 이메일 주소와 비밀번호를 각 유저들에게 추가할 수 있습니다.(도메인을 가진 각 유저와 연결되어야 합니다.)

CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

마지막으로 virtual aliases(가상 별칭) 테이블을 생성해서 다른 이메일로 전달하려고 하는 모든 이메일 주소를 명시할 겁니다.


CREATE TABLE `virtual_aliases` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

테이블이 잘 만들어지면 아래 처럼 Query OK 라고 뜹니다.

Virtual Domains

이제 virtual Domains 테이블에 도메인들을 넣겠습니다. 원하는 도메인을 다 넣을 수 있지만, 여기선 주도메인과 FQDN만 넣도록 하겠습니다.


INSERT INTO `servermail`.`virtual_domains`
(`id` ,`name`)
VALUES
('1', 'example.com'),
('2', 'hostname.example.com');

Virtual Emails

위의 각 도메인에 매칭되는 이메일주소와 비번을 넣을겁니다.


INSERT INTO `servermail`.`virtual_users`
(`id`, `domain_id`, `password` , `email`)
VALUES
('1', '1', ENCRYPT('firstpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email1@example.com'),
('2', '1', ENCRYPT('secondpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email2@example.com');

Virtual Aliases

이메일 주소 (source)에서 다른 이메일 주소로 포워딩 되는 정보를 넣도록 하겠습니다.


INSERT INTO `servermail`.`virtual_aliases`
(`id`, `domain_id`, `source`, `destination`)
VALUES
('1', '1', 'alias@example.com', 'email1@example.com');

다 되었으면 mysql 을 종료합니다.

 mysql > exit

Postfix 설정

Postfix 를 설정해서 SMTP 를 컨트롤하고 그 메세지들을 DB에 있는 각 유저들에게 보내겠습니다.

기본 설정 파일의 복사본을 생성해서 상황에 맞게 설정을 변경하겠습니다.

cp /etc/postfix/main.cf /etc/postfix/main.cf.orig

 

이제 설정파일을 수정합니다

 

vim /etc/postfix/main.cf

TLS 파라미터를 주석처리 하고 다른 파라미터를 설정합니다. 이튜토리얼에서는 공짜 SSL 인증서를 사용하지만, 각 개인에 맞게 설정을 변경하실 수 있습니다.


# TLS parameters
#smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
#smtpd_use_tls=yes
#smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache 
smtpd_tls_cert_file=/etc/ssl/certs/dovecot.pem
smtpd_tls_key_file=/etc/ssl/private/dovecot.pem
smtpd_use_tls=yes
smtpd_tls_auth_only = yes

이제 TLS 셋팅한 곳 아래에 다음 내용을 추가합니다.


smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination

그리고 “mydestinaion” 을 주석처리하고 “localhost”로 설정합니다. 이렇게 하면 당신의 VPS가 MySQL 테이블을 사용하도록 할 수 있습니다.


#mydestination = example.com, hostname.example.com, localhost.example.com, localhost
mydestination = localhost 

myhostname 에 당신의 FQDN이 셋팅되었는지 확인하세요.


myhostname = hostname.example.com

로컬 메일에 대해  MYSQL 테이블 안에 있는 모든 가상 도메인들로 전송되도록 다음 라인을 추가합니다.

virtual_transport = lmtp:unix:private/dovecot-lmtp

Finally, we need to add these three parameters to tell Postfix to configure the virtual domains, users and aliases.

마지막으로 가상 도메인들, 사용자, alias 를 Postfix에 설정하기 위해 다음 세 문장을 추가하세요.


virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf

다음으로 MySQL에 어떻게 접속하는지를 Postfix에 알려주기 위해 위에서 추가한 내용의 3개의 파일을 만들도록 하겠습니다.

우선  mysql-virtual-mailbox-domains.cf 파일을 생성합니다. 당신의 환경에 맞춰서 수정이 필요하다면 수정해 주세요.

 


nano /etc/postfix/mysql-virtual-mailbox-domains.cf
		
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'

재시작 해주세요.


service postfix restart

당신의 도메인을 Postfix가 찾도록 아래 명령어를 치세요. 1이면 성공입니다.


postmap -q example.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf

다음파일을 생성해 주세요. mysql-virtual-mailbox-maps.cf file


vim /etc/postfix/mysql-virtual-mailbox-maps.cf 
		
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'

리스타트 해주세요.

service postfix restart

여기서 다음 명령어를 이용해 당신이 등록한 첫번째 이메일 주소를 Postfix 가 찾게 합니다. 1을 리턴하면 성공입니다.

postmap -q email1@example.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf

마지막으로 세번째 파일을 생성하고 설정해주세요.


nano /etc/postfix/mysql-virtual-alias-maps.cf
		
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT destination FROM virtual_aliases WHERE source='%s'

Postfix 재시작해주세요.

service postfix restart

alias를 찾도록 해주세요.

postmap -q alias@example.com mysql:/etc/postfix/mysql-virtual-alias-maps.cf

보안이 적용된 587 포트를 이용하고 싶다면, 다음 파일을 수정해주세요. /etc/postfix/master.cf file


nano /etc/postfix/master.cf

다음 주석을 풀고 다른 파라미터들을 추가해주세요.


submission inet n       -       -       -       -       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

어떤 경우에는 587 포트가 open 된걸 확인하기 위해 Postfix를 다시 시작해야 할 수 있습니다.

service postfix restart

방화벽을 열어주세요.


ufw allow postfix

ufw allow 587

ufw allow 25

ufw allow ssh

ufw enable

잘모르시면 ufw disable 해도 됩니다. ( 방화벽을 내리는 것입니다. ㅋ)

 

Step 4: Dovecot 설정

7개의 파일을 수정할 것입니다. 복사본을 만들어두고 작업하겠습니다.


cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig
cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.orig
cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.orig
cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.orig

설정 파일을 수정합니다.

vim /etc/dovecot/dovecot.conf

아래 코드가 주석이 풀려있어야 합니다.

!include conf.d/*.conf

프로토콜을 사용가능하도록 다음 라인에  만듭니다. ( 원한다면 ‘pop3’ 도 추가하세요. )


!include_try /usr/share/dovecot/protocols.d/*.protocol
protocols = imap lmtp

메인 설정 파일을 수정하겠습니다.

vim /etc/dovecot/conf.d/10-mail.conf

다음 라인을 찾아서 ‘mail_location‘, 주석을 풀고 다음 파라미터를 넣어주세요.

mail_location = maildir:/var/mail/vhosts/%d/%n

'mail_privileged_group‘ 라인을 찾아서 주석을 풀고, mail 파라미터를 아래와 같이 추가하세요. (/var/mail 이라는 공간을 사용한다는 의미입니다.)

mail_privileged_group = mail 

 Verify permissions

다음 명령어를 넣어보세요.


ls -ld /var/mail

아래와 같이 출력되는지 확인해보세요.

drwxrwsr-x 3 root vmail 4096 Jan 24 21:23 /var/mail

 또는 drwxrwsr-x 3 root mail 4096 Jan 24 21:23 /var/mail

mysql 에서 우리가 등록한 각 도메인의 이름으로 폴더를 만들겠습니다.

mkdir -p /var/mail/vhosts/example.com

Id값이 5000인 vmail 유저를 생성하고 추가합니다.


groupadd -g 5000 vmail 
useradd -g vmail -u 5000 vmail -d /var/mail

그리고 권한을 수정해줍니다.

chown -R vmail:vmail /var/mail

이제 다음 파일을 수정합시다 :  /etc/dovecot/conf.d/10-auth.conf

nano /etc/dovecot/conf.d/10-auth.conf

주석을 풀어줍니다.

disable_plaintext_auth = yes

auth_mechanisms 를 아래와 같이 수정해주세요.

auth_mechanisms = plain login

주석처리해주시고,

#!include auth-system.conf.ext

mysql 을 이용하기 위해 아래 주석을 풀어주세요.

!include auth-sql.conf.ext

이 파일로 연결되도록 auth-sql.conf 파일을 수정합니다. :  /etc/dovecot/dovecot-sql.conf.ext

nano /etc/dovecot/conf.d/auth-sql.conf.ext

파일 내용이 다음 내용으로 되어있어야 합니다(이 부분을 주의해서 처리하세요. 저도 실수해서 고생했습니다.):


passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = static
  args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

(기존에는 userdb{ driver = sql ... } 으로 되어있습니다. 주석처리하고 맨 아래 주석을 풀고 수정하면 되겠습니다. 

우리의 DB 정보를 dovecot 에 연결시키기 위해서 설정파일을 수정합니다:

nano /etc/dovecot/dovecot-sql.conf.ext

다음 부분을 주석 해제하고 넣어주세요.

driver = mysql

다음 부분을 주석 해제하고 위에서 작성한 내용으로 넣어주세요.:

connect = host=127.0.0.1 dbname=servermail user=usermail password=mailpassword

다음을 주석 해제하고 기입해주세요.

default_pass_scheme = SHA512-CRYPT

아래 정보를 찾아서 기입해주세요.

password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

파일 소유자를 바꿔주세요.:


chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot 

아래 파일을 조심스럽게 변경해주세요.


nano /etc/dovecot/conf.d/10-master.conf

 주석을 해제하시고 port 를 0으로 바꿔주세요.
service imap-login {
  inet_listener imap {
    port = 0
}

#Create LMTP socket and this configurations
service lmtp {
   unix_listener /var/spool/postfix/private/dovecot-lmtp {
	   mode = 0600
	   user = postfix
	   group = postfix
   }
  #inet_listener lmtp {
    # Avoid making LMTP visible for the entire internet
    #address =
    #port =
  #}
} 

아래 내용과 같이 수정해주세요.:


service auth {

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

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

  #unix_listener /var/spool/postfix/private/auth {
  # mode = 0666
  #}

  user = dovecot
}

service auth-worker {
  # Auth worker process is run as root by default, so that it can access
  # /etc/shadow. If this isn't necessary, the user should be changed to
  # $default_internal_user.
  user = vmail
}

SSL 설정파일을 건드리도록 하겠습니다.(SSL을 사용하지 않을것이라면 아래 를 건너 뛰셔도 됩니다.)

# nano /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = </etc/ssl/certs/dovecot.pem ssl_key = </etc/ssl/private/dovecot.pem

재시작해주세요.

service dovecot restart

993번 포트가 잘 동작하는지 확인해 보세요. ( pop3를 켯다면 995포트도 체크해주세요.)

(ufw allow telnet) 을 해주어서 telnet 포트를 허용해주세요.

telnet example.com 993

여기서 telnet: Unable to connect to remote host: Connection refused 라고 뜨면,

vim /var/syslog 를 봅니다.

저의 경우 init: dovecot main process (21434) terminated with status 89 가 떳습니다.

제대로 확인하기 위해, vim /etc/dovecot/conf.d/10-logging.conf 를 열고

log_path = /var/log/dovecotlog
mail_debug = yes auth_verbose = yes
auth_debug = yes
auth_debug_passwords = yes
auth_verbose_passwords = yes

이렇게 해주면, 디버그 정보가 나옵니다.
그런데 service dovecot restart 를 해도 여전히 로그도 안나온다면, 
다음과 같이 강제로 실행을 시켜줘 봅니다.
dovecot -c /etc/dovecot/dovecot.conf 그랬더니 드디어 에러가 보입니다. 결국 ssl 인증서가 없어서 에러가 났던거군요. 
일단 그럼 임시적으로 인증서를 옮겨놓아보겠습니다. 
돌아가긴 하는 것 처럼 보였는데, 여전히 안되는것 같습니다.
다시 로그를 확인해봐야겠습니다.


아하~ 에러를 확인 결과,
이미 Dovecot이 동작하고 있었군요....
그런데 이게 강제로 실행한 것이기에 일단 PID를 죽이고 service를 이용해 다시 동작시키겠습니다.

kill 22912 service dovecot restart

 
드디어 정상적으로 stop -> start 가 되네요.
* 위에 에러가 발생했던 이유는 dovecot이 993포트를 이용하고 있어야 telnet으로 접속이 되는데,
993포트를 사용하지 않고있어서 에러가 났었습니다.
다시 telnet example.com 993 을 시도합니다. 이번엔 접속이 되었다가 바로 끊어집니다.
다시 로그를 확인해본 결과 인증서를 대충 아무거나 꽂아줘서 문제가 발생했습니다.
 진짜 SSL을 가져와야 할 때 인것 같습니다.
https://community.letsencrypt.org/t/simple-guide-using-lets-encrypt-ssl-certs-with-dovecot/2921 
여기를 참고 했습니다. SSL을 변경해 주고 해당 Cert위치를 10-ssl.conf 파일에 설정합니다.
ssl_cert = </etc/letsencrypt/live/your.server.toplevel/fullchain.pem
ssl_key = </etc/letsencrypt/live/your.server.toplevel/privkey.pem
dovecot을 재시작합니다. 로그 확인해서 아무 문제가 없는 것을 확인 합니다.(vim /var/log/dovecotlog)
service dovecot restart



축하합니다. 이제 아웃룩으로 연결을 설정해서 테스트 해보십시요.

- Username: email1@example.com
- Password: email1's password
- IMAP: example.com
- SMTP: example.com

Note: use port 993 for secure IMAP and port 587 or 25 for SMTP.

 

Step 5: SpamAssassin (스팸 암살자) 설정

우선 설치합니다.

apt-get install spamassassin spamc

스팸제거용 유저를 생성합니다.

adduser spamd --disabled-login

환경설정을 해줍니다..

nano /etc/default/spamassassin

데몬을 띄울 수 있도록 변경합니다..

ENABLED=1

나머지 환경 설정입니다..


SPAMD_HOME="/home/spamd/"
OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SPAMD_HOME} -s ${SPAMD_HOME}spamd.log" 

PID_File 파라미터를 설정합니다.:

PIDFILE="${SPAMD_HOME}spamd.pid"

자동으로 스팸암살자가 동작되도록 크론을 설정합니다.

CRON=1

안티메일 규칙을 설정하기 위해 다음 파일을 수정합니다.

vim /etc/spamassassin/local.cf

스팸암살자는 각 이메일에 점수를 줘요. 만약 이 이메일이 5.0 보다 높다고 결정되면, 자동적으로 스팸처리합니다. 다음 규칙을 수정해서 설정을 변경할 수 있습니다.:


rewrite_header Subject ***** SPAM _SCORE_ *****
report_safe             0
required_score          5.0
use_bayes               1
use_bayes_rules         1
bayes_auto_learn        1
skip_rbl_checks         0
use_razor2              0
use_dcc                 0
use_pyzor               0

Postfix 설정을 변경합시다.
/etc/postfix/master.cf
위 설정에서 각 메일을 스팸암살자가 체크하게 해줍니다.


다음 위치를 찾으실 수 있으실 겁니다. 그럼 스팸 암살자를 사용하도록 설정해 주세요.:


smtp      inet  n       -       -       -       -       smtpd
-o content_filter=spamassassin

Finally we need to append the following parameters:


spamassassin unix -     n       n       -       -       pipe
user=spamd argv=/usr/bin/spamc -f -e  
/usr/sbin/sendmail -oi -f ${sender} ${recipient}

SpamAssassin , Postfix 를 재시작해주세요.
* 한가지! SSL을 설정했다면, /etc/postfix/main.cf 에 ssl 경로를 수정해 주어야 합니다.


service spamassassin start
service postfix restart

 축하합니다. 이제 설정을 마쳤습니다. DNS 서버(ex: 카페24, 가비아 등 나의 FQDN이 등록된 곳) 에 MX 레코드를 추가해주고, 아웃룩으로 테스트 해보면 될 것 같습니다.

 

여담이지만, 엄청 길죠? 저도 메일서버를 한방에 만들 거라곤 생각도 못했습니다.
일단 영문으로 된 원문 사이트를 참고하세요.
https://www.digitalocean.com/community/tutorials/how-to-configure-a-mail-server-using-postfix-dovecot-mysql-and-spamassassin

저는 저곳에 있는 내용을 수행하면서 막혔던 부분 등을 공유하려고 합니다. 뭐든 한방에 되는건 별로 없으니까요.
이렇게 말씀드리는건 저사이트에 가시면 많은 부분이 잘 설명되어 있어서 참고 하시면 도움되실 거라 생각했습니다.

댓글 남기기

This site uses Akismet to reduce spam. Learn how your comment data is processed.