목차
로그인 서버를 직접 운영하다 보면 어느 날 이런 문의가 와요. "비밀번호를 잊었는데 어떻게 하죠?" 그때 비밀번호 찾기 버튼이 없다면 그 사람은 다시 들어올 방법이 없어요. 새 계정을 만들거나, 그냥 떠나요.
이 글에서 말하는 로그인 서버는 Keycloak 같은, 여러 서비스의 가입과 로그인을 한곳에서 맡아 주는 오픈소스 프로그램이에요. 아파트 경비실처럼 한 곳에서 출입증을 발급하고 확인해 줘요. 이 경비실이 "출입증을 다시 발급해 드릴게요" 하고 메일을 보내려면 우체국이 필요한데, 그게 바로 SMTP(Simple Mail Transfer Protocol, 메일을 보내는 표준 규칙)를 쓰는 발송 서비스예요.
혹시 이런 고민 있으신가요?
- 비밀번호 찾기를 켜고 싶은데, 메일을 어디서 어떻게 보내야 할지 몰라서 계속 미뤄 두고 있어요.
- 메일 발송 설정은 했는데 받은편지함이 아니라 스팸함으로 들어가요.
- 로그인 서버가 보내는 기본 메일이 영어에 링크 하나뿐이라 사용자가 피싱으로 오해할까 걱정돼요.
이 글을 읽으면
- 이메일 인증과 비밀번호 재설정을 켜는 스위치와, 그 전에 준비할 것을 순서대로 확인할 수 있어요.
- 메일이 스팸으로 빠지지 않도록 발신 도메인에 무엇을 걸어야 하는지 알 수 있어요.
- 메일 본문을 한국어와 우리 서비스의 분위기로 바꾸고, 실제로 도착하는지 확인하는 방법을 알 수 있어요.
1단계. 켜기 전에 메일 길부터 만들기
먼저 결정할 것은 어떤 발송 서비스를 쓸지예요. 로그인 서버가 직접 메일을 쏘는 구조가 아니라, 로그인 서버가 발송 서비스에 "이 주소로 이 내용을 보내 주세요"라고 맡기는 구조예요. 택배를 직접 배달하지 않고 택배사에 맡기는 것과 같아요.
고를 때 확인할 기준은 네 가지예요.
| 기준 | 왜 보나요 | 확인 방법 |
|---|---|---|
| 내 도메인으로 보낼 수 있는가 | 발신 주소가 서비스 도메인이어야 사용자가 믿어요 | 발송 서비스 설정에 도메인 등록 칸이 있는지 |
| 인증 레코드를 도와주는가 | SPF, DKIM, DMARC 가 없으면 스팸으로 가요 | 도메인 관리 화면에서 레코드가 자동으로 생기는지 |
| 월 발송 한도가 충분한가 | 인증 메일과 재설정 메일은 가입자 수에 비례해요 | 한도 숫자와 초과 시 요금 |
| 광고 메일과 나눠 보낼 수 있는가 | 안내 메일과 광고 메일은 법적 성격이 달라요 | 발신 주소나 스트림을 나눌 수 있는지 |
저희는 도메인 관리를 이미 맡기고 있던 곳이 SMTP 발송도 제공해서 그곳으로 정했어요. 도메인과 발송이 한곳에 있으면 인증 레코드가 자동으로 걸려서 손이 덜 가요. 다만 이건 저희 사정이에요. 여러분은 위 표를 채워 보고 가장 막히는 항목이 적은 곳을 고르면 돼요.
참고
비밀번호 재설정 메일은 거래 관계에서 나가는 안내라서 보통 광고성 정보의 사전 동의 대상이 아니라고 알려져 있어요. 다만 저희도 조문까지 직접 확인한 것은 아니에요. 나라와 상황마다 다를 수 있으니, 광고 메일을 같은 길로 보낼 계획이라면 먼저 확인하세요.
한 가지 더 챙길 것이 있어요. 메일 발송 서비스는 사용자의 이메일 주소를 외부 사업자에게 넘기는 일이에요. 개인정보 처리방침에 수탁자(업무를 맡은 외부 업체)로 한 줄 적어 두세요. 나중에 고치면 되겠지 하고 넘기기 쉬운데, 켜는 날 같이 적는 편이 안전해요.
2단계. 발신 도메인에 SPF, DKIM, DMARC 걸기
메일이 스팸으로 가는 가장 흔한 이유는 "이 도메인 이름으로 보낼 자격이 있는 서버가 맞나요?"에 답하지 못해서예요. 받는 쪽 메일 서비스는 그 답을 도메인에 적힌 세 가지 레코드(도메인에 달아 두는 짧은 안내문)로 확인해요.
- SPF: "이 도메인 이름으로 보내도 되는 서버 목록"이에요. 건물 출입 명부와 같아요.
- DKIM: 메일마다 붙는 디지털 도장이에요. 중간에 내용이 바뀌지 않았다는 증명이에요.
- DMARC: 위 둘이 맞지 않는 메일을 받는 쪽이 어떻게 처리할지 정하는 규칙이에요.
도메인 관리 화면에서 한 번에 확인하는 방법이에요. 아래는 레코드의 모양이에요. 값은 발송 서비스가 알려 주는 것을 그대로 써야 해서 자리표시자로 적었어요.
이름 종류 값@ TXT v=spf1 include:<발송 서비스가 알려 준 도메인> ~all<선택자>._domainkey TXT v=DKIM1; k=rsa; p=<공개 키>_dmarc TXT v=DMARC1; p=none; rua=mailto:<리포트를 받을 주소>DMARC 의 p=none 은 "일단 감시만 하고 막지는 말아요"라는 뜻이에요. 처음부터 reject 로 시작하면 설정 실수 하나로 정상 메일이 전부 버려질 수 있어요. 며칠 동안 리포트를 보고 문제가 없으면 quarantine, 그다음 reject 로 올려요.
저희는 도메인과 발송이 같은 곳이라 세 레코드가 켜는 순간 자동으로 걸렸어요. 그래도 확인은 직접 했어요. 자동이라는 말과 실제로 걸렸다는 사실은 다르니까요.
TIP
설정이 끝났으면 본인의 개인 메일 주소로 한 통 보낸 뒤, 메일 원본 보기에서 spf=pass, dkim=pass, dmarc=pass 세 줄을 찾으세요. 셋 다 pass 면 길이 열린 거예요. 하나라도 fail 이면 사용자에게 켜지 마세요.
3단계. Keycloak 에 SMTP 와 스위치 켜기
이제 로그인 서버 쪽이에요. 켜야 할 것은 스위치 세 개와 SMTP 연결 정보예요.
| 설정 | 하는 일 | 주의할 점 |
|---|---|---|
| 비밀번호 재설정 허용 | 로그인 화면에 "비밀번호를 잊으셨나요?" 링크가 생겨요 | 테마가 이 값을 읽어서 링크를 그린다면 코드는 안 바꿔도 돼요 |
| 이메일 인증 | 가입한 사람이 메일 링크를 눌러야 계정이 확인돼요 | 로컬 개발 환경에 메일 서버가 없다면 켜지 마세요. 가입이 막혀요 |
| 이메일로 로그인 허용 | 아이디를 잊어도 이메일과 비밀번호로 들어와요 | 별도의 아이디 찾기 화면을 만들지 않아도 돼요 |
SMTP 연결에는 다음 정보가 들어가요.
호스트 발송 서비스가 알려 준 SMTP 주소포트 465 (처음부터 암호화되는 연결)SSL 켬인증 켬사용자 발송 서비스가 알려 준 계정비밀번호 환경변수에서 읽기 (저장소에 적지 않기)보내는 주소 no-reply@<내 도메인>표시 이름 서비스 이름포트는 서비스마다 465 와 587 중 하나를 안내해요. 465 는 연결하자마자 암호화하고, 587 은 연결한 뒤 암호화로 바꿔요. 발송 서비스 안내를 따르면 되고, 로그인 서버의 SSL 과 StartTLS 칸을 포트에 맞춰서 켜세요.
여기서 많은 분들이 한 번 놀라는 지점이 있어요. 운영 중인 로그인 서버에는 설정 파일을 고쳐도 새 값이 들어가지 않아요. 초기 설정 파일(realm 파일)은 서버가 처음 만들어질 때 한 번만 읽기 때문이에요. 이미 사용자가 있는 서버라면 관리 콘솔의 설정 화면에서 사람이 직접 스위치를 켜고 SMTP 를 입력해야 해요. 파일은 "새로 설치할 때의 기록"으로 남겨 두는 용도예요.
저희는 이렇게 나눴어요. 로컬 개발용 설정 파일에는 비밀번호 재설정과 이메일 로그인만 켜고, 이메일 인증은 꺼 뒀어요. 로컬에 메일 서버가 없어서 켜면 개발자가 가입 자체를 못 해요. 운영 서버에서만 관리 콘솔로 인증을 켰어요.
TIP
스위치를 켜기 전에 관리 콘솔의 이메일 설정 화면에서 "연결 테스트" 버튼으로 자기 주소에 한 통을 보내 보세요. 스위치를 켠 뒤 실패를 발견하면 그 사이에 가입한 사람이 영영 인증 메일을 못 받을 수 있어요.
4단계. 메일 본문을 한국어로 바꾸기
SMTP 가 되면 메일은 나가요. 하지만 기본 메일은 영어이고, 제목과 링크 하나가 전부예요. 사용자 입장에서는 낯선 영어 메일 한 통이라서 스팸이나 피싱으로 보이기 쉽고, 실제로 받는 쪽 메일 서비스의 분류에서도 불리하다고 알려져 있어요.
Keycloak 은 화면 테마와 별개로 메일 테마를 따로 지정해요. 방법은 기본 테마를 부모로 두고 바꾸고 싶은 것만 덮어쓰는 거예요. 파일을 전부 복사하면 나중에 Keycloak 을 올릴 때 원본과 어긋나기 쉬워요.
# theme.propertiesparent=base# messages_en.properties (UTF-8 로 한국어를 그대로 적어요)emailVerifySubject=이메일 주소를 확인해 주세요passwordResetSubject=비밀번호를 다시 정해 주세요저희가 쓴 26 버전대의 Keycloak 은 메시지 파일을 읽을 때 UTF-8 을 먼저 시도해요. 그래서 한국어를 이스케이프 없이 그대로 적을 수 있었어요. 버전에 따라 다를 수 있으니, 글자가 깨져 보이면 이 부분부터 의심하세요. 파일 이름이 영어(_en)인 것도 이상해 보이지만, 로그인 서버의 언어를 따로 켜지 않았다면 영어 묶음을 읽기 때문에 거기에 한국어를 쓰는 거예요.
메일 본문 틀에서 지킨 규칙은 네 가지예요.
- 제목은 사용자가 하려던 일을 그대로 말해요. "비밀번호를 다시 정해 주세요"처럼요.
- 링크 유효 시간을 본문에 적어요. 유효 시간이 지난 링크를 누르면 오류가 나는데, 미리 알려 두면 문의가 줄어요.
- "요청하지 않으셨다면 이 메일을 무시하세요" 한 줄을 꼭 넣어요.
- 이미지는 넣지 않아요. 일부 메일 서비스는 SVG 를 막고, PNG 는 따로 공개 주소를 둬야 해요. 브랜드는 서비스 이름 글자와 색으로만 내요.
HTML 만이 아니라 텍스트 대체본도 있어요. HTML 을 못 여는 메일 앱이 이쪽을 보여 줘요. 저희는 텍스트 틀을 새로 만들지 않고 부모가 읽는 메시지 키만 한국어로 덮어썼어요.
TIP
로컬에 로그인 서버를 띄울 수 없다면 템플릿 엔진(FreeMarker)을 단독으로 돌려서 메일 틀만 렌더링해 보세요. 로그인 서버가 틀에 넘기는 변수(링크, 유효 시간, 서비스 이름)를 같은 이름으로 만들어 넣으면 HTML 이 나오고, 브라우저에서 모양을 볼 수 있어요. 단, 이건 모양 확인일 뿐이고 실제 발송 확인은 따로 해야 해요.
5단계. 흐름을 끝까지 따라가며 확인하기
설정을 마쳤다면 코드 확인과 사람 확인을 나눠서 해요. 메일이 정말 도착하는지는 코드로 알 수 없어요.
사용자 요청부터 새 비밀번호까지의 흐름
확인할 시나리오와 기대하는 결과예요.
| 시나리오 | 기대하는 결과 |
|---|---|
| 가입한 주소로 재설정 요청 | 안내 화면이 나오고 한국어 메일이 도착해요 |
| 가입하지 않은 주소로 재설정 요청 | 같은 안내 화면이 나와요. 가입 여부가 화면으로 드러나면 안 돼요 |
| 메일의 링크로 새 비밀번호 설정 | 그 자리에서 로그인되고, 옛 비밀번호는 안 먹어요 |
| 같은 링크를 두 번 사용 | 두 번째는 거부되고 문구가 한국어예요 |
| 유효 시간이 지난 링크 | 거부되고 다시 요청하도록 안내해요 |
| 아이디를 모르고 이메일로 로그인 | 이메일과 비밀번호로 들어와요 |
두 번째 항목이 보안상 중요해요. "그런 주소는 없습니다"라고 알려 주면 누구든 그 서비스에 가입한 사람이 누구인지 조회할 수 있어요. 존재 여부와 상관없이 "메일을 보냈다면 곧 도착합니다" 같은 같은 문구를 보여 주는 게 맞아요.
그리고 마지막으로, 문서에 적은 것과 실제 동작이 같은지 의심하세요. 저희가 이 흐름을 만들 때 메시지 키 일부는 템플릿 소스를 읽고 넣은 것이어서, 실제 화면으로 확인하기 전까지는 가설이었어요. 운영에서 스위치를 켠 뒤 실제 비밀번호 찾기 메일을 한 번 받아 보고서야 확정했어요.
참고
아직 못 푼 질문도 있어요. 발송이 실패했을 때 감시하고 다시 보내는 장치는 만들지 않았어요. 먼저 한 통이 도착하는 것이 목표였고, 가입자가 늘면 반송 알림을 받아 보는 일을 따로 정할 생각이에요.
자주 묻는 질문
Q1. 가입 때 이메일 인증도 같이 켜야 하나요?
둘은 따로 켤 수 있어요. 다만 인증하지 않은 주소로 재설정 메일을 보내는 건 남의 주소로 가입해 계정을 가로채는 길을 열 수 있어요. 재설정을 켠다면 인증도 함께 켜는 쪽을 권해요. 대신 인증을 켜면 가입 절차가 한 단계 늘어난다는 대가가 있어요.
Q2. 메일이 스팸함으로 들어가요. 무엇부터 볼까요?
받은 메일의 원본 보기에서 SPF, DKIM, DMARC 결과 세 줄부터 보세요. fail 이 있으면 레코드가 틀린 거예요. 모두 pass 인데도 스팸이라면 보내는 주소와 제목, 본문의 링크 도메인이 서로 같은 서비스를 가리키는지 확인해 보세요.
Q3. 개인정보와 관련해 따로 챙길 것이 있나요?
발송 서비스는 이메일 주소를 처리하는 외부 업체예요. 개인정보 처리방침의 수탁자 항목에 적어 두세요. 메일 본문에는 비밀번호나 개인정보를 쓰지 말고, 링크 하나와 안내만 넣어요.
정리
- 켜기 전에 발송 서비스를 고르고 SPF, DKIM, DMARC 부터 걸어
pass를 확인해요. - 로그인 서버에서는 비밀번호 재설정, 이메일 인증, 이메일 로그인을 켜고 연결 테스트를 먼저 해요.
- 운영 중인 서버는 설정 파일이 아니라 관리 콘솔에서 켜요.
- 메일은 한국어 제목, 유효 시간, 무시해도 된다는 한 줄을 넣고 이미지는 빼요.
- 가입하지 않은 주소에도 같은 안내를 보여 주고, 실제 메일 한 통으로 마지막 확인을 해요.
비밀번호 찾기는 화려하지 않지만, 로그인하지 못하는 사람이 서비스로 돌아올 유일한 문이에요. 메일이 도착한다는 사실 하나를 확인하는 데까지 오늘 시간을 써 보세요.