[365 TIP 27 호 ] Postfix 작성일자 : 2011-11-14 작성자 : slowlygo@net-farm.com ( 주 ) 넷팜 http://www. 365managed.com
목차 1. 시작하며... 1 2. 간단설치및설정... 2 1) 설치... 2 2) 기본설정... 3 (1) 도메인설정... 4 (2) 포트외부오픈... 5 (3) 인증설정... 5 3. Postfix 관리... 11 1) Postfix 구조... 11 (1) 메일수신흐름... 11 (2) 메일발신흐름... 11 2) SMTP relay와 access control... 12 3) Lookup Table... 13 4) master.cf... 14 5) qshape tool... 16
1. 시작하며 안녕하세요. 날씨가점점쌀쌀해지고있습니다. 감기조심하셔야할듯합니다. 이번호에서는 Postfix에대해알아보도록하겠습니다. Postfix는 CentOS 6.0 에서기본메일전송에이전트입니다. http://www.postfix.org/ 를방문해보시거나, 혹은 README_FILES 을대충보시면아시겠지만, 설명이예제위주로잘되어있어쉽게따라하실수있습니다. 그냥한번읽어보시면도움이될만한간단한내용으로구성하였습니다. 진행환경은 OS 는 CentOS 6.0 이며 postfix-2.6.6-2.1.el6_0.x86_64 입니다. 해당내용에문의가있으신경우, slowlygo@net-farm.com 으로메일주시면됩니다. 그럼시작해보도록하겠습니다. -1-
2. 간단설치및설정 CentOS 6.0 에서는기본메일전송에이전트이기때문에설치가되어있습니다. 1) 설치 설치는간단하게 Yum을이용해서설치하시면됩니다. [root@localhost ~]# yum -y install postfix [root@localhost ~]# rpm -ql postfix /etc/pam.d/smtp.postfix /etc/postfix /etc/postfix/access /etc/postfix/canonical /etc/postfix/generic /etc/postfix/header_checks /etc/postfix/main.cf... root@localhost ~]# /etc/init.d/postfix restart root@localhost ~]# ps aux grep postfix root 1928 0.0 0.2 61972 2712? Ss 13:44 0:00 /usr/libexec/postfix/master postfix 1930 0.0 0.2 62052 2672? S 13:44 0:00 pickup -l -t fifo -u postfix 1931 0.0 0.2 62120 2716? S 13:44 0:00 qmgr -l -t fifo -u [root@ocalhost ~]# netstat -anlp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1051/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1928/master tcp 0 0 :::22 :::* LISTEN 1051/sshd tcp 0 0 ::1:25 :::* LISTEN 1928/master Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 2 [ ACC ] STREAM LISTENING 10310 1928/master private/tlsmgr unix 2 [ ACC ] STREAM LISTENING 10314 1928/master private/rewrite... -2-
2) 기본설정 Postfix 메인설정파일은 /etc/postfix/main.cf 입니다. [root@localhost ~]# grep "^[^#]" /etc/postfix/main.cf queue_directory = /var/spool/postfix command_directory = /usr/sbin daemon_directory = /usr/libexec/postfix data_directory = /var/lib/postfix mail_owner = postfix inet_interfaces = localhost inet_protocols = all mydestination = $myhostname, localhost.$mydomain, localhost unknown_local_recipient_reject_code = 550 alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases debug_peer_level = 2 debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5 sendmail_path = /usr/sbin/sendmail.postfix newaliases_path = /usr/bin/newaliases.postfix mailq_path = /usr/bin/mailq.postfix setgid_group = postdrop html_directory = no manpage_directory = /usr/share/man sample_directory = /usr/share/doc/postfix-2.6.6/samples readme_directory = /usr/share/doc/postfix-2.6.6/readme_files 간단히외부메일전송및수신을위해서는 3가지만처리하면됩니다. ㄱ. 도메인설정ㄴ. 포트외부오픈ㄷ. 인증설정 -3-
(1) 도메인설정 설정유틸로 postconf 가있습니다. 이명령을자주사용합니다. 가장간단하게는 hostname 설정을하면됩니다. * 추가로같은네트웍대다른호스트들을신뢰할수없는경우에는 mynetworks_style=host로설정합니다. * mydestination 로컬전송되는도메인을의미합니다. * myorigin 이서버에서발송시메일에나타나는도메인을의미합니다. [root@tip ~]# postconf grep ^my mydestination = $myhostname, localhost.$mydomain, localhost mydomain = localdomain myhostname = localhost.localdomain mynetworks = 127.0.0.0/8 xxx.xxx.xxx.xxx/24 [::1]/128 [fe80::%eth0]/64 mynetworks_style = subnet myorigin = $myhostname [root@tip ~]# hostname tip.365managed.com [root@tip ~]# postconf grep ^my mydestination = $myhostname, localhost.$mydomain, localhost mydomain = 365managed.com myhostname = tip.365managed.com mynetworks = 127.0.0.0/8 xxx.xxx.xxx.xxx/27 [::1]/128 [fe80::%eth0]/64 mynetworks_style = subnet myorigin = $myhostname [root@tip ~]# postconf -e mynetworks_style=host [root@tip ~]# postconf grep ^my mydestination = $myhostname, localhost.$mydomain, localhost mydomain = 365managed.com myhostname = tip.365managed.com mynetworks = 127.0.0.1/32 xxx.xxx.xxx.xxx/32 [::1]/128 [fe80::20c:29ff:fe7d:157b%eth0]/128 mynetworks_style = host myorigin = $myhostname -4-
(2) 포트외부오픈 [root@tip ~]# netstat -antp grep master tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3806/master [root@tip ~]# postconf -e inet_interfaces=all [root@tip ~]# /etc/init.d/postfix restart postfix 종료중 : [ OK ] postfix를시작중 : [ OK ] [root@tip ~]# netstat -antp grep master tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 3896/master tcp 0 0 :::25 :::* LISTEN 3896/master (3) 인증설정 외부오픈후인증설정을하지않을경우, 릴레이서버로이용당하므로필히하셔야합니다. 아래 README 문서는보면자세히나옵니다. /usr/share/doc/postfix-2.6.6/readme-postfix-sasl-redhat.txt /usr/share/doc/postfix-2.6.6/readme_files/sasl_readme 우선어떤인증설정이가능한지확인해보겠습니다. [root@tip ~]# postconf -a cyrus dovecot [root@tip ~]# postconf grep smtpd_sasl smtpd_sasl_auth_enable = no smtpd_sasl_authenticated_header = no smtpd_sasl_exceptions_networks = smtpd_sasl_local_domain = smtpd_sasl_path = smtpd smtpd_sasl_security_options = noanonymous smtpd_sasl_tls_security_options = $smtpd_sasl_security_options smtpd_sasl_type = cyrus -5-
ㄱ. 아래내용을 main.cf 파일에추가합니다. smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination [root@tip ~]# /etc/init.d/postfix restart postfix 종료중 : [ OK ] postfix를시작중 : [ OK ] [root@tip ~]# postconf egrep 'smtpd_sasl smtpd_recipient_restrictions' smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination smtpd_sasl_auth_enable = yes smtpd_sasl_authenticated_header = no smtpd_sasl_exceptions_networks = smtpd_sasl_local_domain = smtpd_sasl_path = smtpd smtpd_sasl_security_options = noanonymous smtpd_sasl_tls_security_options = $smtpd_sasl_security_options smtpd_sasl_type = cyrus smtpd_sasl_local_domain = $myhostname 으로설정하겠습니다. [root@tip ~]# postconf -e smtpd_sasl_local_domain=\$myhostname [root@tip ~]# postconf grep smtpd_sasl smtpd_sasl_auth_enable = yes smtpd_sasl_authenticated_header = no smtpd_sasl_exceptions_networks = smtpd_sasl_local_domain = $myhostname smtpd_sasl_path = smtpd smtpd_sasl_security_options = noanonymous smtpd_sasl_tls_security_options = $smtpd_sasl_security_options smtpd_sasl_type = cyrus -6-
ㄴ. smtpd_sasl_path = smtpd 설정은인증경로를나타내고있습니다. [root@tip ~]# cat /etc/sasl2/smtpd.conf pwcheck_method: saslauthd mech_list: plain login # 참고로 pam 파일을보면 [root@tip ~]# cat /etc/pam.d/smtp.postfix #%PAM-1.0 auth include password-auth account include password-auth [root@tip ~]# cat /etc/pam.d/password-auth #%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid >= 500 quiet auth required pam_deny.so account required pam_unix.so account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 500 quiet account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 type= password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so -7-
ㄷ. pwcheck_method: saslauthd 가기본설정이므로 cyrus-sasl 설정을확인하고서비스를시작합니다. [root@tip ~]# rpm -qa grep sasl cyrus-sasl-lib-2.1.23-8.el6.x86_64 cyrus-sasl-2.1.23-8.el6.x86_64 [root@tip ~]# yum install cyrus-sasl-plain... [root@tip ~]# saslauthd -v saslauthd 2.1.23 authentication mechanisms: getpwent kerberos5 pam rimap shadow ldap [root@tip ~]# cat /etc/sysconfig/saslauthd # Directory in which to place saslauthd's listening socket, pid file, and so # on. This directory must already exist. SOCKETDIR=/var/run/saslauthd # Mechanism to use when checking passwords. Run "saslauthd -v" to get a list # of which mechanism your installation was compiled with the ablity to use. MECH=pam # Options sent to the saslauthd. If the MECH is other than "pam" uncomment the next line. # DAEMONOPTS=--user saslauth # Additional flags to pass to saslauthd on the command line. See saslauthd(8) # for the list of accepted flags. FLAGS= [root@tip ~]# /etc/init.d/saslauthd start saslauthd ( 을 ) 를시작중 : [ OK ] -8-
ㄹ. 최종간단테스트 [root@localhost ~]# telnet tip.365managed.com 25 Trying xxx.xxx.xxx.xxx.. Connected to tip.365managed.com. Escape character is '^]'. 220 tip.365managed.com ESMTP Postfix helo localhost 250 tip.365managed.com ehlo localhost 250-tip.365managed.com 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH PLAIN LOGIN 250-AUTH=PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN * mydestination 도메인수신체크 mail from:test@test.com 250 2.1.0 Ok rcpt to:slowlygo@tip.365managed.com 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> subject:test test. 250 2.0.0 Ok: queued as DE4926053B -9-
* 릴레이체크 rset 250 2.0.0 Ok mail from:test@test.com 250 2.1.0 Ok rcpt to:slowlygo@net-farm.com 554 5.7.1 <slowlygo@net-farm.com>: Relay access denied * 인증체크 rset 250 2.0.0 Ok auth plain AHNsb3dseWdvAHRlc3Q= 235 2.7.0 Authentication successful mail from:test.com 250 2.1.0 Ok rcpt to:slowlygo@net-farm.com 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> subject:test test. 250 2.0.0 Ok: queued as AF1486053B -10-
3. Postfix 관리 1) Postfix 구조 대략적인윤곽만잡아보겠습니다. 자세한사항은 http://www.postfix.org/overview.html 를참고하시면됩니다. 이미지만첨부하였습니다. (1) 메일수신흐름 (2) 메일발신흐름 -11-
2) SMTP relay 와 access control ㄱ. Postfix는 Protocol, Blacklist, Threshold 기반접근통제를할수있으며, 다른접근제한방법또한지원합니다. ㄴ. header_checks, body_checks, smtpd proxy 등을지원합니다. ㄷ. SMTP conversation 각단계상에서접근제한을할수있습니다. Restriction list name Status Effect of REJECT or DEFER result smtpd_client_restrictions Optional Reject all client commands smtpd_helo_restrictions Optional Reject HELO/EHLO information smtpd_sender_restrictions Optional Reject MAIL FROM information smtpd_recipient_restrictions Required Reject RCPT TO information smtpd_data_restrictions Optional Reject DATA command smtpd_end_of_data_restrictions Optional Reject END-OF-DATA command smtpd_etrn_restrictions Optional Reject ETRN command 단계상으로체크를하려니이용하기불편해서, smtpd_delay_reject 옵션을 default yes 로해서 RCPT TO 혹은 EXRN 명령전에한번에체크하도록설정할수도있습니다. 적용되는순서에유의할필요가있습니다. [root@tip ~]# postconf grep restrictions smtpd_client_restrictions = smtpd_data_restrictions = smtpd_end_of_data_restrictions = smtpd_etrn_restrictions = smtpd_helo_restrictions = smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination smtpd_sender_restrictions = -12-
/etc/postfix/main.cf 에아래내용을추가하고테스트를해보겠습니다. 아래는 kisarbl을사용하는예시입니다. smtpd_client_restrictions = permit_mynetworks, reject_rbl_client spamlist.or.kr 패킷을살짝잡아보면, 아래쿼리확인이가능합니다. 18:41:39.492583 IP xxx.xxx.xxx.xxx.51381 > 168.126.63.1.53: 38285+ A? Xxx.xxx.xxx.xxx.spamlist.or.kr. (45) 18:41:39.515617 IP 168.126.63.1.53 > xxx.xxx.xxx.xxx.51381: 38285 NXDomain 0/0/0 (45) * 현재네임서버가 168.126.63.1 로잡혀있습니다. 추가로 smtpd_client_restrictions 로되어있어 25 번포트접속단계에서차단되어야하는데, rcpt to 명령에서동작하는이유는 smtpd_delay_reject = yes 이기때문입니다. * 참고로메일서버운영시캐싱네임서버를운영하는것이아무래도속도향상에도움이됩니다. * 자세한내용은 http://www.postfix.org/smtpd_access_readme.html 를참고하시기바랍니다. 3) Lookup Table Postfix는접근제어, 주소재작성, 컨텐츠필터링등의정보를저장하고확인하기위해 lookup tables를이용합니다. Main.cf를보시면아시겠지만, type:table 형식으로정의됩니다. [root@tip ~]# postconf grep maps alias_maps = hash:/etc/postfix/aliases (local aliasing) header_checks = regexp:/etc/postfix/header_checks (content filtering) transport_maps = hash:/etc/postfix/transport (routing table) virtual_alias_maps = hash:/etc/postfix/virtual (address rewriting) -13-
어떤타입을지원하는지는아래와같이확인가능합니다. 관련해서는 postmap 이란명령어가있습니다. [root@tip ~]# postconf -m btree cidr environ hash ldap mysql nis pcre proxy regexp static unix Lookup tables 에 mysql 을지원하므로 MySQL 을이용할수도있습니다. 4) master.cf master.cf를 master 프로세스설정파일입니다. Postfix services 서비스를통제하는파일이라고생각하시면됩니다. 이파일을수정해서외부필터링시스템을이용할수있습니다. # service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) smtp inet n - n - - smtpd #submission inet n - n - - smtpd # -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 - n - - smtpd # -o smtpd_tls_wrappermode=yes -14-
# -o smtpd_sasl_auth_enable=yes # -o smtpd_client_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=originating #628 inet n - n - - qmqpd pickup fifo n - n 60 1 pickup cleanup unix n - n - 0 cleanup qmgr fifo n - n 300 1 qmgr #qmgr fifo n - n 300 1 oqmgr tlsmgr unix - - n 1000? 1 tlsmgr rewrite unix - - n - - trivial-rewrite bounce unix - - n - 0 bounce defer unix - - n - 0 bounce trace unix - - n - 0 bounce verify unix - - n - 1 verify flush unix n - n 1000? 0 flush proxymap unix - - n - - proxymap proxywrite unix - - n - 1 proxymap smtp unix - - n - - smtp # When relaying mail as backup MX, disable fallback_relay to avoid MX loops relay unix - - n - - smtp -o smtp_fallback_relay= # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 showq unix n - n - - showq error unix - - n - - error retry unix - - n - - error discard unix - - n - - discard local unix - n n - - local virtual unix - n n - - virtual lmtp unix - - n - - lmtp anvil unix - - n - 1 anvil scache unix - - n - 1 scache 간단히 smtp 50000 포트를추가할경우, 간단히 50000 inet n - n - - smtpd 라인을추가후 -15-
root@tip ~]# /etc/init.d/postfix reload postfix를재시작하고있습니다 : [ OK ] [root@tip ~]# telnet localhost 50000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 tip.365managed.com ESMTP Postfix 간단히설명드리면, type이 inet일경우서비스명은 host:port 와같은형식을취하는데, 50000 번이므로 50000번에 smtpd을오픈하고있으라는의미입니다. 5) qshape tool qshape 명령어를통해 queue 상태를체크할수있습니다. [root@tip ~]# yum install postfix-perl-scripts root@tip ~]# qshape head T 5 10 20 40 80 160 320 640 1280 1280+ TOTAL 0 0 0 0 0 0 0 0 0 0 0 자세한사항은 http://www.postfix.org/qshape_readme.html 를참조하시면됩니다. -- 수고많이하셨습니다. -- [ 본문서의수정및재배포를금합니다.] -16-