고쳐 쓰다

고쳐 쓰다

AUTH LOGIN 인증을 사용할 때마다 내 exim4 vis는 이메일을 보낼 때 segfault를 발생시킵니다. 그러나 AUTH PLAIN을 사용하여 이메일을 보내는 것은 매우 잘 작동합니다. 두 인증 방법 모두 Dovecot Authenticator에 연결됩니다.

Exim4 정보:

Exim version 4.92 #3 built 09-Sep-2021 16:25:33
Copyright (c) University of Cambridge, 1995 - 2018
(c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2018
Berkeley DB: Berkeley DB 5.3.28: (September  9, 2013)
Support for: crypteq iconv() IPv6 PAM Perl Expand_dlfunc GnuTLS move_frozen_messages Content_Scanning DANE DKIM DNSSEC Event OCSP PRDR PROXY SOCKS SPF TCP_Fast_Open Experimental_ARC Experimental_DCC Experimental_DMARC Experimental_DSN_info
Lookups (built-in): lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmjz dbmnz dnsdb dsearch ldap ldapdn ldapm mysql nis nis0 passwd pgsql sqlite
Authenticators: cram_md5 cyrus_sasl dovecot plaintext spa tls
Routers: accept dnslookup ipliteral iplookup manualroute queryprogram redirect
Transports: appendfile/maildir/mailstore/mbx autoreply lmtp pipe smtp
Malware: f-protd f-prot6d drweb fsecure sophie clamd avast sock cmdline
Fixed never_users: 0
Configure owner: 0:0
Size of off_t: 8
Configuration file search path is /etc/exim4/exim4.conf:/var/lib/exim4/config.autogenerated
Configuration file is /var/lib/exim4/config.autogenerated

다음은 세그폴트 메시지입니다.

Sep 13 12:57:36 tornavacas kernel: exim4[12679]: segfault at 0 ip 00007fdd2d854206 sp 00007ffe23909ac8 error 4 in libc-2.28.so[7fdd2d7de000+148000]
Sep 13 12:57:36 tornavacas kernel: Code: 0f 1f 40 00 66 0f ef c0 66 0f ef c9 66 0f ef d2 66 0f ef db 48 89 f8 48 89 f9 48 81 e1 ff 0f 00 00 48 81 f9 cf 0f 00 00 77 6a <f3> 0f 6f 20 66 0f 74 e0 66 0f d7 d4 85 d2 74 04 0f bc c2 c3 48 83

다음은 strace 출력의 마지막 줄입니다.

[pid 16595] munmap(0x7f5e7f800000, 2097152) = 0
[pid 16595] munmap(0x7f5e7df65000, 331776) = 0
[pid 16595] munmap(0x7f5e7fb1a000, 135168) = 0
[pid 16595] exit_group(1)               = ?
[pid 16595] +++ exited with 1 +++
[pid 16592] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 16595
[pid 16592] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=16595, si_uid=106, si_status=1, si_utime=2, si_stime=1} ---
[pid 16592] alarm(0)                    = 30
[pid 16592] rt_sigaction(SIGCHLD, {sa_handler=SIG_IGN, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f5c6ba6b840}, {sa_handler=SIG_DFL, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f5c6ba6b840}, 8) = 0
[pid 16592] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
[pid 16592] +++ killed by SIGSEGV +++
<... select resumed> )                  = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=16592, si_uid=106, si_status=SIGSEGV, si_utime=0, si_stime=1} ---
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f5c6bc07730}, NULL, 8) = 0
rt_sigreturn({mask=[]})                 = -1 EINTR (Interrupted system call)
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV}], WNOHANG, NULL) = 16592
wait4(-1, 0x7fff60755674, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigaction(SIGCHLD, {sa_handler=0x55cf02123500, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f5c6bc07730}, NULL, 8) = 0
select(11, [3 4 5 6 7 8 9 10], NULL, NULL, NULL

문제를 재현하는 방법은 다음과 같습니다.

#!/usr/bin/expect

set timeout 30
proc abort {} { exit 2 }

spawn nc tornavacas.domain.com 587
expect default abort "220 "
send "EHLO mypc\r"
expect default abort "\n250 "
send "AUTH LOGIN\r"
expect default abort "\n334 "
send "ZGlzZ3Vpc2VkQGRvbWFpbi5jb20=\r"
expect default abort "\n334 "
send "cGFzc3dvcmQ=\r"
send "MAIL FROM:[email protected]\r"
expect default abort "\n250 "
send "RCPT TO:[email protected]\r"
expect default abort "\n250 "
send "DATA\r"
expect default abort "\n354 "
send "Subject: Mensaje de prueba de Microsoft Outlook\r"
send "\r"
send "This is a multipart message in MIME format.\r"
send ".\r"
expect default abort "\n250 "
send "QUIT\r"

이 스크립트를 실행하면 다음과 같은 결과가 나타납니다.

../..
DATA
354 Enter message, ending with "." on a line by itself
Subject: Mensaje de prueba de Microsoft Outlook

This is a multipart message in MIME format.
.

그럼에도 불구하고 AUTH PLAIN을 사용하여 동일한 메시지를 보내면 작동합니다.

#!/usr/bin/expect

set timeout 30
proc abort {} { exit 2 }

spawn nc tornavacas.domain.com 587
expect default abort "220 "
send "EHLO mypc\r"
expect default abort "\n250 "
send "AUTH PLAIN AGRpc2d1aXNlZEBkb21haW4uY29tAHBhc3N3b3Jk\r"
expect default abort "\n235 "
send "MAIL FROM:[email protected]\r"
expect default abort "\n250 "
send "RCPT TO:[email protected]\r"
expect default abort "\n250 "
send "DATA\r"
expect default abort "\n354 "
send "Subject: Mensaje de prueba de Microsoft Outlook\r"
send "\r"
send "This is a multipart message in MIME format.\r"
send ".\r"
expect default abort "\n250 "
send "QUIT\r"

위 명령의 출력은 다음과 같습니다.

DATA
354 Enter message, ending with "." on a line by itself
Subject: Mensaje de prueba de Microsoft Outlook

This is a multipart message in MIME format.
.
250 OK id=1mPk9v-0004O2-Bp

보시다시피 이제 이메일 서버는 250 코드로 응답하지만 이전에는 작동하지 않아 전혀 응답하지 않았습니다.

문제는 두 경우 모두 인증이 작동하지만 사용자가 PLAIN 방법 대신 LOGIN 방법을 사용하여 자신을 인증하면 상황이 달라진다는 것입니다.

저는 두 가지 접근 방식을 모두 지원하고 싶습니다. AUTH LOGIN을 사용한 후 segfault의 원인을 알고 계십니까?

고쳐 쓰다

더 자세히 조사한 결과 특히 다음 코드 조각에서 문제의 원인이 check_data ACL이라는 사실을 발견했습니다.

  warn add_header = :at_start: ${authresults {$primary_hostname}}

이론적으로 이 줄은 이메일에 authresults 확장자가 있는 헤더만 추가해야 합니다. 단, 주석 처리하면 segfault가 발생하지 않지만 warning 지시문이 활성화되면 segfault가 발생합니다.

따뜻한 안부 인사,

답변1

문제의 원인은 특히 다음 코드 조각에서 check_data ACL에 있다는 것을 알았습니다.

add_header = :at_start: ${authresults {$primary_hostname}} 경고

이론적으로 이 줄은 이메일에 authresults 확장자가 있는 헤더만 추가해야 합니다. 단, 주석 처리하면 segfault가 발생하지 않지만 warning 지시문이 활성화되면 segfault가 발생합니다.

관련 정보