Customize direct-delivery Postfix configuration

If you have a mail receiver container which requires customised Postfix configuration, this is the topic for you. Herein are described the steps required to set Postfix main.cf configuration variables to whatever your heart desires.

Postfix configuration variables can be set via the container environment. Any environment variable starting with POSTCONF_ will set a Postfix configuration variable named for the rest of the environment variable to the value of the environment variable. For example, if you set the environment variable POSTCONF_always_bcc to bob@example.com, then Postfix will be configured with always_bcc = bob@example.com, which will send a copy of all incoming mail to Bob. Poor Bob.

Procedure

  1. Figure out what configuration variables you want to set, and what values to set them to. This may be done by reading the fine manual, or through recommendations in other Discourse documentation, or otherwise.

  2. Connect to your Discourse server via SSH, grab some root privileges, and head over to where all the discourse-docker configuration lives:

    ssh ubuntu@192.0.2.42
    sudo -i
    cd /var/discourse
    
  3. Open up containers/mail-receiver.yml in your text editor of choice, and swing down to the env: section of the file. Somewhere in there, add entries for the variables you want to add, being careful to not modify anything else, and maintaining appropriate indenting. For example, if we were adding our always_bcc setting, the file might look a bit like this:

    env:
      LANG: en_US.UTF-8
      MAIL_DOMAIN: discourse.example.com
      DISCOURSE_BASE_URL: 'https://discourse.example.com'
      DISCOURSE_API_KEY: abcdefghijklmnop
      DISCOURSE_API_USERNAME: system
    
      POSTCONF_always_bcc: 'bob@example.com'
    

    Once you’re happy with what you’ve added, save and exit your editor.

  4. To load the configuration, you simply have to restart the mail-receiver container (a rebuild is not required):

    ./launcher restart mail-receiver
    

    After a brief spasm, the container should be running again.

  5. Test your changes. Ensure both that what you wanted to have happen has, indeed, happened, and also that nothing you didn’t expect to change hasn’t.

Addendum: adding files to the mail-receiver container

Many Postfix configuration parameters require access to “database files”, which provide key/value information which Postfix uses to make decisions about what do with mail. If you see that a configuration parameter accepts a filename that looks like hash:/some/file, you’ve found a use for database files.

The thing is, Postfix running inside the container needs to be able to get at those files while it’s running, which means you need to either copy those files into the container, or (preferably) put those files into a directory on the host, and then mount that directory as a volume inside the container. These instructions describe the second method.

Once you have completed this procedure, any file you place into /var/discourse/shared/mail-receiver/etc will immediately become visible at /etc/postfix/shared inside the container, and any changes you make to those files will be immediately visible to Postfix.

Here’s how to make it happen.

  1. If you’re not still logged in as root to your Discourse server, do so again:

    ssh ubuntu@192.0.2.42
    sudo -i
    cd /var/discourse
    
  2. Open up containers/mail-receiver.yml in your text editor of choice, and this time head for the volume: section. Underneath the existing definition for the /var/spool/postfix directory, add another one, so that your volume section looks like this:

    volumes:
      - volume:
          host: /var/discourse/shared/mail-receiver/postfix-spool
          guest: /var/spool/postfix
      - volume:
          host: /var/discourse/shared/mail-receiver/etc
          guest: /etc/postfix/shared
    

    Save/exit your editor.

  3. To attach the new volume, you simply have to restart the mail-receiver container (a rebuild is not required):

    ./launcher restart mail-receiver
    

All done!

10개의 좋아요

Matt, do you think that could be possible to enable accounts like admin@domain or info@domain from this Postfix configuration?

I only need to have a couple of addresses for incoming e-mail and I have it working with Discourse but I can’t set accounts (their seem to be blocked by default even though messages are processed).

Thanks for all your guides related.

Digital Ocean과 Mailgun을 사용하여 발신 이메일을 처리하도록 Discourse 트라이얼 서비스를 설정했습니다. Digital Ocean IP 주소를 가리키는 적절한 MX 레코드가 있는 도메인을 등록해 두었습니다. Discourse에서 발신 및 수신 이메일이 모두 정상적으로 작동합니다. 주제에 대한 답변은 알림이 설정된 사용자에게 발신 이메일을 생성하며, 테스트 사용자는 해당 이메일에 답변할 수 있고 게시글이 Discourse에 표시됩니다. 지금까지는 문제가 없습니다.

위와 같이 POSTCONF_always_bcc: 옵션을 추가해 보았지만 작동하지 않는 것 같습니다. ‘app’ 부분은 Mailgun을 통해 이메일을 보내는 방법을 알고 있지만( app.yml에 Mailgun 서버의 사용자 이름과 비밀번호가 포함되어 있음), ‘mail-receiver’ 부분이 Mailgun을 통해 이메일을 제대로 보내지 못하는 것 같습니다. mail-receiver 설정 파일에 이 정보를 입력하는 방법에 대한 예시를 본 적이 없습니다.

always_bcc 옵션이 읽히고 처리되고 있다는 것은 알고 있습니다. 다음을 입력하면:

./launcher enter mail-receiver

그런 다음

mailq

을 실행하면, 전송을 시도 중인 제가 보낸 테스트 메시지가 큐에 있는 것을 볼 수 있습니다. “-Sender/Recipient-------” 열에는 테스트 메시지가 온 주소, "(unknown mail transport error)"라는 문구, 그리고 always_bcc 설정에 넣었던 이메일 주소가 표시됩니다.

수신 메시지를 어떻게 필터링할 수 있을지 기대했습니다. 예를 들어 postmaster@mydomain 또는 admin@mydomain으로 보내진 메시지는 Discourse에서 처리되지 않고, 대신 Mailgun을 통해 공개 인터넷으로 내 gmail 주소로 재전송되도록 하고 싶습니다. 아마도 @satonotdead 사용자가 하려던 것이 바로 이런 것일 것입니다.

이 작업을 수행하는 방법에 대한 힌트가 있다면 감사하겠습니다!

음. 네, 먼저 메일 수신 설정에 메일 전송 수단을 구성해야 합니다. app.yml에는 자격 증명이나 전송 메커니즘에 대한 정보가 없기 때문입니다. 볼륨 마운트에 관한 다음 섹션에서 힌트된 대로 더 완전한 구성을 추가해야 할 것 같으며, 그 세부 사항은 이 문서의 범위를 벗어납니다.

postmasteradmin 이메일을 어떻게 처리할지에 대한 간단한 해결책은 각 이메일 유형별로 그룹을 생성하고, 해당 이메일을 수신하기를 원하는 사람들을 그 그룹에 추가하는 것입니다. 그러면 그들은 그 이메일들을 그룹 메시지로 처리할 수 있습니다.

3개의 좋아요

Mailgun이 아니라 'mail-receiver’를 의미하신 건가요? 즉, 'mail-receiver’가 공개 인터넷을 통해 Mailgun과 통신하는 방법을 배우고, 자격 증명을 올바르게 전달하여 실제 전달 작업을 수행하도록 요청하는 것을 말씀하시는 건가요?

네. 실수했습니다.

네, 그것도 맞고, 혹은 다른 방식으로 mail-receiver(즉, Postfix)를 구성하여 메일을 어떻게든 전달하도록 하는 것입니다. 개인적으로는 그 방법을 아신다면 mail-receiver를 사용하는 것보다 직접 그 작업을 수행하시는 것이 더 나을 것이라고 생각합니다.

또 다른 해결책은 어떤 <mail thing>domain의 메일을 처리하고 나머지 메일을 mail receiver로, 아마도 다른 MX 레코드를 통해 전달하는 것입니다.

오늘 저녁 내내 수많은 조합을 시도해 본 끝에, Discourse가 실행되는 컨테이너 외부에 postfix를 설치하는 데 성공했고, 명령줄을 통해 Mailgun으로 이메일을 보낼 수 있게 되었습니다. 즉, postfix를 설정하여 Mailgun을 통해 성공적으로 이메일을 전송할 수 있게 된 것입니다. 하지만 이제 Mailgun을 통해 릴레이가 작동하도록 설정할 수 있는 방법을 mail-receiver 컨테이너에 적용하는 데 여전히 막막합니다. 분명 (간단한!) 방법이 있을 텐데, 어떻게 해야 할지 모르겠습니다. 메시지가 메일 큐에 막히는 이유를 파악할 수 있는 로그도 찾지 못하고 있습니다. 제가 마지막으로 리눅스를 사용한 것은 몇 년 전이라, 그때는 컨테이너가 없었습니다. postfix가 어떤 통신을 시도하고 있는지 확인할 수 있도록 로그 기록을 활성화하는 방법이 있을까요? 그러면 문제가 어디에 있는지 파악할 수 있을 것 같습니다. 개념적으로는 admin@mydomain으로 들어온 메일이 Mailgun을 통해 제 개인 Gmail 계정으로 바로 전달되고, category1@mydomain, category2@mydomain 등으로 들어온 메일은 로컬로 Discourse에 전달되어 게시글을 생성하는 데 사용되기를 원합니다.

2개의 좋아요

Discourse 컨테이너 외부, 예를 들어 다른 VPS 또는 데이터센터에서 mail-receiver를 사용할 수 있나요?

아이디어는 프라이버시를 위해 Discourse의 IP 주소를 변경하고, 외부의 "mail-receiver"를 사용하여 Discourse 포럼과 인증 및 연동하는 것입니다.

네. 지금 그렇게 하고 있습니다. 메일 수신기를 Digital Ocean에서 실행 중이고, Discourse는 다른 데이터센터의 서버에서 돌리고 있습니다.

누군가 그 방법을 설명해 주실 수 있나요? 이 사람은 답변만 해줘도 돈을 요구합니다.

질문은 무엇인가요?

서버에 docker가 설치되어 있고 필요한 포트에 접근할 수만 있다면, 메일 수신기를 설정하는 데 특별한 것이 필요하지 않습니다.

메일 수신기를 설정했는데, 빠르고 간단해서 그렇게 했습니다. 그런데 메일 처리를 확인하려고 하면 404 오류가 나요.

제 사이트는 서브도메인 형태로, forum.site.com입니다.

그리고 앱의 메일 수신기에서 엔드포인트는 이렇게 설정되어 있습니다.

DISCOURSE_MAIL_ENDPOINT: ‘http://forum.site.com/admin/email/handle_mail

discourse도 다시 빌드해야 할까요?

404 오류가 발생한다면, 아마도 API 키가 잘못되었기 때문일 것입니다.

2개의 좋아요

기본 API인데도 여전히 404 오류가 발생합니다. 구글 톡으로 보내 드렸으니 확인해 주세요.

1개의 좋아요

SMTP 배너 설정 방법?

MXtoobox’s SuperTool에서 SMTP 배너 검사 관련 문제가 보고되었습니다.
image

일반적으로 EHLO 배너는 MAIL_DOMAIN과 일치해야 하며, 이는 다시 역방향 DNS 포인터(PTR 레코드)와 일치해야 합니다. 따라서 제 mail-receiverdiscourse.example에서 실행된다면, POSTCONF_myhostnamediscourse.example이어야 합니다.

EHLO 배너를 올바르게 설정하는 방법은 무엇일까요?

처음에는 mail-receiver.yml에서 HOSTNAME을 설정하여 /etc/postfix/mail-receiver-environment.json의 원래 host-mail-receiver.localdomain을 대체하려 했습니다. 하지만 이는 /etc/hostname을 변경하지도 않고, Postfix 설정의 myhostname도 변경하지 않습니다.

POSTCONF_myhostname을 사용하려는 유혹이 있지만, $myhostname이 여러 곳에서 사용되므로 /etc/hostname과 더 이상 일치하지 않게 되어 원치 않는 부작용이 생길까 두려워합니다.

root@host-mail-receiver:/etc/postfix# postconf | grep myhostname
lmtp_lhlo_name = $myhostname
local_transport = local:$myhostname
milter_macro_daemon_name = $myhostname
myhostname = host-mail-receiver.localdomain
myorigin = $myhostname
smtp_helo_name = $myhostname
smtpd_proxy_ehlo = $myhostname
root@host-mail-receiver:/etc/postfix# cat /etc/hostname
host-mail-receiver

Discourse-setup에서 요구하는 설정이 하나 있습니다. 이름이 기억나지 않고, 휴대폰에서 찾기에도 어렵습니다. 소스를 확인하거나 직접 실행해 보실 수 있습니다.

Postfix 설정 smtp_helo_nameHELO(또는 EHLO) 명령에 지정된 이름을 변경하지만, 이는 발신 전달 설정이며 SMTP 배너는 수신 시 전송됩니다. 해당 설정에서 기본적으로 지정되는 호스트명은 myhostname에서 가져오지만, smtpd_banner 설정을 사용하여 배너에 다른 내용을 표시하도록 수정할 수 있습니다.

1개의 좋아요

이것이 다른 분들에게 도움이 될지 모르겠지만, 저도 비슷한 문제를 겪고 있었고, 이 덕분에 API 키를 무효화한 상태였다는 것을 알게 되었습니다. 무효화를 해제하자 수신 메일이 다시 정상적으로 작동했습니다.

API 키와 관련이 있다는 것을 깨닫게 해 주셔서 감사합니다 :slightly_smiling_face:

1개의 좋아요

이 글이 작성된 이후에 무언가가 변경되었을까요? env: 아래에 POSTCONF_smtpd_banner 값을 추가했는데, 여러 번 다시 시작해도 절대 반영되지 않더군요. 적용되려면 재빌드(./launcher rebuild mail-receiver)를 해야 했습니다.

안녕하세요 여러분,

도메인 마이그레이션(Change the domain name or rename your Discourse 참고)을 마쳤고, 과정은 순조롭게 진행되었습니다. 다만, 몇몇 카테고리로의 수신 메일을 위해 MX 레코드와 함께 mail-receiver 컨테이너를 사용하고 있습니다.

제가 확인한 바로는, 컨테이너의 기본 설정에서 수신 도메인과 LetsEncrypt 인증서 경로가 하드코딩되어 있습니다. 설정 파일이나 고급 옵션을 통해 두 개의 도메인을 허용할 수 있을까요?