Postfix 설정 · 5 min read · Oct 07, 2025
Postfix, Courier 및 MySQL을 이용한 가상 사용자 및 도메인 (Debian Etch) - 페이지 2
4 Postfix/Courier를 위한 MySQL 데이터베이스 생성
기본적으로 MySQL은 루트 비밀번호 없이 설치되며, 우리는 즉시 이를 변경합니다 (yourrootsqlpassword를 원하는 비밀번호로 교체):
mysqladmin -u root password yourrootsqlpassword이제 mail이라는 데이터베이스를 생성합니다:
mysqladmin -u root -p create mail다음으로 MySQL 셸로 이동합니다:
mysql -u root -pMySQL 셸에서 mail 데이터베이스에 대해 SELECT, INSERT, UPDATE, DELETE 권한을 가진 mail_admin 사용자(비밀번호는 mail_admin_password로 교체)를 생성합니다. 이 사용자는 Postfix와 Courier가 메일 데이터베이스에 연결하는 데 사용됩니다:
GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost' IDENTIFIED BY 'mail_admin_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost.localdomain' IDENTIFIED BY 'mail_admin_password';
FLUSH PRIVILEGES;여전히 MySQL 셸에서 Postfix와 Courier가 필요로 하는 테이블을 생성합니다:
USE mail;CREATE TABLE domains (
domain varchar(50) NOT NULL,
PRIMARY KEY (domain) )
TYPE=MyISAM;CREATE TABLE forwardings (
source varchar(80) NOT NULL,
destination TEXT NOT NULL,
PRIMARY KEY (source) )
TYPE=MyISAM;CREATE TABLE users (
email varchar(80) NOT NULL,
password varchar(20) NOT NULL,
quota INT(10) DEFAULT '10485760',
PRIMARY KEY (email)
) TYPE=MyISAM;CREATE TABLE transport (
domain varchar(128) NOT NULL default '',
transport varchar(128) NOT NULL default '',
UNIQUE KEY domain (domain)
) TYPE=MyISAM;quit;여러분이 알았듯이, quit; 명령으로 MySQL 셸을 종료하고 리눅스 셸로 돌아왔습니다.
domains 테이블은 Postfix가 이메일을 수신해야 하는 각 가상 도메인을 저장합니다 (예: example.com).
| domain |
| example.com |
forwardings 테이블은 하나의 이메일 주소를 다른 이메일 주소로 별칭을 지정하는 데 사용됩니다. 예를 들어, [email protected]의 이메일을 [email protected]로 전달합니다.
| source | destination |
| [email protected] | [email protected] |
users 테이블은 모든 가상 사용자(즉, 이메일 주소, 이메일 주소와 사용자 이름이 동일하기 때문에)와 비밀번호( 암호화된 형태!) 및 각 메일 박스에 대한 쿼터 값을 저장합니다 (이 예제에서 기본 값은 10485760 바이트로, 이는 10MB를 의미합니다).
| password | quota | |
| [email protected] | No9.E4skNvGa. (암호화된 형태의 “비밀“) | 10485760 |
transport 테이블은 선택 사항이며, 고급 사용자용입니다. 이는 단일 사용자, 전체 도메인 또는 모든 메일을 다른 서버로 전달할 수 있게 해줍니다. 예를 들어,
| domain | transport |
| example.com | smtp:[1.2.3.4] |
는 example.com의 모든 이메일을 smtp 프로토콜을 통해 IP 주소 1.2.3.4의 서버로 전달합니다 (대괄호 []는 “MX DNS 레코드를 조회하지 마십시오”를 의미합니다 (IP 주소에 대해 의미가 있습니다…). 대신 완전한 도메인 이름(FQDN)을 사용하면 대괄호를 사용하지 않습니다.).
그런데 (여러분의 메일 서버 시스템의 IP 주소가 192.168.0.100이라고 가정합니다) 브라우저에서 http://192.168.0.100/phpmyadmin/를 통해 phpMyAdmin에 접근하고 mail_admin으로 로그인할 수 있습니다. 그러면 데이터베이스를 살펴볼 수 있습니다. 나중에 phpMyAdmin을 사용하여 메일 서버를 관리할 수 있습니다.
5 Postfix 구성
이제 Postfix에 데이터베이스에서 모든 정보를 찾을 수 있는 위치를 알려줘야 합니다. 따라서 여섯 개의 텍스트 파일을 생성해야 합니다. Postfix에 localhost 대신 IP 주소 127.0.0.1에 연결하도록 지시하는 것을 알 수 있습니다. 이는 Postfix가 chroot 감옥에서 실행되고 MySQL 소켓에 접근할 수 없기 때문입니다. 만약 Postfix에 localhost를 사용하라고 지시하면 MySQL에 연결하려고 시도할 것입니다. 127.0.0.1을 사용하면 Postfix는 TCP 네트워킹을 사용하여 MySQL에 연결하며, 이는 chroot 감옥에서도 문제가 없습니다 (대안은 MySQL 소켓을 chroot 감옥으로 이동하는 것이며, 이는 다른 문제를 일으킵니다).
/etc/mysql/my.cnf에 다음 줄이 포함되어 있는지 확인하십시오:
vi /etc/mysql/my.cnf| [...] bind-address = 127.0.0.1 [...] |
/etc/mysql/my.cnf를 수정해야 했다면, 지금 MySQL을 재시작하십시오:
/etc/init.d/mysql restart다음 명령을 실행하여 MySQL이 127.0.0.1 (localhost.localdomain)에서 수신 대기하고 있는지 확인하십시오:
netstat -tapserver1:/usr/src# netstat -tap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 localhost.localdo:mysql *:* LISTEN 3003/mysqld
tcp 0 0 *:sunrpc *:* LISTEN 1684/portmap
tcp 0 0 *:auth *:* LISTEN 2036/inetd
tcp 0 0 *:1522 *:* LISTEN 2077/rpc.statd
tcp 0 0 *:smtp *:* LISTEN 12053/master
tcp6 0 0 *:imaps *:* LISTEN 3839/couriertcpd
tcp6 0 0 *:pop3s *:* LISTEN 3629/couriertcpd
tcp6 0 0 *:pop3 *:* LISTEN 3572/couriertcpd
tcp6 0 0 *:imap2 *:* LISTEN 3792/couriertcpd
tcp6 0 0 *:www *:* LISTEN 3712/apache2
tcp6 0 0 *:ssh *:* LISTEN 2058/sshd
tcp6 0 148 server1.example.com:ssh ::ffff:192.168.0.2:4515 ESTABLISHED2139/0이제 여섯 개의 텍스트 파일을 생성합시다.
vi /etc/postfix/mysql-virtual_domains.cf| user = mail_admin password = mail_admin_password dbname = mail query = SELECT domain AS virtual FROM domains WHERE domain='%s' hosts = 127.0.0.1 |
vi /etc/postfix/mysql-virtual_forwardings.cf| user = mail_admin password = mail_admin_password dbname = mail query = SELECT destination FROM forwardings WHERE source='%s' hosts = 127.0.0.1 |
vi /etc/postfix/mysql-virtual_mailboxes.cf| user = mail_admin password = mail_admin_password dbname = mail query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s' hosts = 127.0.0.1 |
vi /etc/postfix/mysql-virtual_email2email.cf| user = mail_admin password = mail_admin_password dbname = mail query = SELECT email FROM users WHERE email='%s' hosts = 127.0.0.1 |
vi /etc/postfix/mysql-virtual_transports.cf| user = mail_admin password = mail_admin_password dbname = mail query = SELECT transport FROM transport WHERE domain='%s' hosts = 127.0.0.1 |
vi /etc/postfix/mysql-virtual_mailbox_limit_maps.cf| user = mail_admin password = mail_admin_password dbname = mail query = SELECT quota FROM users WHERE email='%s' hosts = 127.0.0.1 |
그런 다음 이러한 파일의 권한과 그룹을 변경합니다:
chmod o= /etc/postfix/mysql-virtual_*.cf
chgrp postfix /etc/postfix/mysql-virtual_*.cf이제 /home/vmail의 홈 디렉토리를 가진 vmail이라는 사용자와 그룹을 생성합니다. 여기에서 모든 메일 박스가 저장됩니다.
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /home/vmail -m다음으로 Postfix 구성을 진행합니다. 반드시 server1.example.com을 유효한 FQDN으로 교체하십시오. 그렇지 않으면 Postfix가 제대로 작동하지 않을 수 있습니다!
postconf -e 'myhostname = server1.example.com'
postconf -e 'mydestination = server1.example.com, localhost, localhost.localdomain'
postconf -e 'mynetworks = 127.0.0.0/8'
postconf -e 'virtual_alias_domains ='
postconf -e 'virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf'
postconf -e 'virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf'
postconf -e 'virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf'
postconf -e 'virtual_mailbox_base = /home/vmail'
postconf -e 'virtual_uid_maps = static:5000'
postconf -e 'virtual_gid_maps = static:5000'
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination'
postconf -e 'smtpd_use_tls = yes'
postconf -e 'smtpd_tls_cert_file = /etc/postfix/smtpd.cert'
postconf -e 'smtpd_tls_key_file = /etc/postfix/smtpd.key'
postconf -e 'transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf'
postconf -e 'virtual_create_maildirsize = yes'
postconf -e 'virtual_maildir_extended = yes'
postconf -e 'virtual_mailbox_limit_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf'
postconf -e 'virtual_mailbox_limit_override = yes'
postconf -e 'virtual_maildir_limit_message = "The user you are trying to reach is over quota."'
postconf -e 'virtual_overquota_bounce = yes'
postconf -e 'proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps'그 후 TLS에 필요한 SSL 인증서를 생성합니다:
cd /etc/postfix
openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 365 -x509<-- 국가 이름 입력 (예: "DE").
<-- 주 또는 지방 이름 입력.
<-- 도시 입력.
<-- 조직 이름 입력 (예: 회사 이름).
<-- 조직 단위 이름 입력 (예: "IT 부서").
<-- 시스템의 완전한 도메인 이름 입력 (예: "server1.example.com").
<-- 이메일 주소 입력.그런 다음 smtpd.key의 권한을 변경합니다:
chmod o= /etc/postfix/smtpd.key새 게시물을 받은 편지함에서 받기
스팸은 없습니다. 언제든지 구독 해지 가능합니다.