Coder Social home page Coder Social logo

gosendmail's Introduction

GoSendmail

A subset of sendmail functionality for modern self hosting.

Motivation

Traditional models of email security are designed around a trusted mail server, and semi-trusted user agents. The mail server should continue to perform reasonably even if an end-user machine is compromised. For single-user domains, realistic threat models are more likely to involve compromise of the publicly connected server, motivating a design minimizing trust in the front server.

GoSendmail is an originating mail transfer agent for this threat model.

It is designed as a counterpoint to maildiranasaurus, which receives email on a semi-trusted server.

Features

  • Sends from an authoritative / stable IP, supporting StartTLS, and with client certificates proving the authoritative sender.
  • Mail DKIM signed with a key that isn't on the authoritative server.

Design

gosendmail provides two binaries which together provide:

  • Santitizing / writing a message ID to identify a new message.
  • DKIM signing / authorization of email.
  • Finding the destination mail server(s) for the message.
  • Speaking the SMTP protocol over secured TLS for delivery.

signmail parses stdin for mail sent via a mutt-like program. It runs santization and dkim signing, and then passes the signed message to another process, based on the sending domain. The sub-process interaction is designed to be interoperable with the semantics of sendmail. (e.g. the final email body is passed to stdin.)

sendmail runs on a semi-trusted server, takes an already signed message, and performs the actual sending to remote MTSs.

Usage

  • go build ./cmd/sendmail ./cmd/signmail
  • copy sendmail to your cloud server (or build it there).
  • Modify config.json for relevant keys and domain(s).
  • Configure Mutt or your MTA to send using the signmail binary.
  • Use the environmental variables GOSENDMAIL_TLS and GOSENDMAIL_SELFSIGNED when insecure mail delivery is desirable. These variable will be read by the sendmail binary, a can be propagated through SSH.

Configuration Options

Environmental Variables

  • GOSENDMAIL_TLS - set to a false-y ("false", "0") value to skip StartTLS
  • GOSENDMAIL_SELFSIGNED - set to a true value ("true", "1") to allow TLS handshakes with servers that present invalid certificates.
  • GOSENDMAIL_RECIPIENTS - overrides the addresses the message will be sent to. This helps support partial resumption of remaining recipients and BCC. If not specified, recipients will be loaded from the To, CC, and BCC fields.

Configuration Options (signmail)

  • DkimKeyCmd The subprocess to execute to retrieve the bytes of the dkim signing key.
  • DkimSelector The DKIM selector, a part of the DKIM dns record. (default: 'default')
  • SendCommand The subprocess to use to send signed messages via the semi-trusted server.

Configuration Options (sendmail)

  • DialerProxy A URL (e.g. socks5://...) that connections to remote MTAs will be dialed through.
  • TLSCert The certificate file for the sender (client) to use for self authentication.
  • TLSKey The corresponding private key file for the sending client to use.

DKIM setup

openssl genpkey -algorithm ed25519 -out domain.dkim.pem
openssl pkey -in domain.dkim.pem -pubout -out domain.dkim.pub
P=openssl asn1parse -in domain.dkim.pub -offset 12 -noout -out /dev/stdout | openssl base64

then the record is v=DKIM1; k=ed25519; p=$P

gosendmail's People

Contributors

dependabot[bot] avatar willscott avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

gosendmail's Issues

Automated server deployment

this may take the form of a dockerfile / kubernetes setup for provisioning.

The goal is to minimize the effort to go from having a registered domain to having a working gosendmail / maildiranasauraus setup on a VM serving that domain.

partial sending / retry

currently there is no queue of messages that have been attempted to be sent.

if a message is partially sent, or if there gray listing that prevents a message from being delivered, but the same message will need to be tried again later, there's no provision for doing so.

Without over-complicating things, a basic setup for resolving this would be:
inflight.json in the same folder as config.json can hold a JSON dictionary keyed on a stable hash of messages.

(the hash would be off of just the sanitized body contents)

The value would contain the current list of remaining recipients, and the canonical message - the ParsedMessage object.

a gosignmail --enqueue invocation would queue a message with remaining work if it is not successfully sent in the immediate invocation attempt.

a gosignmail --resume invocation would iterate through and continue sending any inflight messages.

Logging

Better logging needed for recognizing / responding to partial failures

BCC Handling

sendmail should strip BCC handler after parsing recipients.

external dkim signing

currently, the use of https://github.com/toorop/go-dkim uses an rsa private key for signing.

The signature type is supported by GPG directly, and one could imagine DKIM signing directly with a pre-existing GPG signing key, rather than an on-disk key.

Doing so would require a refactor of the dependency

safe stripping of BCC

sendmail should receive a BCC header, and use it for parsing rcpt's, but should not actually send it.

currently disabled because
the RemoveHeader method seems in its line-ending detection to mess up DKIM.

Without the line-ending re-write, the remove header method doesn't find the expected '\r\n\r\n' sequence to indicate body - presumably the actual byte sequence of message at time of sending is just '\n\n' in some cases.

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.