그렇습니다. 메일 서버를 구축하고 있는데, 실제 메일이 스팸처리가 되어 이를 방지하는 방법을 미리 알아보려고 합니다.
스팸메일의 문제점은 수신 거부를 해도 스팸 발송자가 발신자 정보를 지속적으로 위/변조하여 발송한다는 것인데요.
이런 행위를 이메일 위장, 또는 이메일 스푸핑(Spoofing)이라고 합니다.
SPF(메일서버등록제, Sender Policy Framework) 레코드는 이를 방지하기 위한 인증 기술로, 메일서버 정보를 사전에 DNS에 공개 등록하여 메일에 표시된 발신자 정보가 실제 메일 서버 정보와 일치하는지 확인합니다.
대용량 메일을 발송하는 경우나 메일 서버의 신원이 불분명한 경우 국내 메일 서비스 업체나, Gmail을 포함한 여러 업체에서 해당 메일을 스팸으로 처리하는 것 같습니다.
우선 저는 IMAP, POP와 같은 메일 수신 관련 서비스를 실행하지 않습니다. 또한 메일 서버에 접근할 수 있는 대상도 내부망으로 한정했고, 메일 인증을 활성화시켰습니다. 외부 트래픽을 막으니 RELAY도 전부 주석처리했습니다.
만약 스팸을 메일 서버를 구축하는 데 있어 처리해야 한다면 KISA-RBL을 추천드립니다.
KISA-RBL은 손쉽게 스팸을 차단하는데 이용할 수 있도록 KISA에서 무료로 관리/운영하는 실시간 스팸차단리스트입니다.
White Domain에 대해 알아보면서 SPF, DKIM, DMARC에 대해 더 자세히 알아보려고 합니다.
White Domain은 사전에 등록된 개인이나 사업자에 한하여 국내 주요 포털사이트로의 이메일 전송을 보장해 주는 제도입니다.
이를 등록하기 위해서는 SPF를 등록해야한다고 합니다.
Sender Policy Framework은 이메일 수신 서비스에서 이메일 발신자가 신뢰할만한 주소인지, 신뢰도를 검증해 수신자에게 스팸 메일이 전달되는 것을 막기 위해 널리 사용되는 방법입니다.
메일 마케팅 서비스를 이용하는 경우, 발신자의 주소가 변경되는 경우 스팸으로 처리할 확률이 매우 높아집니다.
SPF와 DKIM 설정을 하게 되면 "의심스러운 발신자"가 원인으로 이메일의 수신이 차단되거나 스팸으로 분류되는 확률을 낮출 수 있습니다.
SPF 레코드 작동 원리
SPF는 메일 수신 시 메일 서버가 발신자의 IP주소를 메커니즘에 정의된 IP 주소와 비교하는 방식으로 작동합니다.
발신자가 DNS에 메일 서버와 정보와 정책을 나타내는 SPF 레코드를 등록해 두면, 수신자가 이메일을 수신할 때 DNS에 등록된 SPF 레코드와 이메일에 표시된 발송 IP를 대조 한 뒤 수신 여부를 결정합니다.
만약 메일 서버가 프록시 서버를 거치는 경우 SPF 유효성 검사 프로세스에 영향을 줄 수 있습니다.
이를 위해선 프록시 서버가 원본 IP를 전달하도록 구성해야 합니다.
SPF 레코드 형식은 일반적으로 TXT 레코드 타입을 사용하고 다음과 같이 사용될 수 있습니다.
"v=spf1 ip4:xxx.xxx.xxx.xxx ~all"
현재 버전은 spf1이며, 가장 일반적인 spf 버전입니다.
다음 내용은 호스트가 도메인에서 메일을 보내거나, spf 레코드를 처리하기 위한 메커니즘입니다.
SPF 레코드 수식자(qualifiers)
- + for pass
- - for fail
- ~ for soft fail
- ? for neutral
SPF 메커니즘
메커니즘 | 설명 | 사용 예시 |
all | 주로 SPF 레코드의 가장 마지막 자리에 오며 항상 사용 | “v=spf1 mx -all” 해당 도메인의 mx 서버를 질의하여 발송 서버의 IP의 mx서버의 IP와 일치하면 수신 허용 “v=spf1 -all” 해당 도메인은 어느 서버에서도 메일을 발송하지 않음 “v=spf1 +all” 해당 도메인은 어느 서버에서도 수신을 허용 |
ip4 | ip4주소(또는 주소 범위)를 유효한 전송 소스로 정의 | “v=spf1 ip4:192.168.0.1 -all” 192.168.0.1의 IP주소만 허용하고 나머지는 실패 |
ip6 | ip6주소(또는 주소 범위)를 유효한 전송 소스로 정의 | “v=spf1 ip6:1080::8:800:200C:417A/96 -all” – 1080::8:800:0000:0000 와 1080::8:800:FFFF:FFFF 사이의 IP주소만 pass, 나머지는 fail. |
a | 현재(또는 지정된) 도메인의 DNS a레코드를 유효한 전송 소스로 정의 | “v=spf1 a -all” – 현재 도메인 테스트 |
MX | 현재(또는 지정된) 도메인의 DNS MX 레코드를 유효한 전송 소스로 정의 | |
include | 이 도메인의 SPF 레코드를 유효한 전송 소스로 정의 | include : example.com |
SPF는 수신자가 발신자의 DNS에서 전달받은 SPF의 정책을 비교하여 이를 검사하는 것이다.
즉 SPF를 사용하려는 수신 서버는 이를 사용할 별도의 무언가가 또 필요할 것이다.
DKIM
DKIM은 이메일 인증 방법 중 하나로 수신 서버에서 수신된 이메일이 위변조 되지 않았는지 디지털 서명을 이용해 검증하는 기술입니다.
발송 서버는 이메일 발송 시 이메일 발송자, 수신자, 제목, 내용 등을 비밀 키로 서명합니다.
이 서명 값을 DKIM-Signature 헤더(Header)에 추가합니다.
수신 서버는 DKIM-Signature 헤더 내 도메인(d=) DNS에 공개된 공개 키와 서명 알고리즘 정보 등이 담긴 DKIM 레코드를 조회하고 이 값들을 이용해 수신된 이메일 DKIM-Signature 헤더의 디지털 서명을 검증합니다.
다음은 DKIM 작동 방식에 대한 개요입니다.
- 디지털 서명: 보낸 사람의 메일 서버는 암호화 알고리즘(예: RSA 또는 SHA)을 사용하여 개인 키로 발신 이메일에 서명합니다. 서명 프로세스는 전자 메일 메시지에 대한 고유한 서명을 생성합니다.
- 공개 키 공개: 발신자의 메일 서버는 이메일 주소에 사용된 도메인의 DNS(Domain Name System) 레코드에 공개 키를 공개합니다. 공개 키는 DKIM TXT 레코드로 저장됩니다.
- 이메일 전송 : 서명한 이메일을 수신자의 메일 서버로 전송합니다.
- DKIM 확인: 수신자의 메일 서버는 이메일 주소에서 추출한 도메인을 사용하여 DNS에서 발신자의 공개 키를 검색하여 DKIM 확인을 수행합니다.
- 서명 확인: 수신자의 메일 서버는 검색된 공개 키를 사용하여 이메일 메시지에 첨부된 서명을 해독합니다. 그런 다음 이메일 콘텐츠의 해시를 다시 계산하고 해독된 서명과 비교합니다.
- 결과 평가: 재계산된 해시가 복호화된 서명과 일치하면 이메일이 전송 중 변조되지 않았음을 나타내며 발신자를 확인합니다. 받는 사람의 메일 서버는 전자 메일을 신뢰할 수 있고 신뢰할 수 있는 것으로 간주합니다.
DKIM 레코드 구조
다음은 발송 도메인 DNS에 등록하는 DKIM 레코드 예입니다.
DKIM 레코드는 수신 서버에서 수신된 이메일의 DKIM-Signature 헤더 검증을 위해 사용됩니다.
DKIM 레코드는 SPF 레코드와 다르게 발송 도메인 DNS에 등록되는 것이 아니라
'${지정자}._domainkey.${도메인}' 도메인 DNS에 TXT 레코드로 등록합니다.
(가비아의 경우 호스트명 뒤에 자동적으로 도메인이 붙습니다. 따라서 {selctor}._domainkey와 같이 작성하시면 됩니다.)
DKIM-Signature 구조
다음은 이메일 발송 시 이메일 헤더에 추가되는 DKIM 서명(DKIM-Signature 헤더) 예입니다.
DKIM-Signature: v=1; a=rsa-sha256; d=example.net; s=toast;
t=1117574938; x=1118006938;
h=from:to:subject:date;
bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;
b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZVoG4ZHRNiYzR
v | 필수 | 1 | 버전입니다. |
a | 필수 | sha-256 | DKIM 서명에 사용되는 알고리즘입니다. |
s | 필수 | - | 지정자(Selector)입니다. 발송 도메인은 여러 개의 DKIM을 사용할 수 있습니다. 따라서, DKIM-Signature 헤더에서는 이 서명이 어떤 공개 키를 이용해 인증해야 되는지 수신 서버에게 알려주어야 합니다. 예를 들어 지정자가 'toast'면 수신 서버는 'toast._domainkey.example.com'의 DNS에서 DKIM 레코드를 확인합니다. |
h | 필수 | - | 서명할 헤더(Header)입니다. 헤더들은 콜론(:)으로 구분합니다. |
b | 필수 | - | 서명할 헤더(h)에 정의된 헤더들을 서명한 값입니다. Base64로 인코딩됩니다. |
bh | 필수 | - | 이메일 본문을 서명한 값입니다. |
l | 선택 | - | 본문 서명(b)에 사용된 본문의 길이입니다. 따로 정의되어 있지 않다면 본문 전체를 사용합니다. |
d | 필수 | - | 도메인입니다. 지정자(s)와 함께 DKIM 서명을 검증하기 위해 DNS에 DKIM 레코드를 조회할 때 사용됩니다. MAIL FROM(5321.From)과 From(5322.From)과 다를 수 있습니다. 하지만, 다를 경우 의심스러운 메일로 분류될 수 있습니다. |
t | 선택 | - | DKIM 서명 생성 일시입니다. 형식은 유닉스 시간(Unix Time)입니다. 1970년 1월 1일 0시 0분 0초 UTC(협정 세계시)부터의 경과 시간을 초로 환산한 값입니다. 예, 2020년 6월 8일 오후 3시 47분 17초의 유닉스 시간: 1591631237초 |
x | 선택 | - | DKIM 서명 만료 일시입니다. 형식은 서명 생성 일시(t)와 같습니다. |
DKIM 패키지를 설치합니다.
1. sudo apt opendkim opendkim-tools
2. /etc/opendkim.conf
# This is a basic configuration for signing and verifying. It can easily be
# adapted to suit a basic installation. See opendkim.conf(5) and
# /usr/share/doc/opendkim/examples/opendkim.conf.sample for complete
# documentation of available configuration parameters.
AutoRestart yes
AutoRestartRate 10/1h
Syslog yes
SyslogSuccess yes
LogWhy yes
# Common signing and verification parameters. In Debian, the "From" header is
# oversigned, because it is often the identity key used by reputation systems
# and thus somewhat security sensitive.
Canonicalization relaxed/simple
Mode sv
#SubDomains no
OversignHeaders From
# Signing domain, selector, and key (required). For example, perform signing
# for domain "example.com" with selector "2020" (2020._domainkey.example.com),
# using the private key stored in /etc/dkimkeys/example.private. More granular
# setup options can be found in /usr/share/doc/opendkim/README.opendkim.
Domain yourdomain.com
Selector mail
KeyFile /etc/opendkim/mail.private
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256
# In Debian, opendkim runs as user "opendkim". A umask of 007 is required when
# using a local socket with MTAs that access the socket as a non-privileged
# user (for example, Postfix). You may need to add user "postfix" to group
# "opendkim" in that case.
UserID opendkim:opendkim
UMask 002
# Socket for the MTA connection (required). If the MTA is inside a chroot jail,
# it must be ensured that the socket is accessible. In Debian, Postfix runs in
# a chroot in /var/spool/postfix, therefore a Unix socket would have to be
# configured as shown on the last line below.
#Socket local:/run/opendkim/opendkim.sock
Socket inet:8891@localhost
#Socket inet:8891
#Socket local:/var/spool/postfix/opendkim/opendkim.s
# Hosts for which to sign rather than verify, default is 127.0.0.1. See the
# OPERATION section of opendkim(8) for more information.
#InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
# The trust anchor enables DNSSEC. In Debian, the trust anchor file is provided
# by the package dns-root-data.
TrustAnchorFile /usr/share/dns/root.key
#Nameservers 127.0.0.1
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
~
KeyTable - OpenDKIM에게 키를 찾을 위치를 알려줍니다.
두 가지 방법으로 생성합니다. 대부분 2048 비트수가 현재 기본값인데, 가비아는 TXT 레코드 값이 250자 이상을 넘을 수 없어, 다른 방법을 사용해야 합니다.
이러한 도메인 업체 때문에 1024비트로 변경해서 바꾸는 명령어도 알려드립니다.
# 2048 default
opendkim-genkey -d yourdomain.com -D /etc/opendkim/yourdomain.com -s mail -v
# 1024 TXT 제한
opendkim-genkey -b 1024 -d yourdomain.com -D /etc/opendkim/yourdomain.com -s mail -v
-d 도메인 옵션, -D key 저장될 디렉터리, -s {selctor} 명..
이는 help 명령어나 man page를 참고하시길 바랍니다.
생성된 키파일의 권한이나 소유권을 설정해 주는데, 상황에 맞추시고 opendkim으로 소유권을 변경해 주셔도 됩니다.
생성된 공개키 파일은 txt 파일로 생성됩니다.
mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB3213x9ky4iCRcozQXKXuAGEWukuceaTktyv9fJRAVKQIIJ+3fK1Nbfc4DGBfF4uT0Sm/p6Vz6otRWUL53m/FlD8K16/Zpovo27xrgOnQnCx3posE6M1ZimE6i5GKnV/iAlr0kpgycv8Da5eYHSLUAsiBdEBMAgpUlrNwIDAQAB" )
; ----- DKIM key mail for yourdomain.com
이후 KeyTable 설정파일에 다음과 같이 설정합니다.
mail._domainkey.yourdomain.com yourdomain.com:mail:/etc/opendkim/mail.private
SigningTable - OpenDKIM 키 사용 방법을 정의합니다. KeyTable을 활성화해야 합니다.
다음과 같이 작성할 수 있습니다.
*@yourdomain.com mail._domainkey.yourdomain.com
발신자의 메일 메시지에 하나 이상의 서명을 적용하는 방식을 제어하는데, 위 와일드카드는 모든 계정에 대해 서명을 체크합니다.
TrustedHosts
1. ExternalIgnoreList - OpenDKIM이 외부 호스트에 대한 DKIM확인을 식별하기 위한 리스트
2. InternalHosts - OpenDKIM이 내부 호스트에 대한 DKIM확인을 식별하기 위한 리스트
두 리스트를 한 번에 관리하는 파일입니다.
127.0.0.1
localhost
192.168.0.1/24
*.yourdomain.com
Test
실제 메일을 보낸 이후 원본 보기를 클릭하여 헤더에 들어간 내용을 확인하는 방법이 있습니다.
opendkim-testkey -d yourdomain.com -s mail -v 명령어를 통해 key OK를 확인합니다.
DMARC
DMARC 레코드를 사용하는 이유는 spoofing, fishing을 방지하는 TXT 레코드입니다.
동일하게 도메인 서버에 설정해야 하기 때문에 도메인이 필요하고, 해당 도메인 관리 업체의 제약을 따릅니다.
DMARC의 TXT 레코드는 전자 메일을 보내는 도메인의 알려진 소유자와 대조하여 전자 메일 작성자의 ip를 확인함으로써 전자 메일 메시지의 출처에 대한 유효성을 검사합니다.
_dmarc.microsoft.com. 3600 IN TXT "v=DMARC1; p=none; pct=100; rua=mailto:d@rua.contoso.com; ruf=mailto:d@ruf.contoso.com; fo=1"
DMARC 레코드 태그
v | DMARC 버전이며, DMARC1이어야 합니다. 이 태그는 필수 항목입니다. |
p | 인증을 통과하지 못한 메일에 대해 취할 조치를 수신 메일 서버에 지시합니다. • none—메일에 아무런 조치를 취하지 않고 의도된 수신자에게 보냅니다. 메일을 일일 보고서에 기록합니다. 보고서는 레코드의 rua 옵션에 지정된 이메일 주소로 전송됩니다. • quarantine— 메일을 스팸으로 표시하고 수신자의 스팸 폴더로 보냅니다. 수신자는 스팸 메일을 검토하여 스팸이 아닌 메일을 파악할 수 있습니다. • reject— 메일을 거부합니다. 이 옵션을 선택하면 일반적으로 수신 서버에서 발신 서버로 반송 메일을 보냅니다. 이 태그는 필수 항목입니다. |
pct | 인증되지 않은 메일 중 DMARC 정책을 적용할 비율을 지정합니다. DMARC를 단계적으로 배포할 때 적은 비율의 메일에 먼저 적용하기 시작하는 것이 좋습니다. 수신 서버에서 인증을 통과하는 도메인의 메일이 증가함에 따라 비율을 점차 높여 레코드를 업데이트하고 최종적으로는 100%가 될 수 있도록 합니다. |
1에서 100 사이의 정수여야 합니다. 레코드에서 이 옵션을 사용하지 않으면 도메인에서 보낸 모든 메일(100%)에 DMARC 정책이 적용됩니다. | |
이 태그는 선택사항입니다. | |
rua | 도메인의 DMARC 활동에 대한 보고서를 수신할 이메일 주소입니다. |
이메일 주소에 mailto:를 포함해야 합니다. | |
예: mailto:dmarc-reports@solarmora.com | |
DMARC 보고서를 여러 이메일로 보내려면 각 이메일 주소를 쉼표로 구분하고 각 주소 앞에 mailto: 접두사를 추가합니다. 예:mailto:dmarc-reports@solarmora.com, mailto:dmarc-admin@solarmora.com |
|
이 옵션으로 인해 많은 양의 보고서 이메일이 생성될 수도 있으므로, 본인의 이메일 주소를 사용하지 않는 것이 좋습니다. 대신 DMARC 보고서 전용 편지함, 그룹 또는 DMARC 보고서를 전문적으로 다루는 타사 서비스를 고려해 보세요. | |
ruf | 지원되지 않습니다. Gmail에서는 오류 보고서를 보내는 데 사용되는 ruf 태그가 지원되지 않습니다. 오류 보고서는 포렌식 보고서라고도 합니다. |
sp | 기본 도메인의 하위 도메인에서 전송된 메일에 적용되는 정책을 설정합니다. 하위 도메인에 다른 DMARC 정책을 사용하려는 경우 이 옵션을 사용하세요. |
• none—메시지에 대해 아무런 조치를 취하지 않고 의도한 수신자에게 전달합니다. 일일 보고서에 메시지를 기록합니다. 보고서가 정책에서 rua 옵션으로 지정된 이메일 주소로 전송됩니다. | |
• quarantine—메일을 스팸으로 표시하고 수신자의 스팸 폴더로 보냅니다. 수신자는 스팸 메일을 검토하여 스팸이 아닌 메일을 파악할 수 있습니다. | |
• reject—메일을 거부합니다. 이 옵션을 선택하면 수신 서버에서 발신 서버로 반송 메일을 보내야 합니다. | |
레코드에서 이 옵션을 사용하지 않으면 하위 도메인에는 상위 도메인에 설정된 DMARC 정책이 상속됩니다. | |
이 태그는 선택사항입니다. | |
adkim | 메일 정보가 DKIM 서명과 어느 정도 일치해야 하는지를 정의하는 DKIM의 정렬 정책을 설정합니다. https://support.google.com/a/answer/10032169#alignment 알아보기 |
• s—엄격한 정렬. 발신자 도메인 이름이 DKIM 메일 헤더에 있는 d=domainname과 정확하게 일치해야 합니다. | |
• r—Relaxed alignment (default). Allows partial matches. Any valid subdomain of d=domain in the DKIM mail headers is accepted. | |
이 태그는 선택사항입니다. | |
aspf | 메일 정보가 SPF 서명과 어느 정도 일치해야 하는지를 정의하는 SPF의 정렬 정책을 설정합니다. https://support.google.com/a/answer/10032169#alignment 알아보기 |
• s—엄격한 정렬. 메일의 보낸사람 헤더가 SMTP MAIL FROM 명령어의 도메인 이름과 정확하게 일치해야 합니다. | |
• r—완화된 정렬(기본값). 부분 일치가 허용됩니다. 도메인 이름의 유효한 하위 도메인이 모두 허용됩니다. | |
이 태그는 선택사항입니다. |
보안적용 예시
빈칸은 각 규칙에 따른 ip 혹은 도메인이니 본인 도메인을 추가하면 됩니다.
'도전' 카테고리의 다른 글
Video Protocol (0) | 2023.06.29 |
---|---|
개발 용어 (0) | 2023.06.26 |
SLAM (0) | 2023.06.07 |
Hellow WebGPU (0) | 2023.05.15 |
Normal Map (2) (0) | 2023.05.13 |
댓글