Skip to content

Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix

Unsolved Linux
  • Hello Mark,

    I’m using and configuring my domain with CloudFlare/virtualmin and would like to be able to use virtualmin and postfix so that applications on my server (like vaultwarden for example) can send emails securely via selhosted SMTP.

    Being a little lost in this jungle, could you do a detailed tutorial with screen for :

    • DNS/Cloudflare configuration (SPF, MX, DKIM, DMARC)
    • Activate email on a virtualmin domain with postfix
    • Configure email postfix on virtualmin and postfix
    • Configure firewall for emailing (virtualkmin)
    • Testing

    Thank a lot in advance.

    DownPW

  • @DownPW can you clarify the “secure” part? For example, are you looking for postfix to secure the email, or will you handle this via the client?

    In addition, under Virtualmin, Postfix is automatically configured per domain and should work without issue.

    Can you clarify?

  • a postfix to secure the email.

    On the other hand, I have not configured anything on the domain name side. No MX, SPF, dmarc or dkim for example hence the request

    @phenomlab said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    In addition, under Virtualmin, Postfix is automatically configured per domain and should work without issue.

    OK so how to test to see if it works correctly ?

    For example, the application I want to use requires include this configuration:

    SMTP_HOST=xxxx.example.com
    SMTP_FROM=xxxx@example.com
    SMTP_FROM_NAME=xxxx
    SMTP_PORT=587 # Ports 587 (submission) and 25 (smtp) are standard without encryption and with encryption via STARTTLS (Explicit TLS). Port 465 is outdated and us>
    SMTP_SSL=true # (Explicit) - This variable by default configures Explicit STARTTLS, it will upgrade an insecure connection to a secure one. Unless SMTP_EXPLICIT_>
    SMTP_EXPLICIT_TLS=false # (Implicit) - N.B. This variable configures Implicit TLS. It's currently mislabelled (see bug #851) - SMTP_SSL needs to be set to true for this o>
    SMTP_USERNAME=user@example.com
    SMTP_PASSWORD=mysmtppassword
    

    and I look at the postfix config in virtualmin, but I don’t see what values ​​are declared.

    And I still have DNS configuration problems at Cloudflare

  • @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    a postfix to secure the email.

    Postfix by default will attempt TLS opportunistic knocking - a process that determines which protocols the receiving host will allow and will then perform a handshake which establishes contact based on those protocols (provided both ends support it - which in most cases, they do). Security between connecting domains is typically certificate based, although you require one certificate minimum for each domain you will be connecting to. As you can imagine, this is not really feasible unless you forward all mail to a relay host and secure that channel with a certificate.

    However, at that point, you are trusting the relay host to send the email in a secure manner which may not always be the case.

    @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    OK so how to test to see if it works correctly ?

    By default, each domain created in Virtualmin will have a corresponding email account for each domain. For example

    38342eee-9ee5-4c08-990f-5919eeb5a5d8-image.png

    As you can see from this example, there is a mail account added here. By default, Virtualmin based domains have email which is accessible at https://yourserver.com:20000 where you can login to that same portal, and access mail sent and received for that domain.

    If you wanted to define the below

    SMTP_HOST=xxxx.example.com
    SMTP_FROM=xxxx@example.com
    SMTP_FROM_NAME=xxxx
    SMTP_PORT=587 
    

    It could look something like the below

    SMTP_HOST=vps.mydomain.com # This is the name of the Virtualmin instance itself
    SMTP_FROM=user@mydomain.com # Change this to the sender email address you want to use
    SMTP_FROM_NAME=xxxx # Change this to the sender name, for example, "John Smith"
    SMTP_PORT=587  # Change this to the port number that the server will answer on. Postfix by default will listen on a variety of ports, with 587 being one of them.
    

    @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    and I look at the postfix config in virtualmin, but I don’t see what values ​​are declared.

    You should not have to modify Postfix in any way unless there is a specific reason to do so.

    @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    And I still have DNS configuration problems at Cloudflare

    By this, do you mean the absence of DKIM, DMARC and SPF or other issues?

  • @phenomlab said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    By this, do you mean the absence of DKIM, DMARC and SPF or other issues?

    yes and MX too

  • @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    yes and MX too

    Ok. MX is the base requirement for mail to be delivered in any circumstance, and all DNS zone files should have a least one entry. For example:

    088f713e-bdb4-4405-9e9c-9c502920b78f-image.png

    The MX record root.phenomlab.com is my VPS server, and yours ideally would be something similar. MX records require a weight based preference to determine order (in my case, 10), and it’s possible to have multiple - for example, 20 would be used to define the next in the list if the primary record is not available.

    In terms of Cloudflare DNS, an example of this is below

    87ffd151-c546-42d2-aeda-adfdde9b41ed-image.png

    There are a number of quality free tools that can help you create DMARC, SPF, and DKIM records as shown below

    DMARC

    https://easydmarc.com/tools/dmarc-record-generator

    DIKM

    https://easydmarc.com/tools/dkim-record-generator

    SPF

    https://easydmarc.com/tools/spf-record-generator

  • @phenomlab said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    By default, Virtualmin based domains have email which is accessible at https://yourserver.com:20000

    hmmm acess seem to work, I log with root but Inbox doesn’t seem to load correctly.

    fd195731-4b44-4671-a6e3-9740be4ebd70-image.png

    After a moment I have this message :

    f3455b91-f7d0-4ed8-80cd-447248289046-image.png

    If I log with my root account like always, I have this :

    e27442e8-fd73-478f-b8ca-62e274b5413a-image.png

    EDIT: seems Ok with other account. Seems root account doesn’t have inbox


    @phenomlab said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    The MX record root.phenomlab.com is my VPS server

    what is root.phenomlab.com on your virtualmin? it’s not a virtual server, jsut your hostname i guess

    For example, I am login to virtualmin on adm.xxxx.fr (hostname of my server) so my mx field should be adm.xxxx.fr and not root.xxxx.fr right?

    for dmarc and dkim, i’am not see for the moment, i see later

    — EDIT:

    my Dmarc configuration

    fe134949-48ad-4b52-96d8-00dd32f12762-image.png

  • 17e39798-932a-497f-8502-f7a8ac7983c1-image.png

    DMARC =

    v=DMARC1;p=reject;sp=reject;pct=100;rua=mailto:xxxxxxx@xxxxxxx.fr;ruf=mailto:xxxxxxx@xxxxxxx.fr;ri=86400;aspf=s;adkim=s;fo=1;
    

    What do you think about it ?

    For DKIM, I don’t quite understand. Once generated in the tools you gave, I understand for the DNS entry in CF but what do I do with the private and public key?

    9abcfcf9-f108-4698-bd0c-d1e26f83123d-image.png

  • Ok I have test to send an email with usermin. No error but email but I don’t receive the email

  • Ok I have test to send an email with usermin. No error but email but I don’t receive the email

    See this to mail queue :

    0a54ffd1-49a0-49e4-ad0e-9ea0b64995e0-image.png

    /var/log/mail.log

    Feb 20 21:26:24 adm postfix/smtp[674993]: E1205627B7: to=<xxxxxxxxxx@caramail.com>, relay=none, delay=4339, delays=4279/0.03/60/0, dsn=4.4.1, status=deferred (connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out)
    Feb 20 21:26:24 adm postfix/smtp[674993]: connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out
    

    Very strange. I’ll stop there for tonight.

  • @DownPW that looks like the port (25) is unreachable. Have you configured the firewall in your Virtualmin server to permit this outbound traffic? Similarly, do you have any other firewall type device between the server and the Internet which could be dropping packets?

  • no Hetzner firewall configured
    no crowdsec

    I have just firewalld of virtualmin by default. I have add 25 and 587 port. Same problem

    image.png

    other log :

    Feb 20 21:40:11 adm postfix/smtpd[679903]: disconnect from unknown[45.129.14.179] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:40:11 adm postfix/smtpd[679903]: warning: unknown[45.129.14.179]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:40:05 adm postfix/smtpd[679903]: connect from unknown[45.129.14.179]
    Feb 20 21:40:05 adm postfix/smtpd[679903]: warning: hostname 179.hosted-by.198xd.com does not resolve to address 45.129.14.179
    Feb 20 21:39:54 adm postfix/smtpd[679911]: disconnect from unknown[45.129.14.179] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:54 adm postfix/smtpd[679911]: warning: unknown[45.129.14.179]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:39:50 adm postfix/smtpd[679903]: disconnect from unknown[45.129.14.128] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:50 adm postfix/smtpd[679903]: warning: unknown[45.129.14.128]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:39:47 adm postfix/smtpd[679911]: connect from unknown[45.129.14.179]
    Feb 20 21:39:47 adm postfix/smtpd[679911]: warning: hostname 179.hosted-by.198xd.com does not resolve to address 45.129.14.179
    Feb 20 21:39:39 adm postfix/smtpd[679903]: connect from unknown[45.129.14.128]
    Feb 20 21:39:39 adm postfix/smtpd[679903]: warning: hostname 128.hosted-by.198xd.com does not resolve to address 45.129.14.128
    Feb 20 21:39:38 adm postfix/smtpd[679911]: disconnect from unknown[45.129.14.179] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:37 adm postfix/smtpd[679911]: warning: unknown[45.129.14.179]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:39:32 adm postfix/smtpd[679903]: disconnect from unknown[45.129.14.128] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:32 adm postfix/smtpd[679903]: warning: unknown[45.129.14.128]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:39:30 adm postfix/smtpd[679911]: connect from unknown[45.129.14.179]
    Feb 20 21:39:30 adm postfix/smtpd[679911]: warning: hostname 179.hosted-by.198xd.com does not resolve to address 45.129.14.179
    Feb 20 21:39:24 adm postfix/smtpd[679903]: connect from unknown[45.129.14.128]
    Feb 20 21:39:24 adm postfix/smtpd[679903]: warning: hostname 128.hosted-by.198xd.com does not resolve to address 45.129.14.128
    Feb 20 21:39:22 adm postfix/smtp[679066]: 1AD316278E: to=<xxxxxxxxxxxx@gmail.com>, relay=none, delay=3410, delays=3260/0.03/150/0, dsn=4.4.1, status=deferred (connect to alt2.gmail-smtp-in.l.google.com[2a00:1450:4025:c03::1a]:25: Connection timed out)
    Feb 20 21:39:22 adm postfix/smtp[679066]: connect to alt2.gmail-smtp-in.l.google.com[2a00:1450:4025:c03::1a]:25: Connection timed out
    Feb 20 21:39:19 adm postfix/smtpd[679911]: disconnect from unknown[45.129.14.179] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:19 adm postfix/smtpd[679911]: warning: unknown[45.129.14.179]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:39:17 adm postfix/smtpd[679903]: disconnect from unknown[45.129.14.128] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:16 adm postfix/smtpd[679903]: warning: unknown[45.129.14.128]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:39:12 adm postfix/smtpd[679911]: connect from unknown[45.129.14.179]
    Feb 20 21:39:12 adm postfix/smtpd[679911]: warning: hostname 179.hosted-by.198xd.com does not resolve to address 45.129.14.179
    Feb 20 21:39:08 adm postfix/smtpd[679903]: connect from unknown[45.129.14.128]
    Feb 20 21:39:08 adm postfix/smtpd[679903]: warning: hostname 128.hosted-by.198xd.com does not resolve to address 45.129.14.128
    Feb 20 21:39:02 adm postfix/smtpd[679911]: disconnect from unknown[45.129.14.179] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:01 adm postfix/smtpd[679911]: warning: unknown[45.129.14.179]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:39:01 adm postfix/smtpd[679903]: disconnect from unknown[45.129.14.128] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:39:00 adm postfix/smtpd[679903]: warning: unknown[45.129.14.128]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:38:55 adm postfix/smtpd[679911]: connect from unknown[45.129.14.179]
    Feb 20 21:38:55 adm postfix/smtpd[679911]: warning: hostname 179.hosted-by.198xd.com does not resolve to address 45.129.14.179
    Feb 20 21:38:53 adm postfix/smtpd[679903]: connect from unknown[45.129.14.128]
    Feb 20 21:38:53 adm postfix/smtpd[679903]: warning: hostname 128.hosted-by.198xd.com does not resolve to address 45.129.14.128
    Feb 20 21:38:52 adm postfix/smtp[679066]: connect to alt1.gmail-smtp-in.l.google.com[2a00:1450:4013:c16::1b]:25: Connection timed out
    Feb 20 21:38:44 adm postfix/smtpd[679903]: disconnect from unknown[45.129.14.128] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
    Feb 20 21:38:43 adm postfix/smtpd[679903]: warning: unknown[45.129.14.128]: SASL LOGIN authentication failed: authentication failure
    Feb 20 21:38:38 adm postfix/smtpd[679903]: connect from unknown[45.129.14.128]
    Feb 20 21:38:38 adm postfix/smtpd[679903]: warning: hostname 128.hosted-by.198xd.com does not resolve to address 45.129.14.128
    Feb 20 21:38:22 adm postfix/smtp[678126]: 73987627BE: to=<xxxxxxxxxxxxxxxxxxxxxxxx@gmail.com>, relay=none, delay=3350, delays=3200/0.03/150/0, dsn=4.4.1, status=deferred (connect to alt2.gmail-smtp-in.l.google.com[2a00:1450:4025:c03::1a]:25: Connection timed out)
    Feb 20 21:38:22 adm postfix/smtp[678126]: connect to alt2.gmail-smtp-in.l.google.com[2a00:1450:4025:c03::1a]:25: Connection timed out
    Feb 20 21:38:22 adm postfix/smtp[679066]: connect to alt1.gmail-smtp-in.l.google.com[142.250.153.26]:25: Connection timed out
    Feb 20 21:37:52 adm postfix/smtp[678126]: connect to alt1.gmail-smtp-in.l.google.com[2a00:1450:4013:c16::1b]:25: Connection timed out
    Feb 20 21:37:52 adm postfix/error[679677]: 20D20627C1: to=<xxxxxxxxxxxxxxx@caramail.com>, relay=none, delay=5027, delays=4967/60/0/0.01, dsn=4.4.1, status=deferred (delivery temporarily suspended: connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out)
    Feb 20 21:37:52 adm postfix/error[679676]: 225BB627B7: to=<xxxxxxxxxxxxxxxxx@caramail.com>, relay=none, delay=3784, delays=3724/60/0/0, dsn=4.4.1, status=deferred (delivery temporarily suspended: connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out)
    Feb 20 21:37:52 adm postfix/smtp[679070]: 1ED2A627AB: to=<xxxxxxxxxxxxxxxx@caramail.com>, relay=none, delay=4432, delays=4372/0.08/60/0, dsn=4.4.1, status=deferred (connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out)
    Feb 20 21:37:52 adm postfix/smtp[679070]: connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out
    Feb 20 21:37:52 adm postfix/error[679676]: 1FBDB627B3: to=<xxxxxxxxxxxxxxxx@caramail.com>, relay=none, delay=3500, delays=3440/60/0/0.01, dsn=4.4.1, status=deferred (delivery temporarily suspended: connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out)
    Feb 20 21:37:52 adm postfix/smtp[679069]: 1DE7B62796: to=<xxxxxxxxxxxxxx@caramail.com>, relay=none, delay=4587, delays=4527/0.07/60/0, dsn=4.4.1, status=deferred (connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out)
    Feb 20 21:37:52 adm postfix/smtp[679068]: 1D536627AE: to=<xxxxxxxxxxxxxxxx@caramail.com>, relay=none, delay=4531, delays=4471/0.05/60/0, dsn=4.4.1, status=deferred (connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out)
    Feb 20 21:37:52 adm postfix/smtp[679067]: 1C5D3627B6: to=<xxxxxxxxxxxxxxxxxxx@caramail.com>, relay=none, delay=3815, delays=3755/0.04/60/0, dsn=4.4.1, status=deferred (connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out)
    Feb 20 21:37:52 adm postfix/smtp[679069]: connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out
    Feb 20 21:37:52 adm postfix/smtp[679068]: connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out
    Feb 20 21:37:52 adm postfix/smtp[679067]: connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out
    Feb 20 21:37:52 adm postfix/smtp[679066]: connect to gmail-smtp-in.l.google.com[142.250.110.27]:25: Connection timed out
    Feb 20 21:37:22 adm postfix/smtp[678126]: connect to alt1.gmail-smtp-in.l.google.com[142.250.153.26]:25: Connection timed out
    Feb 20 21:37:22 adm postfix/smtp[679070]: connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out
    Feb 20 21:37:22 adm postfix/smtp[679069]: connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out
    Feb 20 21:37:22 adm postfix/smtp[679068]: connect to mx00.caramail.com[212.227.15.30]:25: Connection timed out
    Feb 20 21:37:22 adm postfix/smtp[679067]: connect to mx01.caramail.com[217.72.192.76]:25: Connection timed out
    Feb 20 21:37:22 adm postfix/smtp[679066]: connect to gmail-smtp-in.l.google.com[2a00:1450:400c:c0b::1b]:25: Connection timed out
    Feb 20 21:37:05 adm postfix/anvil[677271]: statistics: max cache size 3 at Feb 20 21:27:30
    Feb 20 21:37:05 adm postfix/anvil[677271]: statistics: max connection count 1 for (smtp:45.88.90.174) at Feb 20 21:27:05
    Feb 20 21:37:05 adm postfix/anvil[677271]: statistics: max connection rate 4/60s for (smtp:45.129.14.128) at Feb 20 21:28:06
    Feb 20 21:36:52 adm postfix/smtp[678126]: connect to gmail-smtp-in.l.google.com[142.250.110.27]:25: Connection timed out
    
  • Seems port 25 OK

    image.png

  • @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    For example, I am login to virtualmin on adm.xxxx.fr (hostname of my server) so my mx field should be adm.xxxx.fr and not root.xxxx.fr right?

    Yes, correct.

    @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    For DKIM, I don’t quite understand. Once generated in the tools you gave, I understand for the DNS entry in CF but what do I do with the private and public key?

    The private and public key can simply be stored. You do not have to do anything with these.

  • @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    Seems port 25 OK

    Not sure about that - see below from your server. When sending a telnet request on port 25, there is no response. This typically means the port is closed on your side.

    71978ee1-8be0-41d5-ae6b-68742f02cbd5-image.png

    What SHOULD happen is this

    990ed97c-4449-4936-8c78-95268828839e-image.png

    However, it DOES respond on port 587

    236cd744-7126-4c72-b67e-40b53b2b70f0-image.png

    From recollection, your VPS is being hosted by Hetzner. Although you have no firewall rules in place to prevent outbound connections on port 25, Hetzner by default will block this port until you’ve paid at least one month’s billing, and will only release the block if you formally request it. You’ll need to get the port unblocked before you can proceed - see below

    https://docs.hetzner.com/cloud/servers/faq/#why-can-i-not-send-any-mails-from-my-server

    Unfortunately, email spammers and scammers like to use cloud hosting providers. And we at Hetzner naturally want to prevent this. That’s why we block ports 25 and 465 by default on all cloud servers. This is a very common practice in the cloud hosting industry because it prevents abuse. We want to build trust with our new customers before we unblock these mail ports. Once you have been with us for a month and paid your first invoice, you can create a limit request to unblock these ports for a valid use case. In your request, you can tell us details about your use case. We make decisions on a case-by-case basis.

    As an alternative, you can also use port 587 to send emails via external mail delivery services. Port 587 is not blocked and can be used without sending a limit request.

  • OUPS 🙂

    Ok so I think it’s Hetzner who is blocking.
    I will make them an unblocking request.

  • Indeed. +1 for telnet.

    I just trusted the netstats which told me that everything is OK which is certainly the case on the server.

    since I didn’t have Telnet on hand I tested a website which told me OK

    ba38b6b1-1bbc-497a-b787-81edf7662a6b-image.png

  • @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    since I didn’t have Telnet on hand I tested a website which told me OK

    I have to confess, I installed the telnet-client on your server for diagnostic purposes.

  • @DownPW said in Tutorial for secure emailing with personal domain,Cloudflare, virtualmin and postfix:

    I will make them an unblocking request.

    Curious to know how you got on with this…