트러블슈팅 4. SOGo 웹메일에서 euc-kr 메일 한글이 ÀÎÁõ¼­ 처럼 깨질 때 - PCMEISTER 기술 노트
본문 글자 크기

트러블슈팅 4. SOGo 웹메일에서 euc-kr 메일 한글이 ÀÎÁõ¼­ 처럼 깨질 때

mailcow 를 새 서버로 옮기고 나서 웹메일(SOGo)을 이것저것 열어 보는데, 은행이나 결제 대행사에서 온 메일의 한글이 이렇게 보였습니다.

ÀÎÁõ¼­

“인증서” 입니다. euc-kr 바이트를 Latin-1 로 읽으면 딱 이렇게 나옵니다. 깨지는 메일에는 공통점이 있었습니다. 본문이 HTML 이고 문자셋이 euc-kr 이나 ks_c_5601-1987 이었습니다. 국내 은행이나 결제 대행사 안내 메일이 대개 그렇습니다.

SOGo 소스를 찾아보니 HTML 메일을 보여 주는 UIxMailPartHTMLViewer.m 의 _xmlCharsetForCharset 이라는 함수에 문자셋 표가 있었습니다. HTML 을 파싱하기 전에 메일의 문자셋 이름을 이 표에서 찾는데, 표에 없는 이름은 그냥 Latin-1 로 취급합니다. 그 표에 한글 문자셋이 없습니다. 제가 쓰던 SOGo 5.12.9 도 그렇고 업스트림 master 도 그대로였습니다.


mailcow 는 SOGo 를 이미지로 받아 쓰니 소스를 고쳐 다시 빌드하는 건 업데이트 때마다 일이 됩니다. 그래서 mailcow 의 시작 훅(data/hooks/sogo/)에 파이썬 스크립트를 하나 넣어서, 컨테이너가 뜰 때마다 표를 바꾸게 했습니다.

하는 일은 두 가지입니다.

  • SOGo 의 MailPartViewers 번들 안에서 거의 쓸 일이 없는 표 항목 두 개, koi8-u 와 windows-1257 의 문자열과 길이를 euc-kr, ks_c_5601-1987 로 바꿉니다. 이 두 항목은 SOPE 의 iconv 로 변환하는 경로를 타기 때문에 이름만 바꾸면 그대로 iconv 가 한글을 읽습니다.
  • glibc 의 iconv 는 KS_C_5601-1987 이라는 이름을 모릅니다. 그래서 gconv-modules.d 에 UHC(CP949) 의 별칭으로 등록하고 iconvconfig 를 돌립니다.
alias	KS_C_5601-1987//	UHC//

바이너리를 고치는 거라 안전장치를 넣었습니다. 이미 바뀌어 있으면 건너뛰고, 바이너리 구조가 예상과 조금이라도 다르면 아무것도 건드리지 않고 로그만 남기게 했습니다. mailcow 업데이트로 SOGo 가 바뀌어도 최소한 웹메일이 망가지지는 않게요. 적용됐는지는 컨테이너 로그로 확인합니다.

docker compose logs sogo-mailcow | grep korean-charsets
korean-charsets: patched

대가로 KOI8-U(우크라이나어)와 windows-1257(발트어) HTML 메일은 이제 Latin-1 로 보일 겁니다. 그런 메일을 받을 일은 없어서 이쪽을 골랐습니다. 업스트림 표에 한글이 들어가면 훅 파일을 지우고 컨테이너를 다시 만들면 됩니다.

docker compose up -d --no-deps --force-recreate sogo-mailcow

적용하고 나서 문제였던 은행 메일과 PG 사 메일을 다시 열어 보니 한글이 제대로 나왔습니다.

같은 김에 외부 이미지도 항상 보이게 바꿨습니다. sogo.conf 에 SOGoMailDisplayRemoteInlineImages = always; 를 넣으면 새 계정은 바로 적용되는데, 기존 계정은 각자 프로필에 never 가 저장돼 있어서 따로 바꿔 줘야 했습니다.

참고: SOGo 소스, https://github.com/Alinto/sogo

트러블슈팅 시리즈의 글

완료 글 30개 인터넷