#email #smtp #milter #sendmail #postfix


Bindings to the sendmail milter library

13 releases

new 0.2.3 May 3, 2021
0.2.2 Jan 7, 2021
0.2.1 May 17, 2020
0.2.0 Feb 9, 2020
0.1.4 Nov 26, 2019

#12 in Email

Download history 17/week @ 2021-01-12 27/week @ 2021-01-19 7/week @ 2021-01-26 8/week @ 2021-02-02 32/week @ 2021-02-09 112/week @ 2021-02-16 16/week @ 2021-02-23 14/week @ 2021-03-02 8/week @ 2021-03-09 32/week @ 2021-03-16 38/week @ 2021-03-23 45/week @ 2021-03-30 20/week @ 2021-04-06 51/week @ 2021-04-13 44/week @ 2021-04-20 30/week @ 2021-04-27

146 downloads per month
Used in 2 crates


786 lines


The milter library provides Rust bindings to libmilter, the sendmail mail filter API.

This library serves the creation of milters: mail filtering applications that can be integrated with MTAs (mail servers) such as Postfix.


This crate requires the milter C library (libmilter) to be available.

On Debian and Ubuntu, install the package libmilter-dev.

If your distribution does not provide pkg-config metadata for libmilter, try using the provided milter.pc file when executing the build:

PKG_CONFIG_PATH=. cargo build

The integration tests of this crate require the third-party miltertest utility in order to exercise the test milters. This program can be found among the OpenDKIM command-line tools.

On Debian and Ubuntu, install either the miltertest or the opendkim-tools package (only required when working on the milter crate itself).

The minimum supported Rust version is 1.42.0.


The main use case of this library is creating milter applications, that is, executable programs with a main function.

Include libc in addition to milter in Cargo.toml:

milter = "0.2"
libc = "0.2"

Here’s a simple milter application that logs client IP addresses:

use milter::{on_connect, Context, Milter, Status};
use std::net::SocketAddr;

fn handle_connect(
    _: Context<()>,
    _: &str,
    socket_addr: Option<SocketAddr>,
) -> Status {
    if let Some(socket_addr) = socket_addr {
        println!("Connect from {}", socket_addr.ip());


fn main() {
        .expect("milter execution failed");

Refer to the API documentation for complete usage instructions.


This package includes an example milter inspect, which prints all arguments and macros for each stage, and so is immediately useful as a view into how milters operate, and what shape the received data has.

Start the inspect example by passing a socket spec with an unused port (again, if your distribution does not provide the requisite pkg-config metadata, you may need to adjust PKG_CONFIG_PATH, see above):

cargo run --example inspect inet:3000@localhost

After the milter has started, configure the MTA – Postfix – to connect to it. Add the following parameters to /etc/postfix/main.cf, and reload the Postfix configuration:

smtpd_milters = inet:localhost:3000
non_smtpd_milters = $smtpd_milters

The inspect milter will then print everything it receives from Postfix.


Copyright © 2019–2021 David Bürgin

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.


~21K SLoC