6.1. MX 알고리즘

MX 레코드는 해당 호스트로 수신되는 편지를 다른 호스트로 라우팅 하도록 한다. 원격 호스트에서 다음과 같이 설정된 도메인, nobreak.com 으로 편지를 송신할 경우에 Sendmail의 동작을 알아보자.

nobreak.com.            IN      MX 10   layla.nobreak.com.
                        IN      MX 20   marie.nobreak.com.
                        IN      MX 20   suzi.nobreak.com.
  1. 로컬호스트가 해당 도메인에 대해 인증을 갖는지 확인한다.

  2. layla로 배달을 시도한다.

  3. marie 혹은 suzi로 배달을 시도한다.

  4. (3)에서 시도되지 않은 호스트로 배달을 시도한다.

  5. 자체 큐잉 후, 일정 기간동안 주기적으로 2-4의 과정을 반복한다.

흔히 갖는 잘못된 MX의 이해 중 하나는, layla가 다운되어 marie로 편지가 배달되었을 때, 편지가 marie의 메일박스에 저장 된다는 생각으로, 다수의 MX 레코드 설정을 꺼리는 경우이다. 이렇게 되면, 사용자 계정을 양쪽 호스트에 설정하여 두어야 하며, 사용자는 매번 양쪽의 계정을 모두 확인하여야 한다는 노파심 때문일텐데, 일반적으로 낮은 priority를 갖는 호스트는 큐잉서버로 동작하도록 설정하기 때문에 결국 편지는 하나의 호스트(layla)로 집결 된다. 위의 경우 marie와 suzi의 Sendmail이 다음 조건을 만족하도록 설정되어 있으면 메일 큐잉서버로 동작한다.

  1. 해당 도메인(nobreak.com)에 대한 인증을 갖지 않아야 한다.

  2. 서버는 해당 호스트로의 메일 릴레이(Relay)를 허용하여야 한다.

인증을 갖지 않아야 한다는 것은 Sendmail의 w 클래스(sendmail.cw 혹은 sendmail.cf의 Cw)에 nobreak.com 도메인이 없어야 함을 의미하고, 메일 릴레이란 수신되는 편지의 최종 배달지가 자신이 아닐 경우, 즉 인증을 갖지 않을 경우 편지를 해당 호스트로 포워딩함을 뜻한다.

근래의 몇몇 OS 배포판들은 기본적으로 Sendmail이 릴레이를 거부하도록 설정되어 있는데, 이러할 경우 해당 호스트는 큐잉서버로 동작하지 못함에 유의하자. 보통 기관의 SMTP 서버는 타인에 의한 남용을 막기위해 내부 IP(혹은 도메인)에 대해서만 릴레이를 허용하도록 설정하지만, 메일 큐잉 서버의 경우는 본 Feature를 끄거나 해당 호스트를 목적지로 하는 편지에 대해서는 릴레이를 허용하도록(이 말의 의미하는 바를 잘 모르겠다면, 모든 IP에 대해 릴레이를 허용토록 설정하라) 조정하여야 한다. (참고: Allowing controlled SMTP relaying in Sendmail 8.9)

layla의 수신 불능으로 인해 marie로 전달되는 편지는 메일큐에 저장되어 있으면서, 일정 기간(sendmail.cf에서 지정된 Timeout.queuereturn=5d 만큼)동안 주기적(Sendmail 구동시 지정된, 일반적으로 30분 -q30m)으로 배달이 시도된다. 따라서 반드시 layla만이 nobreak.com 에 대한 인증을 가져야 한다.

* layla의 /etc/sendmail.cw (Solaris: /etc/mail/sendmail.cw)
nobreak.com

marie와 suzi가 우선순위가 같다는 점에서 다음과 같은 무한루프 시나리오를 생각해 볼 수 있다. layla가 다운되었을 경우 편지는 marie(혹은 suzi)로 배달될 것이고, 해당 도메인의 큐잉서버인 marie는 다시 MX 리스트의 우선순위에 입각하여 포위딩을 시도할 것이다. 결국 편지는 suzi로 배달될 것이고 suzi 또한 이 과정을 반복한다.

정말 그럴까? 그럴수도 있다. 하지만 Sendmail은 편지를 포워딩 하기전에 해당 도메인의 MX 리스트를 파악하고, 자신의 인증된 도메인(sendmail.cw에 기록된)이 포함되어 있는지 확인한다. 만약 포함되어 있다면, 매칭되는 도메인중 가장 높은(다수가 매칭 될 수도 있기 때문에) 우선순위를 갖는 도메인을 포함하여 같거나 적은(MX 값이 큰) 레코드를 MX 리스트에서 제외한다.

nobreak.com.            IN      MX 10   layla.nobreak.com.
                        IN   MX 20   marie.nobreak.com. (제외)
                        IN   MX 20   suzi.nobreak.com.  (제외)

결국 marie의 Sendmail이 유지하는 MX 리스트에는 layla만이 남게되고, 기대한 바대로 편지는 layla가 정상운영될때 까지 큐잉된다.

nobreak.com.            IN      MX 10   layla.nobreak.com.

그러나 만약 Sendmail이 자신을 MX 리스트에서 찾지 못하면(sendmail.cw에 marie.nobreak.com 이 등록되어 있지 않으면), suzi로의 불필요한 포워딩이 발생할 것이고, 불행히 suzi 또한 같은 상황이라면, 결국 무한루프에 빠질수 있다. Sendmail은 이러한 최악의 상황을 막기위해, 최대 포워딩 횟수 제한(sendmail.cf의 MaxHopCount=17, 기본값 25)을 갖고 있으므로, 결국 marie나 suzi중 MaxHopCount에 먼저 걸리는 시스템의 관리자(postmaster)와 송신자에게 다음과 같은 내용의 오류 편지를 보내어줄 것이다.

From: Mail Delivery Subsystem <MAILER-DAEMON@marie.nobreak.com>
To: postmaster@marie.nobreak.com
Subject: Returned mail: Too many hops 26 (25 max):...

----- The following addresses had permanent fatal errors -----
<nobreak@nobreak.com>

 ----- Transcript of session follows -----
554 Too many hops 26 (25 max):...
===========================================================
Received: from suzi.nobreak.com by marie.nobreak.com ...
Received: from marie.nobreak.com by suzi.nobreak.com ...
...
Received: from suzi.nobreak.com by marie.nobreak.com ...
Received: from marie.nobreak.com by suzi.nobreak.com ...
...

다음은 단일 큐잉 시스템에서 위와같은 루프가 발생하였을 경우의 메일 메시지이다.

nobreak.com.            IN      MX 10   layla.nobreak.com.
                        IN      MX 20   marie.nobreak.com.
From: Mail Delivery Subsystem <MAILER-DAEMON@marie.nobreak.com>
To: postmaster@marie.nobreak.com
Subject: Returned mail: Local configuration error

----- The following addresses had permanent fatal errors -----
<nobreak@nobreak.com>

 ----- Transcript of session follows -----
553 marie.nobreak.com. config error: mail loops back to me (MX problem?)
554 <nobreak@nobreak.com>... Local configuration error
===========================================================
...

DNS에 등록되어 포인팅되는 호스트명을 sendmail.cw에 나열하지 않았을 경우 발생할 문제에 대해 확신할 수 없다면, alias된 모든 호스트명을 sendmail.cw 파일에 포함하기 바란다.