{"id":24122197,"url":"https://github.com/tlinden/qpsmtpd-plugin-router","last_synced_at":"2026-05-10T22:37:13.687Z","repository":{"id":144613065,"uuid":"73541738","full_name":"TLINDEN/Qpsmtpd-Plugin-Router","owner":"TLINDEN","description":"qpsmtpd general purpose policy mail router / spooler","archived":false,"fork":false,"pushed_at":"2016-12-11T11:39:37.000Z","size":50,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-11T11:41:53.007Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TLINDEN.png","metadata":{"files":{"readme":"README.pod","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-12T08:44:14.000Z","updated_at":"2016-11-12T09:38:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"fe7ac63d-b957-42e5-b5f2-cdb32c21bcd3","html_url":"https://github.com/TLINDEN/Qpsmtpd-Plugin-Router","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2FQpsmtpd-Plugin-Router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2FQpsmtpd-Plugin-Router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2FQpsmtpd-Plugin-Router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TLINDEN%2FQpsmtpd-Plugin-Router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TLINDEN","download_url":"https://codeload.github.com/TLINDEN/Qpsmtpd-Plugin-Router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241210936,"owners_count":19927817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-11T11:38:54.350Z","updated_at":"2026-05-10T22:37:13.643Z","avatar_url":"https://github.com/TLINDEN.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"=head1 Qpsmtpd-Plugin-Router\n\nqpsmtpd general purpose policy mail router / spooler\n\n=head1 Status\n\nnothing useful implemented yet.\n\n=head1 DESCRIPTION\n\nThis plugin acts as a general  purpose smtp routing queue. It tries to\ndeliver mails  queued into it  to an external  target, which can  be a\nmail  server, an  external delivery  agent, a  script or  even another\nqueue plugin.  If this doesn't  work, it puts  the mail back  into the\nqueue (on disk, that is) and tries again later.\n\nFor this to work, a queueing daemon  will be forked on startup, but it\ncan be  started independently as well.  This daemon will take  care of\nmails residing in the various sub queues (see below).\n\nIn fact, the queue/router plugin call from qpsmtpd will just throw new\nmails into the incoming queue and  exit, the daemon will then process\nthe new mail.\n\nTherefore  it  is  reallly  important, that  your  filter  and  plugin\nconfiguration is setup properly. Better make sure, that mails entering\nthe queue are wanted. Any unwanted mails must be kept away from it.\n\nIt supports the following delivery methods:\n\n=over\n\n=item static relay host\n\nJust send all mails to this smtp server.\n\n=item mx via smtp\n\nDo dns mx lookup and send mails to whoever it belongs to.\n\nWill  be used  if either  none  of B\u003ctransports\u003e  or B\u003crelayhosts\u003e  is\nconfigured or if B\u003ctransports\u003e is configured but no entry matches.\n\n=item mail delivery agent\n\nSend mail to a local delivery agent (MDA) like maildrop or procmail.\n\n=item pipe\n\nPipe mail into stdin of an external program (useful to implement robots).\n\n=item rule-set based\n\nDifferent   delivery  methods   can  be   configured  in   a  rule-set\n(policy). Any  of the above  listed methods can be  used, configurable\nfor domains, subdomains, regexes or email addresses.\n\n=back\n\nThe plugin maintains a bunch of sub-queues which it creates on startup\nif they don't exist yet:\n\n +------------+----------------------------------------------------+\n | incoming   | new mails enter this queue first                   |\n | active     | contains mails currently being delivered           |\n | deferred   | temporary undeliverable mails                      |\n | archive    | final undeliverable mails, if archiving is enabled |\n +------------+----------------------------------------------------+\n\nBeside  delivering  mails,  the  plugin  can also  be  used  for  mail\nrewriting.  Sender  and/or recipient  domains can be  rewritten.  It's\npossible to rewrite the canonical addresses as well as the mail header\naddresses (From: and To: header fields) if you want.\n\nOn startup  the plugin forks a  queueing daemon which will  run in the\nbackground maintaining mail queues and delivering mails. If a new mail\narrives, the following things will happen:\n\n1) the queue/router plugin will be  called by qpsmtpd and get the mail\nas function argument.\n\n2) if rewriting is configured, the rules will be applied, e.g.\n\".*.foo.bar\" =\u003e \"foo.bar\".\n\n3) plugin will  then put  the  message into  the C\u003cincoming\u003e  queue,\nreturn the queue-id and exit.\n\n4) the queue manager  will pick up the queue file by  moving it to the\nC\u003cactive\u003e queue.\n\n5) it  will then  hand it  to a delivery  agent (one  of SMTP,  MDA or\nPlugin) according to the transport policy.\n\n6) if delivery  was a success, remove the queue  file. If the delivery\nerror was temporary move it to the C\u003cdeferred\u003e queue, otherwise remove\nthe  mail from  the  queue (or  move  it into  the  archive queue,  if\nenabled).\n\n7)  if delivery  failed, mark  the transaction  as failed,  append the\nerror to a transaction specific log of the transaction object (we just\noccupy the  object and add an  array ref with log  entries), increment\nthe retry count and put it into the C\u003cdeferred\u003e queue.\n\n8)  step  5-8 will  repeat  for  every  mail  in the  C\u003cincoming\u003e  and\nC\u003cdeferred\u003e  queues.  However,  if  a   mail  failed  to  deliver  for\nB\u003cmax_age\u003e days, remove  the queue file, unless  archiving is enabled,\nin this case the queue file will be moved to the archive dir.\n\n\n\n\n\n=head1 CONFIG\n\nThe plugin accepts the following parameters:\n\n=over\n\n=item B\u003crelayhost SERVER,[SERVER,...]\u003e\n\nAlways  use this  server  as relay.   Separate  multiple servers  with\ncomma. Add  the port with  :port. When using ipv6  addresses, surround\nthem with brackets (only required if a port has to be specified). When\nusing  hostname,  use fqdn,  otherwise  the  plugin assumes  the  host\nresides under $me domain (that is, the domain after config/me).\n\nIf multiple servers are configured, they will be used in a round robin\nfashion.\n\nExamples:\n\n relayhost 172.10.1.1\n relayhost 10.1.1.1:2525\n relayhost [::1]:2425\n relayhost mx.foo.bar,mx.backup.foo.bar\n\nThe  B\u003crelayhost\u003e  variable has  precedence  over  the other  delivery\nmethods   configured,  if   any.  So,   either  use   B\u003crelayhost\u003e  or\nB\u003ctransports\u003e.\n\n=item B\u003ctransports FILE\u003e\n\nTransport policy text  file containing rules how to  deliver mails per\ndestination  pattern.   You  can  specify  domains,  email  addresses,\nwildcards or regexes.\n\nTarget  can  be  one  or  more mail  server  (same  notation  as  with\nB\u003crelayhost\u003e), a pipe, an MDA or another qpsmtp queue plugin.\n\nTop entries have precedence, that is:  order in the file matters. If a\nrule matches, no further checks will be made.\n\nFormat:\n\n destination    next-hop\n\nDestination examples:\n\n foo.bar\n *.foo\n /blah/\n\nNext-hop examples:\n\n 172.10.1.1\n queue/maildir\n |my-mail-robot.pl\n /usr/bin/maildrop\n\n=item B\u003ctransport-defs FILE\u003e\n\nTo make  it easier to maintain  the transport policy, you  can specify\nvariables, which can be used in the transport policy. The format is simple:\n\n name value\n\nVariables can be used in the transports policy file, e.g.:\n\n /.*spl-[0-9]{6}\\.foo.bar/       $splunkmta\n\n=item B\u003cmax-age DAYS\u003e\n\nHow many  days a mail  is allowed to be  queued. After this  time, the\nmail will be discarded. If  B\u003csend-ndr\u003e is true, a non-delivery report\nwill be  sent to the canonical  sender, otherwise drop the  message or\nput it into the archive queue, if B\u003carchive-failed\u003e is set to true.\n\n=item B\u003carchive-failed BOOL\u003e\n\nIf set  to true, mails which  cannot be delivered will  not be dropped\nbut archived to an archive queue.\n\n=item B\u003cqueue-dir DIR\u003e\n\nIf  you  want  to  use   another  spool  directory  as  qpsmtp  itself\nuses.  Directory  must exist  and  be  writable  to the  user  running\nqpsmtpd.\n\n=item B\u003crewriting FILE\u003e\n\nText file which contains rules how to rewrite mail sender or recipient\naddresses or both.  Rewriting - if  enabled - will be the first action\ndone,  that is,  it  happens  before any  delivery  attempt. Rules  in\ntransport or aliases have to match on rewritten addresses.\n\nFormat:\n\n direction   old-value    new-value\n\nDirection can be:\n\n from\n to\n both\n\nOld-value can be:\n\n domain     (eg: foo.bar)\n wildcard   (eg: *.bar)\n regex      (eg: /[0-9]*.foo.bar/)\n\nNew-value must be a domain.\n\n=item B\u003crewrite-both BOOL\u003e\n\nIf set to  a true value both canonical and  mail header addresses will\nbe rewritten. Example:\n\n from    *.servers.company.foo      company.foo\n\n=item B\u003csend-ndr BOOL\u003e\n\nIf set to true, a non-delivery  response will be sent to the canonical\nsender of  mails that cannot  be delivered after B\u003cmax-age\u003e  days. The\nsender of these NDRs will be \u003c\u003e (none).\n\n=item B\u003caliases FILE\u003e\n\nFilename  containing  recipient user  to  unix  user mapping,  without\ndomains. This  file is  B\u003crequired\u003e if local  delivery (using  the MDA\nagent) is being used.\n\nFormat:\n\n virtual-user    unix-user\n\nThere  B\u003cmust\u003e be  an entry  for root,  since the  MDA agent  will NOT\ndeliver mails to  the root user directly, e.g.:\n\n root    max\n\nAlso there must be an entry for EVERY valid recipient, however you can\nuse regular expressions on the virtual side, e.g.:\n\n .*master    admin\n .*www.*     phpgroup\n\n=back\n\n=cut\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlinden%2Fqpsmtpd-plugin-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftlinden%2Fqpsmtpd-plugin-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftlinden%2Fqpsmtpd-plugin-router/lists"}