_ ___ ____ ____ ____ _ _ ___ _ |_|_ _ / _ \/ ___/ ___|| _ \ | |_ _ __ | |_ _ __|__ \ _ _ _ _ | |_ _ __ _|_||_|| | | \___ \___ \| |_) || | ' ` \| __| '_ \ _) | ' \| ' \| __| '_ \ |_||_|_|| |_| |___) |__) | __/ | | || || | |_| |_) / _/| || | || | |_| |_) | |_|_|_| \___/|____/____/|_| |_|_||_||_|\__| .__/____|_||_|_||_|\__| .__/ |_| |_| OSSP lmtp2nntp - Mail to News Gateway INSTALLATION ============ To install OSSP lmtp2nntp into /path/to/lmtp2nntp/{sbin,man}/ perform the following steps in your shell: $ ./configure --prefix=/path/to/lmtp2nntp $ make $ make check $ make install CONFIGURATION ============= In order to use OSSP lmtp2nntp, the program has to be integrated into a Mail Transfer Agent (MTA) which speaks Local Mail Transfer Protocol (LMTP). OSSP lmtp2nntp was developed and tested with Sendmail 8.12 and Postfix 2.0, but should also work with other MTAs who provide an LMTP interface. The detailed integration into Sendmail and Postfix is shown below. Sendmail -------- 1. Create a new mailer definition macro file cf/mailer/lmtp2nntp.m4 | | PUSHDIVERT(-1) | | _DEFIFNOT(`LMTP2NNTP_MAILER_PATH', `/usr/local/sbin/lmtp2nntp') | _DEFIFNOT(`LMTP2NNTP_MAILER_FLAGS', `mDFMuXz0') | _DEFIFNOT(`LMTP2NNTP_MAILER_MAX', `8388608') | _DEFIFNOT(`LMTP2NNTP_MAILER_ARGS', `--include /usr/local/etc/lmtp2nntp.conf') | | POPDIVERT | | ######################################### | ### LMTP2NNTP Mailer specification ### | ######################################### | | Mlmtp2nntp, P=LMTP2NNTP_MAILER_PATH, F=LMTP2NNTP_MAILER_FLAGS, | S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, | L=990, T=DNS/RFC822/SMTP, M=LMTP2NNTP_MAILER_MAX, | A=LMTP2NNTP_MAILER_ARGS 2. Use the new mailer definition macro within master control Sendmail and lmtp2nntp can talk LMTP to each other through stdin/stdout. In this case Sendmail spawns a child whenever it wants to talk and no communication channel is already established. The new process execs lmtp2nntp and finally the Sendmail parent and the lmtp2nntp child are connected through a local pipe. sendmail.m4 entry for local pipe | | dnl # Mailer: LMTP2NNTP (mail to news gateway using pipe) | dnl define(`LMTP2NNTP_MAILER_FLAGS', `mDFMuXz0') | dnl define(`LMTP2NNTP_MAILER_PATH', `/usr/local/sbin/lmtp2nntp') | dnl define(`LMTP2NNTP_MAILER_ARGS', `lmtp2nntp --include /usr/local/etc/lmtp2nntp.conf') Alternatively, Sendmail and lmtp2nntp can talk LMTP to each other through a socket. Both BSD network and UNIX domain sockets are supported. In this case Sendmail connects to lmtp2nntp through the network. It is a requirement to start lmtp2nntp in daemon mode as described in the "daemonize" section below. sendmail.m4 entry for network socket | | dnl # Mailer: LMTP2NNTP (mail to news gateway using socket) | define(`LMTP2NNTP_MAILER_FLAGS', `mDFMuXz0') | define(`LMTP2NNTP_MAILER_PATH', `[IPC]') sendmail.m4 entry for UNIX domain socket | | define(`LMTP2NNTP_MAILER_ARGS', `FILE /usr/local/var/lmtp2nntp/lmtp2nntp.socket') sendmail.m4 entry for BSD network socket | | define(`LMTP2NNTP_MAILER_ARGS', `TCP 127.0.0.1 24') In all cases, tell M4 to divert configuration information based your preferences into sendmail.cf. This defines the new "lmtp2nntp" mailer in your Sendmail configuration. Additional steps are required to activate the configuration. sendmail.m4 | | MAILER(lmtp2nntp) 3. Activate the virtual user table and mailer table in your Sendmail M4 configuration sendmail.m4 | | FEATURE(mailertable, `hash -o /path/to/mailertable') | FEATURE(virtusertable, `hash -o /path/to/virtusertable') 4. Add the following entries to your virtual user table and your mailer table virtusertable | | posting+*@gateway.example.com %2@lmtp2nntp.invalid mailertable | | lmtp2nntp.invalid lmtp2nntp:news Notice that we use the RFC2606 top-level domain name ".invalid" for the internal mapping between virtual user table and the mailer table. This is neccessary because Sendmail cannot directly map individual recipient mailbox addresses to outgoing mailers. The token following the colon (news.example.com) in mailertable is passed to mailer as $h. The instructions regarding sendmail.m4 above ignore that fact and assume the address of the NNTP server is configured in lmtp2nntp.conf. However, only the "pipe" mode discussed above is able to catch that information from Sendmail. Simply add '--destination $h' to LMTP2NNTP_MAILER_ARGS and omit 'destination' from the config file. In this example configuration we assume that the machine "gateway.example.com" is the FQDN of machine running Sendmail and OSSP lmtp2nntp and "news" is the remote Usenet News server speaking NNTP. This means that mails addressed to "posting+foo.bar@gateway.example.com" are posted via NNTP as news articles into the newsgroup foo.bar on server "news". Additionally, if the MX RR for "news.example.com" points to the address of "gateway.example.com" you can add the following additional entry to your virtual user table in order to let "news.example.com" virtually provide mail to news gateway functionality: virtusertable | | @news.example.com %1@lmtp2nntp.invalid Notice that there are more delivery modes supported by OSSP lmtp2nntp. Refer to the lmtp2nntp(1) manual page for more details. Postfix ------- 1. Make sure that Postfix was built with PCRE map support (see README.PCRE in the original Postfix source distribution). It basically means building and installing PCRE from ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ and configuring Postfix with at least: | make makefiles \ | CCARGS="-I/path/to/pcre/include -DHAS_PCRE" | AUXLIBS="-L/path/to/pcre/lib -lpcre" 2. In the Postfix main configuration file (main.cf) you have to enable the virtual user and transport mapping tables: main.cf | | virtual_maps = pcre:/usr/local/etc/virtual | transport_maps = hash:/usr/local/etc/transport 3. Add the following entry to the Postfix virtual user mapping table /usr/local/etc/virtual | | /^posting\+(.*)@gateway\.example\.com$/ $1@lmtp2nntp.invalid 4. Add the following entry to the Postfix transport mapping table /usr/local/etc/transport | | lmtp2nntp.invalid lmtp:unix:/path/to/lmtp2nntp.news.example.com Additionally convert the transport mapping table into the hash table format Postfix reads (not required for the virtual user mapping table above, because it is PCRE based). $ postmap /usr/local/etc/transport 5. Assuming you use the "lmtp2nntpd" run command script as described in the next section "Daemonize", start lmtp2nntp daemon and reload Postfix to activate the new setup Note that Postfix does not support LMTP across local pipes as Sendmail does so running a daemon is mandatory. $ lmtp2nntpd start $ postfix reload Daemonize --------- 1. Start lmtp2nntp as a daemon for delivering and listen for incoming connections. lmtp2nntpd | | #!/bin/sh | LMTP2NNTP_PATH='/usr/local/sbin/lmtp2nntp' | LMTP2NNTP_CONF='/usr/local/etc/lmtp2nntp.conf' | case $1 in | start ) | $LMTP2NNTP_PATH --daemonize --include $LMTP2NNTP_CONF | ;; | stop ) | $LMTP2NNTP_PATH --kill --include $LMTP2NNTP_CONF | ;; | esac Configuration ------------- lmtp2nntp.conf | | ## | ## lmtp2nntp.conf -- Mail to News Gateway Configuration | ## | | # --- DAEMON --- | user @l_musr@ | childsmax 3 | pidfile "@l_prefix@/var/lmtp2nntp/lmtp2nntp.pid" | | # --- LMTP SERVER --- | | # server communication on TCP socket (address:port) | #acl 127.0.0.1/32 | #bind 127.0.0.1:24 | | # server communication on Unix domain socket (path:permissions) | bind "@l_prefix@/var/lmtp2nntp/lmtp2nntp.socket:660" | | # server communication on stdin/stdout (remove DAEMON section above) | #bind - | | # server communication limits | timeoutlmtp 0 | timeoutlmtpaccept 0 | timeoutlmtpread 10 | timeoutlmtpwrite 10 | size 8388608 | | # ---- NNTP CLIENT ---- | | # client communication via TCP socket | #client 127.0.0.1 | destination 127.0.0.1:nntp | | # client communication limits | timeoutnntp 30 | timeoutnntpconnect 60 | timeoutnntpread 60 | timeoutnntpwrite 60 | operationmode post | | # ---- GATEWAY OPERATION ---- | | # processing mode | groupmode envelope | mailfrom ".*" | nodename "gateway" | restrictheader "X-Gateway:.*lmtp2nntp" | newsgroup "local.test" | | # remove headers (using empty value) | headerrule '500:^(-EF|Path|Received|To|Cc|Bcc|):$1:' | | # merge values from duplicate headers and separte them with "comma space" | headerrule '510:^(Reply-To):$1:[${msg.header.${1}[#]}${msg.header.${1}[#+1]:+, }]' | | # replace empty Subject with text "None" | headerrule '520::Subject:${msg.header.Subject:-None}' | | # create Message-ID if omitted or illegal (no or more than one '@') | headerrule '530::Message-ID:${msg.header.Message-ID:-@@:s/^.*@.*@.*$//:%createmessageid}' | | # append a header to inhibit bang path addressing for mail replies | headerrule '540::Path:lmtp2nntp!not-for-mail' | | # append a header to avoid message loops with news2mail gateways - see restrictheader | headerrule '610::X-Gateway:lmtp2nntp' | | # append a header to approve posting to a moderated newsgroup | headerrule '620::Approved:gateway@example.com' | | # ---- LOGGING ---- | | # normal operation | l2spec 'info: prefix(prefix="%b %d %H:%M:%S <%L> lmtp2nntp[%P]: ", timezone=local) \ | -> buffer(size=65536) \ | -> file(path="@l_prefix@/var/lmtp2nntp/lmtp2nntp.log", append=1, perm=0640)' | | # normal and debug operation | #l2spec 'noop -> { \ | info: prefix(prefix="%b %d %H:%M:%S <%L> lmtp2nntp[%P]: ", timezone=local) \ | -> buffer(size=65536) \ | -> file(path="@l_prefix@/var/lmtp2nntp/lmtp2nntp.log", append=1, perm=0640); \ | debug: prefix(prefix="%b %d %H:%M:%S <%L> lmtp2nntp[%P]: ", timezone=local) \ | -> file(path="@l_prefix@/var/lmtp2nntp/lmtp2nntp.debug", append=0, perm=0640) }' | | # raw debug operation only | #l2spec 'debug: fd(fd=2)'