나는 할 수 있는 간단한 Postfix 서버를 찾고 있습니다.특정 SMTP 메시지의 내용과 수신자를 수정합니다..
지금까지 나는 내 접근 방식에 대해 그다지 확신이 없으며 Postfix 작동 방식에 대한 기본 지식이 누락된 것 같아서 몇 가지 지침을 받고 싶습니다.
문맥
내가 일하는 조직의 설정은 나처럼 Postfix를 실제로 사용해 본 적이 없는 사람에게는 처음에는 약간 어려운 일이므로 내 설명이 이해가 되기를 바랍니다.
DMZ 네트워크의 Linux 컴퓨터가 {1}
Postfix 서버를 실행하고 있으며 들어오는 모든 이메일이 해당 서버로 전달된다는 것을 알게 되었습니다. 그런 다음 서버는 도메인을 기반으로 메시지를 중계할 다른 메일 서버를
결정하는 몇 가지 규칙을 파일에 정의합니다./etc/postfix/transport
{3..N}
(예를 들어 @domain1.company.org
,, @domain2.company.org
). 도메인 이름이 기본 이름인 경우(예를 들어 @company.org
), 메시지는 {2}
직원이 로그인하여 메일 등을 확인하는 기본 이메일 서버 로 전달됩니다.
INTERNET | DMZ | INTERNAL
SMTP ---|---> {1} ---|---> {2}
\---> {3..N}
내가 언급한 "특정 SMTP 메시지"는 일부 엔지니어가 설정한 일부 간단한 장치에서 수집한 것입니다. 이러한 장치가 보낼 수 있는 내용에는 몇 가지 제한 사항이 있습니다.
엔지니어:제목 내용이나 이메일 본문의 특정 영역을 변경할 수 없습니다.
이러한 장치가 메시지를 보내면 네트워크가 메시지를 퍼널링한 {1}
다음 해당 이메일 서버로 메시지를 전달하는 것으로 이해됩니다.
요청된 솔루션
엔지니어:제목과 본문이 간단한 특정 주소에서 보낸 이메일이 수신자에게 전달되기 전에 시스템에서 가로채어 수정되도록 요구할 수 있나요? 예를 들어 제목과 본문에 "leak"라는 단어가 전송되는데 메시지를 전달하기 전에 "freezer"로 변경해도 되나요?
그래서 본질적으로 메시지 내용을 수정해야 합니다.앞으로다른 이메일 서버로 전달됩니다. 메시지가 도착하기 전에 메시지 근처에서 {1}
어떤 일이 일어나야 합니다.{1}
{2..N}
지금까지의 나의 접근 방식
모든 것이 순조롭게 진행될 것이라는 점 {1}
과 이 시스템을 통해 메일이 흐르는 방식을 대대적으로 변경하고 싶지 않다는 점을 고려하여 나는 또 다른 Postfix 서버를 실행하는 또 다른 Linux 상자를 가동해야겠다고 생각했습니다. mailmunger
, 그림에 표시됨)을 {1a}
)로 표시합니다.
그런 다음 엔지니어는 장치를 구성하고 보낼 메시지의 수신자를 지정합니다. 예를 들면 다음과 같습니다 [email protected]
.
내 경우에는 새 Linux 시스템으로 메일을 전달하기 위해 다른 규칙( /etc/postfix/transport
제 생각에는) 을 추가하겠습니다 .{1}
*@mailmunger.company.org
그런 다음 {1a}
다음과 같은 것을 사용합니다.대기열 이후 콘텐츠 필터메시지를 처리하고, 요청한 대로 내용을 수정하고, 수신자 주소에서 내용을 제거하고 mailmunger.
, 메시지를 다시 전달합니다 {1}
.
이는 Postfix 서버 relay_host
의 속성이 {1a}
서버 이름을 사용하여 구성되기 때문입니다 {1}
.
INTERNET | DMZ | INTERNAL
SMTP ---|---> {1} ---|---> {2}
/ ^ \---> {3..N}
| |
v /
{1a}
나는 이 접근 방식이 잘못 작성된 필터의 영향을 제한하기 때문에 가능한 한 안전하다고 생각합니다. 하지만 어쩌면 내가 눈치 채지 못한 채 이 디자인에 실수를 했을 수도 있습니다. 나는 모든 정상적인 메일 흐름이 예상대로 계속되고 메일만 내 새 컴퓨터 에 정체되기를
바랍니다 .[email protected]
mailmunger
질문
- 내 "대기열 후 콘텐츠 필터"가 올바른 방향으로 가고 있나요? 아니면 다음과 같은 다른 메커니즘을 고려해야 합니다.대기열 앞 콘텐츠 필터?
{1a}
서버가 실제로transport
파일을 구성해야 합니까? 아니면 제가 이 속성의 목적을 오해한 걸까요?- 이러한 간단한 장치는 SMTP 메시지를 보낼 서버를 어떻게 알 수 있습니까?
- 제가 알아야 할 문제가 있나요?
답변1
열심히 생각하고 신중하게 테스트한 끝에 해결책을 찾았습니다!
단점은 다음과 같습니다.
- MX 레코드를 잘못 이해하여 서버 에 대한
mailmunger
새 레코드를 만들어야 했습니다. - 아니요, 서버는 파일을 수정할
mailmunger
필요가 없습니다 . 수정/etc/postfix/transport
만/etc/postfix/main.cf
필요합니다 ./etc/postfix/master.cf
- 문제가 너무 많지 않고 메시지가 의도한 대상에 도달하지 못할 때 디버깅이 다소 실망스러울 뿐입니다.
더 자세한 솔루션
따라서 첫 번째 단계는 /etc/postfix/transport
서버를 수정하는 것입니다 {1}
. [email protected]
내 서버로 메시지를 보내려면 전송 맵에 선을 추가해야 합니다 mailmunger
.
/mailmunger.company.org/ relay:[mailmunger.company.org]
내 전송 맵 파일은 정규식 테이블이므로
main.cf
파일에는{1}
다음 줄이 포함됩니다.transport_maps = regexp:/etc/postfix/transport
다음 단계는 구성입니다 mailmunger
.
mailmunger
~의main.cf
이 main.cf
파일에는 필요한 두 가지 주요 섹션이 있습니다.
relayhost = {1}.company.org
local_recipient_maps =
변수를 정의하면 relayhost
서버에 "메시지를 받아야 할 사람이 아닌 경우 이 사람에게 전달하십시오"라고 알립니다.
메시지를 수정한 후 다시 대기열에 넣기 때문에 이는 중요한 부분입니다.다른받는 사람.
이 local_recipient_maps
변수에는 null 값이 필요합니다. 그렇지 않으면 필터 스크립트가 메시지를 처리하기 전에 서버가 지정된 수신자의 사서함을 찾을 수 없으면 메시지가 거부되기 때문입니다.
내 목적은 메시지 내용을 수정하는 것이므로 수신자가 서버에 계정이 없어도 상관 없습니다.그리고수신자 주소.
스크립트가 실패하면 메시지가 보낸 사람에게 반송됩니다.
mailmunger
~의master.cf
여기서 변경한 내용은 기본적으로 정확히 다음과 같습니다.대기열 이후 콘텐츠 필터지침이 지정됩니다.
smtp inet n - y - - smtpd
-o content_filter=filter:dummy
...
filter unix - n n - 10 pipe
flags=Rq user=postfix-filter null_sender=
argv=/opt/postfix-filters/start-filter -f ${sender} -- ${recipient}
이 서비스는 메시지를 파이프라인 서비스 smtp
로 전달하는 추가 옵션을 추가합니다 . 서비스 는 내가 만든 특수 사용자로 내 스크립트를 실행 하고 스크립트의 종료 코드에 따라 메시지를 다시 대기열에 넣거나 보낸 사람에게 반송합니다.filter
filter
postfix-filter
다른 건 다 있어요mailmunger
서비스 구성에서 filter
생성/구성해야 할 몇 가지 사항이 더 있다는 것을 알 수 있습니다.
- 첫 번째 단계는 해당 위치가 마음에 드는 새 디렉토리를 만드는 것입니다
/opt/postfix-filters/
. - 다음 단계는
postfix-filter
사용자를 생성하는 것입니다. 쉘을 사용하여 이 사용자를 지정/usr/sbin/nologin
하고 홈 디렉토리를/opt/postfix-filter
. - 그런 다음
start-filter
다음 논리를 사용하여 디렉터리에 파일을 만들었습니다./opt/postfix-filters/
#!/bin/bash ############################################################################## # # Based on documented example here: # http://www.postfix.org/FILTER_README.html # # Example Execution: # /path/to/script -f sender -- recipient... <message-file # ############################################################################## shopt -s extglob ## Making of copy of the positional arguments _ARGS=("$@") ## Defining paths to directories that we will be using _BASE_DIR="/opt/postfix-filters" _TMP_DIR="${_BASE_DIR}/tmp" [ -d ${_TMP_DIR} ] || { echo "${_TMP_DIR} does not exist"; exit $EX_TEMPFAIL; } _TMP_FILE="${_TMP_DIR}/in.$$" _LOG_FILE="${_BASE_DIR}/log" _FILTERS_DIR="${_BASE_DIR}/filters" SENDMAIL="/usr/sbin/sendmail -G -i " # NEVER NEVER NEVER use "-t" here. ## Exit codes from <sysexits.h> EX_TEMPFAIL=75 EX_UNAVAILABLE=69 ## Clean up when done or when aborting. function _cleanup() { #echo ${_ARGS[@]} #cat ${_TMP_FILE} rm -f ${_TMP_FILE} } trap "_cleanup" 0 1 2 3 15 ## Creating a temp file (in the INSPECT_DIR directory) with a name that uses ## the current Process ID ($$). ## This script assumes that the message content is coming in via stdin. cat >${_TMP_FILE} || { echo "Cannot save mail to file"; exit $EX_TEMPFAIL; } ## Pass the file and args to each script in the directory containing ## filter scripts. If any of them fails with exit code 1, then exit ## this parent script. Assume 0 and all other error codes mean ## continue. for _SCRIPT in ${_FILTERS_DIR}/!(README*) ; do ## A quick test that the path is a file and is executable ( [ -f "${_SCRIPT}" ] && [ -x "${_SCRIPT}" ] ) || continue ## Now we run the script echo "running: ${_SCRIPT} -- ${_TMP_FILE} ${_ARGS[@]}" >> "${_LOG_FILE}" _NEWARGS=$( ${_SCRIPT} "${_TMP_FILE}" ${_ARGS[@]} ) if [ "$?" -eq 0 ] then _ARGS=("${_NEWARGS}") echo "newargs? ${_ARGS[@]}" >> "${_LOG_FILE}" elif [ "$?" -eq 2 ] then echo "args not modified" >> "${_LOG_FILE}" else ## If the script exits with any exit code other than 0 or 2, then we ## will "reject" the message based on the content. To do the rejection, ## we exit this script with the EX_UNAVAILABLE exit code. echo "Message content rejected" exit $EX_UNAVAILABLE fi done ## Putting the mail back in the queue using the args given to this ## script by Postfix. $SENDMAIL ${_ARGS[@]} <"${_TMP_FILE}" ## Exiting with the return status of sending the mail exit $?
- 및
/opt/postfix-filters/
와 같이 에서 생성해야 하는 다른 디렉토리가 있습니다 .filters/
tmp/
- 그런 다음 남은 것은
filters/
해당 디렉토리에 사용자가 실행할 수 있는 하나 이상의 스크립트를 만드는 것 입니다postfix-filter
. 이 작업을 수행하는 방법을 알려 드리겠습니다. 하지만 스크립트 제안은 그대로 두겠습니다.할 수 있는들어오는 매개변수(최종적으로sendmail
명령에 전달됨)를 수정하고 다음 종료 코드 중 하나를 반환해야 합니다.0
(성공에 대해그리고매개변수sendmail
가 수정되었습니다)2
(성공한 경우, 그러나 매개변수는 수정되지 않습니다)- 어쨌든(문제가 무엇입니까, 종료하고 메시지를 반환하십시오).
일을 시작하다
이제 남은 것은 Postfix가 mailmunger
새로운 구성으로 시작되는지 확인하는 것입니다.
[root@mailmunger /etc/postfix]# postfix reload
답변2
예를 들어 Milt를 사용하지 않는 이유는 무엇입니까?메일 상인? 이를 통해 두 번째 Postfix 인스턴스나 기타 이상한 스크립트 및 해킹을 사용하지 않고도 필요한 작업을 정확하게 수행할 수 있습니다.