OpenDKIM (DomainKeys Identified Mail)은 전자 메일의 인증 및 보안을 강화하기 위한 오픈 소스 소프트웨어로 도메인 인증 기술의 일종으로, 전자 메일이 도착한 송신자가 실제로 그들이 주장하는 도메인의 소유자임을 인증한다. OpenDKIM은 전자 메일 서버에 설치되어 메일의 헤더와 본문을 디지털 서명하여 도메인 소유자가 전자 메일을 보낸 것임을 확인하게 처리한다. 서명은 메일 서버에서 검증하고 받는 수신자는 이메일이 실제로 인증된 송신자에 의해 보내졌음을 확인할 수 있습니다. 스팸 메일, 피싱 공격 및 기타 전자 메일 보안 위협을 방지할 수 있는 수단 중 하나다. OpenDKIM은 BSD 라이선스로 배포되며 자유롭게 사용가능하다.
[목차]
2. opendkim 및 opendkim-tools 설치
※ 참고사항 : DKIM과 DMARC의 기본 개념
1. 설치 환경
OS 환경 : Ubuntu 22.04.2 LTS
postfix : 3.6.4
2. opendkim 및 opendkim-tools 설치
apt update
apt install opendkim opendkim-tools
3. opendkim 설치 버전
root@gbminnote:~# opendkim -V
opendkim: OpenDKIM Filter v2.11.0
Compiled with OpenSSL 3.0.2 15 Mar 2022
SMFI_VERSION 0x1000001
libmilter version 1.0.1
Supported signing algorithms:
rsa-sha1
rsa-sha256
ed25519-sha256
Supported canonicalization algorithms:
relaxed
simple
Active code options:
QUERY_CACHE
USE_DB
USE_LDAP
USE_LUA
USE_ODBX
USE_UNBOUND
_FFR_ATPS
_FFR_RBL
_FFR_REPLACE_RULES
_FFR_SENDER_MACRO
_FFR_STATS
_FFR_VBR
libopendkim 2.11.0: atps query_cache
4. DKIM 설정
1) 기본 설정백업
root@gbminnote:~# cp -a /etc/opendkim.conf /etc/opendkim.conf_org
2) opendkim.conf 설정
root@gbminnote:~# vi /etc/opendkim.conf
AutoRestart Yes
AutoRestartRate 10/1h
UMask 022
Syslog Yes
SyslogSuccess Yes
LogWhy Yes
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
Mode sv
PidFile /var/run/opendkim/opendkim.pid
Selector gbminnote
SignatureAlgorithm rsa-sha256
UserID opendkim:opendkim
Socket inet:8891@localhost
3) SOCKET 설정 수정
root@gbminnote:~# vim /etc/default/opendkim
- SOCKET=local:$RUNDIR/opendkim.sock
+ SOCKET=inet:8891@localhost
4) Key디렉터리생성
root@gbminnote:~# mkdir -p /etc/opendkim/keys/gbminnote.com
5) Private key 생성
※ 참고사항.
Private Key 생성 방법은 opendkim-tools에 포함된 opendkim-genkey 커맨드로 가능하나,
내가 사용하는 DNS 관리 문제로 256byte 이상의 key 값을 한 줄로 등록할 수가 없는 상태였다.
Key 값을 두 줄로 입력하면 문제가 없으나 깔끔한 DNS 관리를 위해 tinydns 형식으로 입력하기로 결정하였다.
opendkim-genkey 커맨드는 tinydns 형식으로 생성이 안되기 때문에
https://dkimcore.org/tools/ 사이트에서 key를 생성했다.
opendkim-genkey로 Private key 생성을 하려면 아래내용과 같이 처리할 수 있다.
# cd /etc/opendkim/keys/gbminnote.com
# opendkim-genkey -s gbminnote -d gbminnote.com
# chown opendkim:opendkim gbminnote.private
https://dkimcore.org/tools/ 페이지에서 Private key를 생성하는 방법은 다음과 같다.
키가 생성되면 별도의 페이지에서 생성된 키가 표기된다. 생성된 키 페이지는 영구 보관이 아닐 수 있으니 생성된 값을 gbminnote.com.txt 파일에 별도로 기록해 관리하는 것이 좋다.
root@gbminnote:~# cd /etc/opendkim/keys/gbminnote.com/
root@gbminnote:/etc/opendkim/keys/gbminnote.com# cat gbminnote.com.txt
Bind 9 Format
1682301625.gbminnote._domainkey.gbminnote.com. IN TXT (
"v=DKIM1;t=s;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJwxazJmUHSJevbOpLSGmnOieb"
"r4sw5jXaCrD6I4O2s4SS3LZEyCdghnHCu8krXvFBlBSryCBDHTPyWO/NVWSc7vcZ"
"~내용생략~"
"OPW3YrZfJXMmDapDuwIDAQAB")
Tinydns Format
'1682301625.gbminnote._domainkey.gbminnote.com:v=DKIM1;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJwxazJmUHSJevbOpLSGmnOiebr4sw5jXaCrD6I4O2s4SS3LZEyCdghnHCu8krXvFBlBSryCBDHTPyWO/NVWSc7vcZYG82JR6kC3LTVOMeyBIjKK2kFQE+AeUwOvo6vbYVZCq3hxqMdIFh37pGRL2xun7cOPW3YrZfJXMmDapDuwIDAQAB:3600::
Raw format
-----BEGIN PUBLIC KEY-----
~내용생략~
-----END PUBLIC KEY-----
Private key는 생성된 경로에 업로드하였다.
root@gbminnote:/etc/opendkim/keys/gbminnote.com# cat gbminnote.private
-----BEGIN RSA PRIVATE KEY-----
~내용생략~
-----END RSA PRIVATE KEY-----
root@gbminnote:~# ls -l /etc/opendkim/keys/gbminnote.com/*
-rw-r--r-- 1 root root 929 Apr 24 11:19 /etc/opendkim/keys/gbminnote.com/gbminnote.com.txt
-rw-r--r-- 1 root root 891 Apr 24 11:22 /etc/opendkim/keys/gbminnote.com/gbminnote.private
도메인이 여러 개라면 여러 개의 Private key를 생성하여 동일한 방법으로 설정하면 된다.
6) KeyTable 설정
생성 예제: myselector._domainkey.example1.comexample1.com:myselector:/etc/opendkim/keys/domain1.com/myselector.private
root@gbminnote:~# vi /etc/opendkim/KeyTable
1682301625.gbminnote._domainkey.gbminnote.com gbminnote.com:1682301625.gbminnote:/etc/opendkim/keys/gbminnote.com/gbminnote.private
7) SigningTable설정
생성 예제: *@example1.com myselector._domainkey.example1.com
vi /etc/opendkim/SigningTable
*@gbminnote.com 1682301625.gbminnote._domainkey.gbminnote.com
8) TrustedHosts설정
root@gbminnote:~# vi /etc/opendkim/TrustedHosts
gbminnote.com
9) 퍼미션 변경
root@gbminnote:~# chown -R opendkim: /etc/opendkim/
root@gbminnote:~# chmod -R 750 /etc/opendkim/keys/
root@gbminnote:~# chmod -R 600 /etc/opendkim/keys/gbminnote.com/gbminnote.private
10) postfix연동
root@gbminnote:~# vi /etc/postfix/main.cf
+ # DKIM config
+ milter_default_action = accept
+ milter_protocol = 2
+ smtpd_milters = inet:localhost:8891
+ non_smtpd_milters = inet:localhost:8891
11) 서비스 재시작
root@gbminnote:~# /etc/init.d/opendkim restart
Restarting opendkim (via systemctl): opendkim.service.
root@gbminnote:~# /etc/init.d/postfix restart
Restarting postfix (via systemctl): postfix.service.
12) 서비스 체크 절차
메일 로그 체크
root@gbminnote:~# tail /var/log/mail.log
Apr 24 11:45:13 gbminnote opendkim[4670]: OpenDKIM Filter v2.11.0 terminating with status 0, errno = 0
Apr 24 11:48:36 gbminnote opendkim[5016]: OpenDKIM Filter v2.11.0 starting
Apr 24 11:48:42 gbminnote postfix/postfix-script[5041]: stopping the Postfix mail system
Apr 24 11:48:42 gbminnote postfix/master[2626]: terminating on signal 15
Apr 24 11:48:43 gbminnote postfix/postfix-script[5575]: starting the Postfix mail system
Apr 24 11:48:43 gbminnote postfix/master[5577]: daemon started -- version 3.6.4, configuration /etc/postfix
프로세스 체크
root@gbminnote:~# ps -ef | grep opendkim | grep -v grep
opendkim 5014 1 0 11:48 ? 00:00:00 /usr/sbin/opendkim
opendkim 5016 5014 0 11:48 ? 00:00:00 /usr/sbin/opendkim
postfix설정 값 체크
root@gbminnote:~# postconf | grep milter_default_action
milter_default_action = accept
root@gbminnote:~# postconf | grep milter_protocol
milter_protocol = 2
root@gbminnote:~# postconf | grep smtpd_milters
non_smtpd_milters = inet:localhost:8891
smtpd_milters = inet:localhost:8891
포트 체크
root@gbminnote:~# netstat -nlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:9119 0.0.0.0:* LISTEN 707/sshd: /usr/sbin
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 5577/master
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 664/systemd-resolve
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 3892/sshd: root@pts
tcp 0 0 127.0.0.1:8891 0.0.0.0:* LISTEN 5016/opendkim
tcp6 0 0 :::9119 :::* LISTEN 707/sshd: /usr/sbin
tcp6 0 0 :::25 :::* LISTEN 5577/master
tcp6 0 0 ::1:6011 :::* LISTEN 3892/sshd: root@pts
udp 0 0 127.0.0.53:53 0.0.0.0:* 664/systemd-resolve
13) DKIM, DMARC DNS 설정
DNS에 다음과 같은 레코드를 등록해 키 값을 넣어준다.
domain : gbminnote.com
type : TXT
subname : 1682301625.gbminnote._domainkey
content : "v=DKIM1;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJwxazJmUHSJevbOpLSGmnOiebr4sw5jXaCrD6I4O2s4SS3LZEyCdghnHCu8krXvFBlBSryCBDHTPyWO/NVWSc7vcZYG82JR6kC3LTVOMeyBIjKK2kFQE+AeUwOvo6vbYVZCq3hxqMdIFh37pGRL2xun7cOPW3YrZfJXMmDapDuwIDAQAB"
domain : gbminnote.com
type : TXT
subname : _dmarc
content : "v=DMARC1; p=quarantine; pct=100; rua=mailto:gbminnote@gmail.com"
14) DNS 설정 체크
root@gbminnote:~# dig @8.8.8.8 1682301625.gbminnote._domainkey.gbminnote.com TXT +short
"v=DKIM1;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJwxazJmUHSJevbOpLSGmnOiebr4sw5jXaCrD6I4O2s4SS3LZEyCdghnHCu8krXvFBlBSryCBDHTPyWO/NVWSc7vcZYG82JR6kC3LTVOMeyBIjKK2kFQE+AeUwOvo6vbYVZCq3hxqMdIFh37pGRL2xun7cOPW3YrZfJXMmDapDuwIDAQAB"
root@gbminnote:~# dig @8.8.8.8 _dmarc.gbminnote.com TXT +short
"v=DMARC1; p=quarantine; pct=100; rua=mailto:gbminnote@gmail.com"
14) DKIM 키 설정 체크 방법
- 첫 번째 방법: opendkim-testkey로 체크하는 방법
ex) opendkim-testkey -d 도메인 -s Selector -vvv
opendkim-testkey: usage: opendkim-testkey [options]
-d domain domain name
-k keypath path to private key
-s selector selector name
-v increase verbose output
-x conffile configuration file
DNS 키등록이 안되었을 때
root@gbminnote:~# opendkim-testkey -d gbminnote.com -s 1682301625.gbminnote -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key '1682301625.gbminnote._domainkey.gbminnote.com'
opendkim-testkey: '1682301625.gbminnote._domainkey.gbminnote.com' record not found
정상 등록 되었을 때
root@gbminnote:~# opendkim-testkey -d gbminnote.com -s 1682301625.gbminnote -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key '1682301625.gbminnote._domainkey.gbminnote.com'
opendkim-testkey: key not secure
opendkim-testkey: key OK
- 두 번째 방법: https://mxtoolbox.com/SuperTool.aspx 에서 체크하는 방법
ex) dkim:도메인:selecter
dkim:gbminnote.com:1682301625.gbminnote
15) DKIM 메일 발송 테스트 및 헤더 체크
메일 발송 테스트
root@gbminnote:~# echo "dkim mail sending test" | mail -s "dkim mail sending test" -r "root@gbminnote.com" gbminnote@gmail.com
로그 확인
Apr 24 13:54:30 gbminnote postfix/pickup[9542]: 1A8E118162A: uid=0 from=<root@gbminnote.com>
Apr 24 13:54:30 gbminnote postfix/cleanup[9558]: 1A8E118162A: message-id=<20230424045430.1A8E118162A@gbminnote.com>
Apr 24 13:54:30 gbminnote opendkim[8981]: 1A8E118162A: DKIM-Signature field added (s=1682301625.gbminnote, d=gbminnote.com)
Apr 24 13:54:30 gbminnote postfix/qmgr[9543]: 1A8E118162A: from=<root@gbminnote.com>, size=396, nrcpt=1 (queue active)
Apr 24 13:54:32 gbminnote postfix/smtp[9554]: 1A8E118162A: to=<gbminnote@gmail.com>, relay=gmail-smtp-in.l.google.com[108.177.125.27]:25, delay=1.9, delays=0.05/0/1.2/0.65, dsn=2.0.0, status=sent (250 2.0.0 OK 1682312071 k29-20020a63ff1d000000b005211b187370si10069746pgi.457 - gsmtp)
Apr 24 13:54:32 gbminnote postfix/qmgr[9543]: 1A8E118162A: removed
구글 수신 메일 확인(원문보기)
메일 헤더 정보
이렇게 OpenDKIM을 구축함으로써 메일의 신뢰성과 보안을 한층 강화할 수 있다. DKIM은 메일 발신자의 도메인 인증을 통해 스팸, 피싱, 사기성 메일을 방지하고, 신뢰할 수 있는 이메일 환경을 제공한다. 특히 대량의 이메일을 발송하는 비즈니스나 도메인 신뢰도가 중요한 경우, DKIM 구축은 필수적이며. DMARC와 함께 사용하면 메일 인증 실패 시 적절한 대응을 할 수 있어, 전반적인 이메일 보안 체계를 더 강력하게 유지할 수 있다. 안정적이고 신뢰할 수 있는 메일 시스템을 원한다면 DKIM은 필수적으로 사용해야 할 도구가 되어가고 있다.