Sendmail은 초기 유닉스 환경부터 인터넷 이메일 라우팅의 표준으로 자리 잡은 가장 오래되고 전통적인 메일 전송 에이전트(MTA)입니다. qmail이 모듈화와 권한 분리를 지향했다면, sendmail은 단일 통합 프로세스(Monolithic) 중심의 제어 와 유연한 룰셋(Ruleset) 기반 주소 변환 을 핵심 아키텍처로 삼고 있습니다. 1. 모놀리식(Monolithic) 아키텍처 및 보안 모델 qmail이나 Postfix가 여러 개의 독립적인 작은 데몬으로 쪼개진 것과 달리, sendmail은 원칙적으로 단일 sendmail 바이너리가 수신, 라우팅, 큐 관리, 외부 발송 등의 모든 역할을 통합 수행합니다. 이러한 구조는 과거 단일 버퍼 오버플로우 취약점으로 인해 시스템의 root 권한이 완전히 탈취되는 문제를 겪었습니다. 이를 보완하기 위해 버전 8.12부터는 프로세스 실행 모드를 물리적으로 분리하는 MSP/MTA 분리 모델 을 도입했습니다. 실행 계층 데몬 역할 및 권한 동작 MSP (Message Submission Program) 로컬 콘솔 사용자나 시스템이 메일을 발송할 때 호출됩니다. root가 아닌 smmsp 계정(Setgid) 권한으로 구동되어 메일을 /var/spool/clientmqueue 에 저장한 후 로컬 MTA 데몬으로 넘깁니다. MTA (Mail Transfer Agent) 외부 네트워크에서 들어오는 25번 포트(SMTP) 통신을 수신 대기하고, 실제 라우팅 및 큐 처리를 담당합니다. 초기 바인딩을 위해 root 권한으로 실행( -bd 데몬 모드)됩니다. 2. 구성 설정 및 룰셋 엔진 (Rulesets) Sendmail 아키텍처의 가장 큰 특징이자 악명 높은 부분은 매우 복잡한 정규표현식 형태의 토큰 변환 엔진인 룰셋(Ruleset)입니다. sendmail.mc (Macro Configuration): 관리자가 사람이 읽고 수정하기 쉬운 m4 매크로 언어 형태로 작성하는 원본 설정 파일입니다. sendmail.cf (Compiled Configuration): m4 프로세서를 통해 sendmail.mc 를 컴파일하여 생성되는 최종 파일입니다. sendmail 데몬은 오직 이 기계 친화적인 파일만 읽어 들입니다. 라우팅 파이프라인: 입력된 이메일 주소는 고정된 순서의 룰셋을 거치며 재작성(Rewriting)됩니다. Ruleset 3: 모든 입력 주소의 1차 전처리 및 구문 정규화 (예: < > 괄호 분리 및 토큰화). Ruleset 0: 메일을 어떤 Mailer 를 통해 보낼지 최종 라우팅을 결정합니다. (로컬 계정인지, 원격 SMTP 서버로 보낼지 판별). Ruleset 1, 2, 4: 발신자 주소와 수신자 주소의 최종 변환 처리를 수행합니다. 3. 핵심 메시지 처리 흐름 [ 로컬 사용자 / 애플리케이션 ] [ 외부 원격 SMTP 서버 ] │ │ ▼ ▼ sendmail (MSP) sendmail (MTA 데몬) │ │ ▼ ▼ /var/spool/clientmqueue /var/spool/mqueue │ │ └──────────────┬───────────────┘ ▼ [ 주소 변환 및 라우팅 ] (Ruleset 3 -> 0) │ ┌─────────┴─────────┐ ▼ ▼ [ Local Mailer ] [ SMTP Mailer ] │ │ ▼ ▼ MDA (procmail 등) 네트워크 발송 │ ▼ [ 사용자의 Mailbox ] 4. 큐(Queue) 스토리지 구조 Sendmail은 /var/spool/mqueue 디렉터리에 파일명 접두사(Prefix)를 사용하여 메시지 본문과 메타데이터를 물리적으로 분리 저장합니다. 이는 큐 러너(Queue Runner)가 본문을 전체 리딩하지 않고도 라우팅 정보를 빠르게 스캔할 수 있도록 최적화된 설계입니다. qf (Queue Control File): 메시지 헤더, 봉투 발신자(Envelope Sender), 수신자 목록, 배달 상태 플래그 등 제어 메타데이터가 기록됩니다. df (Data File): 이메일의 실제 본문(Message Body) 데이터가 저장됩니다. tf (Temporary File): 큐 파일을 갱신하거나 새로 생성할 때 파일시스템 원자성(Atomicity)을 보장하기 위해 임시로 생성하는 파일입니다. 작성이 완료되면 qf 로 rename 됩니다. xf (Transcript File): 메일 배달 시도 중 원격 호스트 등에서 발생한 세션 오류 메시지나 트랜스크립트 로그를 임시 저장합니다. 5. 로컬 배달(MDA) 및 에일리어싱 연동 Sendmail 자체는 파일시스템의 사용자 메일함(mbox)에 직접 기록하는 작업을 수행하지 않습니다. MDA(Mail Delivery Agent) 위임: Ruleset 0이 해당 메일을 로컬 대상으로 판별하면, sendmail은 외부 MDA 프로그램(예: procmail , mail.local , 보안을 위한 smrsh 등)을 서브 프로세스로 포크(fork)하여 표준 입력으로 메일을 던져줍니다. 주소 확장: 배달 직전에 /etc/aliases 데이터베이스(해시화된 aliases.db )와 사용자 홈 디렉터리의 .forward 파일을 분석하여 단일 주소를 그룹 리스트로 확장하거나, 스크립트 파이프로 넘기는 처리를 수행합니다. 6. Sendmail 아키텍처의 의의 및 한계 기술적 의의: 인터넷 초창기의 다양한 메일 주소 규격(UUCP, BITNET 등)을 sendmail.cf 의 룰셋 엔진 하나로 모두 파싱하고 라우팅할 수 있는 극강의 유연성 을 제공하여 인터넷 이메일 인프라의 표준을 정립했습니다. 현대적 관점의 한계: 단일 장애점 문제: 모놀리식 구조로 인해 C 언어로 작성된 방대한 코드 베이스 내 특정 버그 하나가 전체 시스템의 보안 붕괴로 직결되는 설계적 결함을 지녔습니다. 유지보수 난이도 극상: m4 매크로와 sendmail.cf 의 기호 중심 문법은 사람이 직관적으로 해독하거나 튜닝하기 매우 어려워, 이 난해함이 향후 qmail이나 Postfix 같은 대체 MTA들이 개발되는 결정적 계기가 되었습니다.