Coder Social home page Coder Social logo

smtprelay's Introduction

smtprelay

Go Report Card

Simple Golang based SMTP relay/proxy server that accepts mail via SMTP and forwards it directly to another SMTP server.

Why another SMTP server?

Outgoing mails are usually send via SMTP to an MTA (Mail Transfer Agent) which is one of Postfix, Exim, Sendmail or OpenSMTPD on UNIX/Linux in most cases. You really don't want to setup and maintain any of those full blown kitchensinks yourself because they are complex, fragile and hard to configure.

My use case is simple. I need to send automatically generated mails from cron via msmtp/sSMTP/dma, mails from various services and network printers via a remote SMTP server without giving away my mail credentials to each device which produces mail.

Main features

  • Simple configuration with ini file .env file or environment variables
  • Supports SMTPS/TLS (465), STARTTLS (587) and unencrypted SMTP (25)
  • Checks for sender, receiver, client IP
  • Authentication support with file (LOGIN, PLAIN)
  • Enforce encryption for authentication
  • Forwards all mail to a smarthost (any SMTP server)
  • Small codebase
  • IPv6 support

smtprelay's People

Contributors

alex1989hu avatar benubois avatar beppler avatar ca0s avatar coronon avatar decke avatar dependabot[bot] avatar jonathonreinhart avatar markgardner avatar nousefreak avatar nwillems avatar simon04 avatar szonov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

smtprelay's Issues

(X)OAUTH2 support

Are you willing to add support OAUTH2/XOAUTH2? It's an authentication for SMTP, based on OAuth2. Google uses it, as well as other providers.

My use case: I have some devices (printer, router, etc.) that support only standard SMTP authentication, and I want to use a Google e-mail address to send e-mails. This can be done either by using a device-specific password (but this requires a 2-step authentication) or XOAUTH2 method.

I'm testing some modifications to smtprelay to add support for this. Basically, there is another small program that is used to get access and refresh tokens from Google (in theory, that should be done only once, when configuring smtprelay) and then I added a new "authenticator" in the SMTP client to support this (in addition to plain and login).

I'll push my modifications in a public repository as soon as I have some time :-) In the meantime, I'm testing/debugging it.

Consider doing a new release

I guess most people will not build this from master and thus not benefit from the dependency updates over the last year.
You may consider doing a new release build.

Enhancing Abuse Prevention in Two-Way Relay Usage

Description

I think that smtprelay is designed for one-way relay. However, when attempting to use it as a two-way relay, the result was receiving a significant amount of spam attacks from attackers. Therefore, I would like to address and improve this issue when using it as a two-way relay.

Jun 17 08:30:12 server02 smtprelay: time="2023-06-17T08:30:12+09:00" level=info msg="delivering mail from peer using smarthost" [email protected] host="mail.some.tld:587" peer=84.54.50.150 to="[[email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]]" uuid=1d56fb66-f036-46cb-909b-d954d2ea4820
Jun 17 08:30:13 server02 smtprelay: time="2023-06-17T08:30:13+09:00" level=info msg="delivering mail from peer using smarthost" [email protected] host="mail.some.tld:587" peer=84.54.50.150 to="[[email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]]" uuid=daf813be-4853-4dc0-99b9-9701d8006920
Jun 17 08:33:24 server02 smtprelay: time="2023-06-17T08:33:24+09:00" level=error msg="delivery failed" error=EOF [email protected] host="mail.some.tld:587" peer=84.54.50.150 to="[[email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]]" uuid=865030e0-3978-4086-94db-3ac167711254

Suggestion

In my opinion, there is a need to make the following changes to the routines of conenctionChecker and recipientChecker. It is necessary to validate the recipients first before validating the peer.

gnh1201@b4bf72a

empty body

I have a use case where an older copy machine sends its scans via smtp and I am using smtprelay for that purpose. My email delivery API doesn't accept an empty body, which the copy machine tries to send, so I have a fork that adds the body. I am also adding some headers to prevent the messages from threading even though they have the same subject.

I was wondering if features like default body or append to body, or default subject or append to subject would be useful to anyone else or valuable in a PR.

remote_sender Parameter not working as expected

; Relay all mails to this SMTP servers.
; If not set, mails are discarded.
;
; Format:
;   protocol://[user[:password]@][netloc][:port][/remote_sender][?param1=value1&...]
;
;   protocol: smtp (unencrypted), smtps (TLS), starttls (STARTTLS)
;   user: Username for authentication
;   password: Password for authentication
;   remote_sender: Email address to use as FROM
;   params:
;     skipVerify: "true" or empty to prevent ssl verification of remote server's certificate
;     auth: "login" to use LOGIN authentication

remotes = starttls://[email protected]:[email protected]:587/[email protected]

The above configuration should based on my understanding take the parameter remote_sender and rewrite any FROM portion of the request to use that email to the upstream provider. Instead it just rejects the SMTP request.

Oct 14 15:08:13  Mailbox unavailable. The server response was: 5.7.1 Submission not allowed for messages in which header from does not match MAIL FROM

retry send

please consider to add
a send retry function
when delivery failed with error like dial tcp address for timeout, etc

proxy support

Please consider to add http proxy / socks5 proxy support to connect to smtp server

.env

Would you consider using .env for configuration so the binary could be portable? I can PR if you're open to the idea.

Option to disable logfile

Hi, is it possible to disable the manual logfile the program writes?

I would run this as a systemd service, and in that case systemd-journald automatically captures the STDOUT of the program and keeps it in a log, with control over rotation and standardized commands to get the logs.

I tried commenting out the config line:

;logfile = /var/log/smtprelay.log

but it just defaulted to the same path again. I'm trying to NOT have this logfile at all, because it would just take up space and when I try to start my systemd service I get:

โ— smtprelay.service - Simple Golang SMTP relay/proxy server
     Loaded: loaded (/etc/systemd/system/smtprelay.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2021-03-17 14:59:20 CET; 6s ago
    Process: 34965 ExecStart=/usr/local/bin/smtprelay --config /etc/smtprelay/config.ini (code=exited, status=1/FAILURE)
   Main PID: 34965 (code=exited, status=1/FAILURE)

Mar 17 14:59:20 myserver systemd[1]: Started Simple Golang SMTP relay/proxy server.
Mar 17 14:59:20 myserver smtprelay[34965]: 2021/03/17 14:59:20 Error opening logfile: open /var/log/smtprelay.log: permission denied
Mar 17 14:59:20 myserver systemd[1]: smtprelay.service: Main process exited, code=exited, status=1/FAILURE
Mar 17 14:59:20 myserver systemd[1]: smtprelay.service: Failed with result 'exit-code'.

because obviously the system account the service runs as doesn't have any unneeded permissions in that directory (/var/log).

Passwords with /

Hi

I am looking to use this for AWS SES integration, as it looks like a good fit. Unfortunately, all the SES-generated passwords contain "/" in the password, and this is not handled well. Do you have any suggestions for this?

Config
remotes = starttls://username:pass/[email protected]:587

Error message
level=fatal msg="error parsing url: 'starttls://username:pass/[email protected]:587': parse "starttls://username:pass/[email protected]:587": invalid port ":pass" after host" remotes="starttls://username:pass/[email protected]:587"

Thanks

Docs please.

Hi,
Thanks for the wonderful piece of code.
But adding some documentation on how to build/deploy/config in the README.md is good to have.

doc: Full Usage Guide w/ Working Examples

I just set this up for a client. This is the config we ended up going with.

  • Directory Structure
  • TLS Config via Let's Encrypt / Caddy
  • SMTP Relay Config

Directory Structure

  • caddy (for automated TLS certificates via Let's Encrypt)
  • smtprelay
/home/app/
โ”œโ”€โ”€ .config/
โ”‚   โ”œโ”€โ”€ caddy/
โ”‚   โ”‚   โ”œโ”€โ”€ caddy.env
โ”‚   โ”‚   โ””โ”€โ”€ Caddyfile
โ”‚   โ””โ”€โ”€ smtprelay/
โ”‚       โ”œโ”€โ”€ allowed_users.txt
โ”‚       โ””โ”€โ”€ smtprelay.ini
โ””โ”€โ”€ .local/
    โ””โ”€โ”€ share/
        โ””โ”€โ”€ caddy/
            โ””โ”€โ”€ certificates/
                โ””โ”€โ”€ acme-v02.api.letsencrypt.org-directory/
                    โ””โ”€โ”€ smtp.example.com/
                        โ”œโ”€โ”€ smtp.example.com.crt
                        โ”œโ”€โ”€ smtp.example.com.json
                        โ””โ”€โ”€ smtp.example.com.key

Let's Encrypt TLS Certs via caddy

caddy run --config ~/.config/caddy/Caddyfile --envfile ~/.config/caddy/caddy.env
  1. Install go, xcaddy, and (optional) serviceman via https://webinstall.dev
    curl https://webi.sh/ | sh
    source ~/.config/envman/PATH.env
    
    webi go xcaddy serviceman
    source ~/.config/envman/PATH.env
  2. Build caddy with DNS support (no webserver required). Example w/ DNSimple:
    #!/bin/sh
    
    g_caddy_version='v2.7.6'
    CGO_ENABLED=0 xcaddy build "${g_caddy_version}" \
        --with github.com/caddy-dns/lego-deprecated \
        --output ~/bin/caddy-"${g_caddy_version}"-dnsimple
    
    ln -sf caddy-"${g_caddy_version}"-dnsimple ~/bin/caddy
  3. Configure caddy via ~/.config/caddy/Caddyfile:
    mkdir -p ~/.config/caddy
    touch ~/.config/caddy/caddy.env
    chmod 0600 ~/.config/caddy/caddy.env
    # note: to keep ports 80 and 443 free, use "https://smtp.example.com:1234" 
    # instead of just the hostname here
    smtp.example.com {
            tls {
                   dns lego_deprecated dnsimple
            }
    }
    
  4. Add DNSimple's ENVs to ~/.config/caddy/caddy.env:
    DNSIMPLE_OAUTH_TOKEN='dnsimple_a_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  5. Test the configuration
    caddy run --config ~/.config/caddy/Caddyfile --envfile ~/.config/caddy/caddy.env
  6. Start caddy as a service with serviceman (Linux, macOS, & Windows)
    my_app_user="$(id -u -n)"
    sudo env PATH="${PATH}" \
        serviceman add --system --cap-net-bind \
            --username "${my_app_user}" --name caddy -- \
            caddy run --config ~/.config/caddy/Caddyfile --envfile ~/.config/caddy/caddy.env
    (--cap-net-bind is only necessary if using default ports 80 & 443)

smtprelay config

smtprelay --config ~/.config/smtprelay/smtprelay.ini
  1. Create the config file ~/.config/smtprelay/smtprelay.ini:
    mkdir -p ~/.config/smtprelay/
    touch ~/.config/smtprelay/smtprelay.ini
    chmod 0600 ~/.config/smtprelay/smtprelay.ini
    ; Hostname for this SMTP server
    hostname = smtp.example.com
    
    ; File which contains username and password used for
    ; authentication before they can send mail.
    allowed_users = /home/app/.config/smtprelay/allowed_users.txt
    
    ; Networks that are allowed to send mails to us
    ; Defaults to localhost. If set to "", then any address is allowed.
    ;allowed_nets = 0.0.0.0/0 ::/0
    allowed_nets = 0.0.0.0/0
    
    ; STARTTLS and TLS are also supported but need a
    ; SSL certificate and key.
    ;listen = starttls://0.0.0.0:587 starttls://[::]:587 tls://0.0.0.0:465 tls://[::]:465
    listen = starttls://0.0.0.0:587 tls://0.0.0.0:465
    local_cert = /home/app/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/smtp.example.com/smtp.example.com.crt
    local_key  = /home/app/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/smtp.example.com/smtp.example.com.key
    
    ; Enforce encrypted connection on STARTTLS ports before
    ; accepting mails from client.
    local_forcetls = true
    
    ; Relay Config (ex: Mailgun)
    remotes = starttls://user:[email protected]:587
  2. Set permissions via ~/.config/smtprelay/allowed_users.txt:
    # go run ./smtprelay/cmd/hasher.go 'my-password'
    # <username> <bcrypt-hash> <email,list>
    my-username $2a$10$uZntKVdnFmAZiswYLTl8auUUxeH4wOnAU5C4zz3rGWvMf2iOmhcDy @account.example.com,[email protected]
    
  3. Test the config
    smtprelay --config ~/.config/smtprelay/smtprelay.ini
  4. Test with Curl
    my_smtprelay_host=smtp.example.com
    my_smtprelay_auth='my-user:my-pass'
    
    my_from="[email protected]"
    my_to="[email protected]"
    my_subject='Hello, World!'
    my_ts="$(date '+%F %H:%M:%S')"
    my_text="It's ${my_ts}. Do you know where your emails are?"
    
    my_file="$(mktemp)"
    printf 'From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s\r\n' \
            "${my_from}" \
            "${my_to}" \
            "${my_subject}" \
            "${my_text}" \
            > "${my_file}"
    # requires tls on 465
    curl -v --url "smtps://${my_smtprelay_host}" \
      --ssl-reqd \
      --user "${my_smtprelay_auth}" \
      --mail-from "${my_from}" \
      --mail-rcpt "${my_to}" \
      --upload-file "${my_file}"
  5. Start as a system service with serviceman:
    my_app_user="$( id -u -n )"
    sudo env PATH="${PATH}" \
     serviceman add --system --cap-net-bind \
         --username "${my_app_user}" --name smtprelay -- \
         smtprelay --config ~/.config/smtprelay/smtprelay.ini

Cannot use settings from ini file

I don't know if I am doing something wrong, but it seems that reading the configuration from the ini file doesn't work.

If I try to run smtprelay with ./smtprelay -config smtprelay.ini, execution ends immediately without any output.

Maybe there is something wrong with reading files, because the -logfile parameter also seems not to work.

Tried on Fedora 33 and Raspbian 9.9, builded with go1.18.3.

I get an error message re. SSL when connecting to remote the remote service

swaks -s 10.10.10.11 --to [email protected]

=== Trying 10.10.10.11:25...
=== Connected to 10.10.10.11.
<- 220 localhost.localdomain ESMTP ready.
-> EHLO localhost
<- 250-localhost.localdomain
<- 250-SIZE 10240000
<- 250-8BITMIME
<- 250 PIPELINING
-> MAIL FROM:root@localhost
<- 250 Go ahead
-> RCPT TO:[email protected]
<- 250 Go ahead
-> DATA
<- 354 Go ahead. End your data with .
-> Date: Thu, 03 Dec 2020 15:55:24 -0500
-> To: [email protected]
-> From: root@localhost
-> Subject: test Thu, 03 Dec 2020 15:55:24 -0500
-> Message-Id: 20201203155524.042117@localhost
-> X-Mailer: swaks v20190914.0 jetmore.org/john/code/swaks/
->
-> This is a test mailing
->
->
-> .
<** 554 Forwarding failed
-> QUIT
<- 221 OK, bye

And the log file says:
2020/12/03 15:55:24 new mail from=root@localhost to=[[email protected] peer=[10.10.10.11]
2020/12/03 15:55:24 delivering using smarthost smtp.mailgun.org:587
2020/12/03 15:55:24 delivery failed: x509: certificate signed by unknown authority

Have I got something misconfigured?

How to use variables instead of config file

First of all, thank you for this gold tool :)

Long story short, everything has been fine via Docker and Kubernetes.
But I do require to use variables instead of config files and I am lost a bit.

The config files does mention:

All config parameters can also be provided as environment
; variables in uppercase and the prefix "SMTPRELAY_".
; (eg. SMTPRELAY_LOGFILE, SMTPRELAY_LOG_FORMAT)

So, I would have something like this:

SMTPRELAY_LISTEN = starttls://127.0.0.1:587 
SMTPRELAY_LOCAL_CERT = /etc/smtprelay/tls_pem.pem 
SMTPRELAY_LOCAL_KEY = /etc/smtprelay/tls_key. 
SMTPRELAY_LOCAL_FORCETLS = true 

The problem I am having is how to convert /usr/local/bin/smtprelay -config /etc/smtprelay/smtprelay.ini to use the above.
I would try it like /usr/local/bin/smtprelay SMTPRELAY_LISTEN = starttls://127.0.0.1:587 SMTPRELAY_LOCAL_CERT = /etc/smtprelay/tls_pem.pem but it fails and use its own internal config..

I have also tried something like /usr/local/bin/smtprelay SMTPRELAY="127.0.0.1:25" SMTPRELAY_LOGFILE="/var/log/smtprelay.log" but it again ignores it and uses its internal config.

I cannot find much reference about how to use those variables.

Thank you

config.go allowedUsers not working?

Hi...

Tried well with Thunderbird (for testing) and following config.go settings:

  • remoteHost
  • remoteUser
  • remotePass
  • remoteAuth
  • remoteSender

Created file userlist (Example, password hashed with go run cmd\hasher.go test):
[email protected] $2a$10$SN1obpmbzZoWI9vkrycRNe9V6wr0bsX0SiZvFVGTfM95GwNP.ai0a

Set allowedUsers in config.go pointing to created userlist file:
allowedUsers = flag.String("allowed_users", "userlist", "Path to file with valid users/passwords")

After setting allowedUsers to filename with user and hash in it, I cannot force Thunderbird to send mail with same settings. Checked username and password twice. Checked also different settings for SMTP auth methods. Thunderbird states "Autentication Required."

Did some newbee log outputs to test functions from auth.go.

  • AuthFetch() is called
  • AuthCheckPassword() never called
  • parseLine() never called

Checked with log level debug and trace, but no hints showing up.

Any ideas, what I'm thinking or doing wrong? Or is it a bug?

Regards
Lars

add options passed to smtpd

The smtpd dependency has some configurable options. I have the need to configure MaxConnections, for example. smtprelay.ini should probably include the ability to configure all or most of the options that can be passed to smtpd. I'd be happy to PR if you'd like.

Sender dependent relay host map

Does it support different servers and credentials depending on login as postfix do?

sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relayhost_map
smtp_sender_dependent_authentication = yes 

Provide a Dockerfile

Hi.

I'm using the Fork grafana/smtprelay as container, but their version is just outdated, which doesn't support accepting untrusted remote tls certs.

I would like to copy their Dockerfile and provide it here, to prevent even more forks.

What are your thinking about that? What are your thinking about publishing an official decke/smtprelay image?

Best,
Mike

Hook to scan with rspamd or similar via HTTP

Hi,

Any interest in a PR to allow a scan of the email via a HTTP post to an external agent ?

I have been looking for a while for a simple relay smtp that has the ability to virus scan/spam filter the emails before relaying (not accepting to a local queue and then forwarding). Currently using haraka, but this feels like a cleaner, less complex solution so might have a go at adding it in as a config option

Trying to send to Office365 throws TLS error

Hi

Looks like a great utility, exactly what I was looking for, but I ran into a snag trying to send email to Office365:

Config file:

remote_host = smtp.office365.com: 587

2020/05/14 13:47:41 delivering using smarthost smtp.office365.com:587 2020/05/14 13:47:52 delivery failed: 504 5.7.4 Unrecognized authentication type [HE1PR0401CA0078.eurprd04.prod.outlook.com]

Am using an application password for the authentication, but also tried with a non-MFA account - same error.

[Feature Request] External Command

Hi,

I was wondering if you would consider a feature along the lines of postfix's pipe(8).

This would enable smtprelay to be extended in many ways by piping its output to a user defined script.

I imagine there could be a config option like:

; Pipe messages to external command
;command = /usr/local/bin/script

Thanks for making smtprelay!

Feature Request: Customizable User-Agent Header in smtprelay

Hello,

We are using your smtprelay software and have recently run into a challenge with certain servers that block the connection based on the User-Agent header. We've identified that the connection is being blocked because the recipient server doesn't recognize or accept the default user-agent our software is sending.

To overcome this limitation, we'd like to request a feature where we can customize the User-Agent header in smtprelay to simulate being another email client, thus improving our email deliverability.

For instance, we'd like to set our user-agent to mimic Thunderbird:

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.0

Being able to modify the User-Agent would provide us (and potentially other users of your software) with more flexibility and better deliverability when dealing with servers that have stringent rules on client identification.

We appreciate your consideration of this feature request and look forward to any feedback or updates.

Best regards!

More flexible control over allowed user "from" address

Prior to #7, authorized users could only send from a single email address. #7 allowed that field in the allowedUsers file to be empty, allowing that user to send from any email address.

I would like to have more control, and allow something between 1 and โˆž addreses.

One use case I've identified is very common on Linux machines, running Postfix, where sendmail (without -r or any remapping) will send from [email protected]. That same machine might also run an application that wants to send as [email protected] This won't work with smptrelay today, without allowing the server to send as (anyone)@example.com which is more dangerous.

Options

I have a couple different ideas for handling this:

Option 1

Expand the allowedUsers parts[2] syntax even further with two enhancements:

  • Allow internal.example.com (or perhaps @internal.example.com) to mean (anyone)@internal.example.com
  • Allow a comma-separated list of allowed email addresses

The config file for my stated usecase would be:

appserver  bcrypt-password-hash [email protected],appserver.internal.example.com

Pros:

  • Simple, readable

Cons:

  • Not completely flexible

Option 2

Update the allowedUsers parts[2] syntax to accept a regular expression.

The config file for my stated usecase would be:

appserver passwdhash  ^(app@example\.com|.*@appserver\.internal\.example\.com)$

I'm not sure that this can be implemented without breaking backwards compatibility. For example, consider an old config file like this:

joe passwdhash [email protected]

If we switched parts[2] to unconditionally be a regex, then the pattern [email protected] would erroneously also match:

There are options here:

  • Break compatibility, release a v2.0 with a warning
  • Require a prefix to use regex, e.g. regex::
    joe passwdhash regex:^.*@example.com$
  • Require a config file option that enables regex (e.g. allowed_users_uses_regex = true)
  • Try to auto-detect the use of regex (bad idea; very ambiguous)

Pros:

  • Very flexible
  • Consistent with other config options that allow regex (allowedRecipients, allowedSender)

Cons:

  • Less readable for most use cases
  • Hard to implement without breaking backwards compatibility

I suggest Option 1. A regex is probably more powerful than any user will need, and there are a lot of characters allowed in the local-part of an email address that are special in a regex, requiring escaping.

Failed to build

Just go go build . in the root and got

azureuser@stevek-playground 12:50 ~/s/smtprelay master> go mod tidy
go: github.com/chrj/[email protected] requires
github.com/eaigner/[email protected]: invalid version: git fetch -f origin refs/heads/:refs/heads/ refs/tags/:refs/tags/ in /home/azureuser/go/pkg/mod/cache/vcs/b1a9951edebf25b789a34398ad65880e06631bf718a381c881083257167b44d8: exit status 128:
fatal: could not read Username for 'https://github.com': terminal prompts disabled
go: github.com/chrj/[email protected] requires
github.com/eaigner/[email protected]: invalid version: git fetch -f origin refs/heads/:refs/heads/ refs/tags/:refs/tags/ in /home/azureuser/go/pkg/mod/cache/vcs/b1a9951edebf25b789a34398ad65880e06631bf718a381c881083257167b44d8: exit status 128:
fatal: could not read Username for 'https://github.com': terminal prompts disabled

Not having time to look at it though but better the author should make sure it builds nicely, given that it is golang, building mod is pretty much straight forward.

Password with special characteres

Hi guys,

After creating a Dockerfile to run the latest smtprelay, I got everything working using a Gmail account with 2FA and an app password.

The problem tho comes when the password has special characters on it.
I am having some issues working that out.

Removing the special characters from the password, it starts.
I have tried that basic scapes I know but got nowhere: ", ', , %

I am running it like this smtprelay -config /etc/smtprelay/smtprelay.ini(currently working with Gmail and App password(2FA))
I need to solve the above to get it working with Office365.

How can I solve this?

Thank you

Errors returned by smtpd.Server.ListenAndServe() are ignored

Problem

Any errors returned by ListenAndServe() are ignored.

For example, trying to run as an unprivileged user:

$ ./smtprelay -logfile smtprelay.log
2021/02/15 01:03:28 Listen on 127.0.0.1:25 ...
2021/02/15 01:03:28 Listen on [::1]:25 ...

The server runs and looks like it is listening, but it is is not (because binding to port 25 is a privileged operation). This is confirmed by looking at lsof -p $(pidof smtprelay) or ss -tnlp.

Cause

The cause is simple: ListenAndServe() is invoked as a goroutine and the return value is lost.

can you provide an example as used as a proxy email relay service?

same as your use case to hide credentials and to be used with other email smtp server.

but how do i send to this local server and then outgoing to another smtp server? can u provide the example? best if can have a failover example and use aws ses as backup in case primary smtp server failed.

[client] -> [smtprelay] -> [smtp backend 1]
                                  -> [smtp backend 2]
                                  -> [aws ses]
                                  ```

Issue warning if configured to require authentication but not TLS

smtpd only allows authentication if the session is operating with TLS:

	if session.server.Authenticator != nil && session.tls {
		extensions = append(extensions, "AUTH PLAIN LOGIN")
	}

This is probably a safe requirement.

However, the following configuration will never work:

$ ./smtprelay -listen ':2525' -allowed_users userlist.txt

If authentication is required (-allowed_users), then a -listen w/o tls:// or starttls:// should be forbidden.

Consider doing a new release

I guess most people will not build this from master and thus not benefit from the dependency updates over the last year.
You may consider doing a new release build (again ๐Ÿ˜).

It looks like the release pipeline is stuck on Windows arm64. I tried to cross-compile master locally and it worked out.

Dockerize the app

Would it be unreasonable request to have an Docker container of this?

doc: Where's the documentation? (Simple Example included)

Since this doesn't have docs on godoc, or usage in the README, I'm just adding some here while I figure out how to use this.

  • Help
  • Config File / ENVs
  • Build
  • Bcrypt Passwords
  • Simple Example
smtprelay -config ~/.config/smtprelay/smtprelay.ini

Test with curl

This looks more complicated than it is because both styles of header need to be specified (in the message file and the mime headers). It may work with just the one in some curl versions. It also requires listening on port 465.

my_smtprelay_host=smtp.example.com
my_smtprelay_auth='my-user:my-pass'

my_from="[email protected]"
my_to="[email protected]"
my_subject='Hello, World!'
my_ts="$(date '+%F %H:%M:%S')"
my_text="It's ${my_ts}. Do you know where your emails are?"

my_file="$(mktemp)"
printf 'From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s\r\n' \
        "${my_from}" \
        "${my_to}" \
        "${my_subject}" \
        "${my_text}" \
        > "${my_file}"

# requires tls on 465
curl -v --url "smtps://${my_smtprelay_host}" \
  --ssl-reqd \
  --user "${my_smtprelay_auth}" \
  --mail-from "${my_from}" \
  --mail-rcpt "${my_to}" \
  --upload-file "${my_file}"

Help

Any unrecognized flag, such as --help, will show the help.

smtprelay --help
Usage of smtprelay:
  -allowed_nets string
    	Networks allowed to send mails (default "127.0.0.0/8 ::1/128")
  -allowed_recipients string
    	Regular expression for valid TO EMail addresses
  -allowed_sender string
    	Regular expression for valid FROM EMail addresses
  -allowed_users string
    	Path to file with valid users/passwords
  -command string
    	Path to pipe command
  -config string
    	Path to config file (ini format)
  -data_timeout string
    	Socket timeout for DATA command (default "5m")
  -hostname string
    	Server hostname (default "localhost.localdomain")
  -listen string
    	Address and port to listen for incoming SMTP (default "127.0.0.1:25 [::1]:25")
  -local_cert string
    	SSL certificate for STARTTLS/TLS
  -local_forcetls
    	Force STARTTLS (needs local_cert and local_key)
  -local_key string
    	SSL private key for STARTTLS/TLS
  -log_format string
    	Log output format (default "default")
  -log_level string
    	Minimum log level to output (default "info")
  -logfile string
    	Path to logfile
  -max_connections int
    	Max concurrent connections, use -1 to disable (default 100)
  -max_message_size int
    	Max message size in bytes (default 10240000)
  -max_recipients int
    	Max RCPT TO calls for each envelope (default 100)
  -read_timeout string
    	Socket timeout for read operations (default "60s")
  -remotes string
    	Outgoing SMTP servers
  -strict_sender
    	Use only SMTP servers with Sender matches to From
  -version
    	Show version information
  -welcome_msg string
    	Welcome message for SMTP session
  -write_timeout string
    	Socket timeout for write operations (default "60s")
error: error parsing commandline arguments: flag provided but not defined: -help

Config File / ENVs

This is the example config file:
https://github.com/decke/smtprelay/blob/master/smtprelay.ini

It can be converted to a the more webdev-friendly ENV format simply by using SMTPRELAY_* with the config options in upper case.

Build

git clone 

pushd ./

go build -o ./smtprelay ./

Bcrypt Passwords

There's a bcrypt hasher in ./cmd/hasher.go

Simple Example

Moved to #149

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.