From 7626e5d047c93443d3d17bcea5adda2c8a7d1c17 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Sun, 19 Nov 2017 08:59:43 +0100 Subject: [PATCH] mail: add postfix and rspamd --- Makefile | 2 +- README.md | 2 + mail/postfix/Makefile | 8 + mail/postfix/pkg-descr | 5 + .../src/etc/inc/plugins.inc.d/postfix.inc | 49 +++ .../Postfix/Api/AntispamController.php | 76 ++++ .../OPNsense/Postfix/Api/DomainController.php | 205 +++++++++++ .../Postfix/Api/GeneralController.php | 76 ++++ .../Postfix/Api/ServiceController.php | 159 ++++++++ .../OPNsense/Postfix/DomainController.php | 34 ++ .../OPNsense/Postfix/GeneralController.php | 39 ++ .../OPNsense/Postfix/forms/antispam.xml | 8 + .../Postfix/forms/dialogEditPostfixDomain.xml | 20 + .../OPNsense/Postfix/forms/general.xml | 112 ++++++ .../app/models/OPNsense/Postfix/ACL/ACL.xml | 9 + .../app/models/OPNsense/Postfix/Antispam.php | 34 ++ .../app/models/OPNsense/Postfix/Antispam.xml | 11 + .../app/models/OPNsense/Postfix/Domain.php | 30 ++ .../app/models/OPNsense/Postfix/Domain.xml | 23 ++ .../app/models/OPNsense/Postfix/General.php | 34 ++ .../app/models/OPNsense/Postfix/General.xml | 87 +++++ .../app/models/OPNsense/Postfix/Menu/Menu.xml | 8 + .../app/views/OPNsense/Postfix/domain.volt | 110 ++++++ .../app/views/OPNsense/Postfix/general.volt | 100 +++++ .../scripts/OPNsense/Postfix/setup.sh | 32 ++ .../conf/actions.d/actions_postfix.conf | 35 ++ .../templates/OPNsense/Postfix/+TARGETS | 6 + .../templates/OPNsense/Postfix/main.cf | 129 +++++++ .../templates/OPNsense/Postfix/master.cf | 135 +++++++ .../templates/OPNsense/Postfix/postfix | 6 + .../OPNsense/Postfix/recipient_access | 4 + .../templates/OPNsense/Postfix/sender_access | 4 + .../templates/OPNsense/Postfix/transport | 9 + mail/rspamd/Makefile | 8 + mail/rspamd/pkg-descr | 3 + .../src/etc/inc/plugins.inc.d/rspamd.inc | 62 ++++ .../OPNsense/Rspamd/Api/ServiceController.php | 139 +++++++ .../Rspamd/Api/SettingsController.php | 38 ++ .../OPNsense/Rspamd/IndexController.php | 53 +++ .../OPNsense/Rspamd/forms/settings.xml | 348 ++++++++++++++++++ .../app/models/OPNsense/Rspamd/ACL/ACL.xml | 9 + .../app/models/OPNsense/Rspamd/Menu/Menu.xml | 5 + .../mvc/app/models/OPNsense/Rspamd/RSpamd.php | 34 ++ .../mvc/app/models/OPNsense/Rspamd/RSpamd.xml | 337 +++++++++++++++++ .../mvc/app/views/OPNsense/Rspamd/index.volt | 166 +++++++++ .../src/opnsense/scripts/rspamd/setup.sh | 8 + .../conf/actions.d/actions_rspamd.conf | 23 ++ .../templates/OPNsense/Rspamd/+TARGETS | 15 + .../templates/OPNsense/Rspamd/2tld.inc.local | 5 + .../templates/OPNsense/Rspamd/antivirus.conf | 29 ++ .../templates/OPNsense/Rspamd/antivirus.wl | 5 + .../templates/OPNsense/Rspamd/dkim.conf | 13 + .../OPNsense/Rspamd/dkim_signing.conf | 22 ++ .../templates/OPNsense/Rspamd/greylist.conf | 14 + .../templates/OPNsense/Rspamd/mx_check.conf | 9 + .../templates/OPNsense/Rspamd/phishing.conf | 9 + .../templates/OPNsense/Rspamd/ratelimit.conf | 62 ++++ .../templates/OPNsense/Rspamd/redis.conf | 28 ++ .../service/templates/OPNsense/Rspamd/rspamd | 6 + .../templates/OPNsense/Rspamd/spamtrap.conf | 28 ++ .../templates/OPNsense/Rspamd/spamtrap.map | 5 + .../templates/OPNsense/Rspamd/spf.conf | 9 + .../OPNsense/Rspamd/surbl-whitelist.inc.local | 5 + 63 files changed, 3097 insertions(+), 1 deletion(-) create mode 100644 mail/postfix/Makefile create mode 100644 mail/postfix/pkg-descr create mode 100644 mail/postfix/src/etc/inc/plugins.inc.d/postfix.inc create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/AntispamController.php create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/DomainController.php create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/GeneralController.php create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/ServiceController.php create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/DomainController.php create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/GeneralController.php create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/antispam.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/dialogEditPostfixDomain.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/general.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/ACL/ACL.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Antispam.php create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Antispam.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Domain.php create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Domain.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/General.php create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/General.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Menu/Menu.xml create mode 100644 mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/domain.volt create mode 100644 mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/general.volt create mode 100755 mail/postfix/src/opnsense/scripts/OPNsense/Postfix/setup.sh create mode 100644 mail/postfix/src/opnsense/service/conf/actions.d/actions_postfix.conf create mode 100644 mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/+TARGETS create mode 100644 mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/main.cf create mode 100644 mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/master.cf create mode 100644 mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/postfix create mode 100644 mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/recipient_access create mode 100644 mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/sender_access create mode 100644 mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/transport create mode 100644 mail/rspamd/Makefile create mode 100644 mail/rspamd/pkg-descr create mode 100644 mail/rspamd/src/etc/inc/plugins.inc.d/rspamd.inc create mode 100644 mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/ServiceController.php create mode 100644 mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/SettingsController.php create mode 100644 mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/IndexController.php create mode 100644 mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/forms/settings.xml create mode 100644 mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/ACL/ACL.xml create mode 100644 mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/Menu/Menu.xml create mode 100644 mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/RSpamd.php create mode 100644 mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/RSpamd.xml create mode 100644 mail/rspamd/src/opnsense/mvc/app/views/OPNsense/Rspamd/index.volt create mode 100755 mail/rspamd/src/opnsense/scripts/rspamd/setup.sh create mode 100644 mail/rspamd/src/opnsense/service/conf/actions.d/actions_rspamd.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/+TARGETS create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/2tld.inc.local create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.wl create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim_signing.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/greylist.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/mx_check.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/phishing.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/ratelimit.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/redis.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/rspamd create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.map create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spf.conf create mode 100644 mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/surbl-whitelist.inc.local diff --git a/Makefile b/Makefile index 70c0b65a5..8902b8d02 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ PAGER?= less all: @cat ${.CURDIR}/README.md | ${PAGER} -CATEGORIES= databases devel dns net-mgmt net security sysutils www +CATEGORIES= databases devel dns mail net-mgmt net security sysutils www .for CATEGORY in ${CATEGORIES} _${CATEGORY}!= ls -1d ${CATEGORY}/* diff --git a/README.md b/README.md index f64394386..8fc960ce7 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ devel/debug -- Debugging Tools devel/helloworld -- A sample framework application dns/dyndns -- Dynamic DNS Support dns/rfc2136 -- RFC-2136 Support +mail/postfix -- SMTP mail relay +mail/rspamd -- Protect your network from spam net-mgmt/collectd -- Collect system and application performance metrics periodically net-mgmt/snmp -- SNMP Server via bsnmpd net-mgmt/telegraf -- Agent for collecting metrics and data diff --git a/mail/postfix/Makefile b/mail/postfix/Makefile new file mode 100644 index 000000000..fb4cdc37b --- /dev/null +++ b/mail/postfix/Makefile @@ -0,0 +1,8 @@ +PLUGIN_NAME= postfix +PLUGIN_VERSION= 0.1 +PLUGIN_COMMENT= SMTP mail relay +PLUGIN_DEPENDS= postfix-sasl +PLUGIN_MAINTAINER= m.muenz@gmail.com +PLUGIN_DEVEL= yes + +.include "../../Mk/plugins.mk" diff --git a/mail/postfix/pkg-descr b/mail/postfix/pkg-descr new file mode 100644 index 000000000..1e96d0531 --- /dev/null +++ b/mail/postfix/pkg-descr @@ -0,0 +1,5 @@ +Postfix attempts to be fast, easy to administer, and secure. +The outside has a definite Sendmail-ish flavor, but the inside +is completely different. + +WWW: http://www.postfix.org/ diff --git a/mail/postfix/src/etc/inc/plugins.inc.d/postfix.inc b/mail/postfix/src/etc/inc/plugins.inc.d/postfix.inc new file mode 100644 index 000000000..0ff66f9de --- /dev/null +++ b/mail/postfix/src/etc/inc/plugins.inc.d/postfix.inc @@ -0,0 +1,49 @@ + gettext('Postfix'), + 'configd' => array( + 'restart' => array('postfix restart'), + 'start' => array('postfix start'), + 'stop' => array('postfix stop'), + ), + 'name' => 'postfix', + 'pidfile' => '/var/spool/postfix/pid/master.pid' + ); + } + + return $services; +} diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/AntispamController.php b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/AntispamController.php new file mode 100644 index 000000000..c9896d712 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/AntispamController.php @@ -0,0 +1,76 @@ +request->isGet()) { + $mdlAntispam = new Antispam(); + $result['antispam'] = $mdlAntispam->getNodes(); + } + return $result; + } + + public function setAction() + { + $result = array("result"=>"failed"); + if ($this->request->isPost()) { + // load model and update with provided data + $mdlAntispam = new Antispam(); + $mdlAntispam->setNodes($this->request->getPost("antispam")); + + // perform validation + $valMsgs = $mdlAntispam->performValidation(); + foreach ($valMsgs as $field => $msg) { + if (!array_key_exists("validations", $result)) { + $result["validations"] = array(); + } + $result["validations"]["antispam.".$msg->getField()] = $msg->getMessage(); + } + + // serialize model to config and save + if ($valMsgs->count() == 0) { + $mdlAntispam->serializeToConfig(); + Config::getInstance()->save(); + $result["result"] = "saved"; + } + } + return $result; + } +} diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/DomainController.php b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/DomainController.php new file mode 100644 index 000000000..f449b9245 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/DomainController.php @@ -0,0 +1,205 @@ +request->isGet()) { + $mdlDomain = new Domain(); + $result['domain'] = $mdlDomain->getNodes(); + } + return $result; + } + + public function setAction() + { + $result = array("result"=>"failed"); + if ($this->request->isPost()) { + // load model and update with provided data + $mdlDomain = new Domain(); + $mdlDomain->setNodes($this->request->getPost("domain")); + // perform validation + $valMsgs = $mdlDomain->performValidation(); + foreach ($valMsgs as $field => $msg) { + if (!array_key_exists("validations", $result)) { + $result["validations"] = array(); + } + $result["validations"]["domain.".$msg->getField()] = $msg->getMessage(); + } + // serialize model to config and save + if ($valMsgs->count() == 0) { + $mdlDomain->serializeToConfig(); + Config::getInstance()->save(); + $result["result"] = "saved"; + } + } + return $result; + } + + public function searchDomainAction() + { + $this->sessionClose(); + $mdlDomain = $this->getModel(); + $grid = new UIModelGrid($mdlDomain->domains->domain); + return $grid->fetchBindRequest( + $this->request, + array("enabled", "domainname", "destination" ) + ); + } + + public function getDomainAction($uuid = null) + { + $mdlDomain = $this->getModel(); + if ($uuid != null) { + $node = $mdlDomain->getNodeByReference('domains.domain.' . $uuid); + if ($node != null) { + // return node + return array("domain" => $node->getNodes()); + } + } else { + $node = $mdlDomain->domains->domain->add(); + return array("domain" => $node->getNodes()); + } + return array(); + } + + public function addDomainAction() + { + $result = array("result" => "failed"); + if ($this->request->isPost() && $this->request->hasPost("domain")) { + $result = array("result" => "failed", "validations" => array()); + $mdlDomain = $this->getModel(); + $node = $mdlDomain->domains->domain->Add(); + $node->setNodes($this->request->getPost("domain")); + $valMsgs = $mdlDomain->performValidation(); + foreach ($valMsgs as $field => $msg) { + $fieldnm = str_replace($node->__reference, "domain", $msg->getField()); + $result["validations"][$fieldnm] = $msg->getMessage(); + } + if (count($result['validations']) == 0) { + unset($result['validations']); + // save config if validated correctly + $mdlDomain->serializeToConfig(); + Config::getInstance()->save(); + unset($result['validations']); + $result["result"] = "saved"; + } + } + return $result; + } + + public function delDomainAction($uuid) + { + $result = array("result" => "failed"); + if ($this->request->isPost()) { + $mdlDomain = $this->getModel(); + if ($uuid != null) { + if ($mdlDomain->domains->domain->del($uuid)) { + $mdlDomain->serializeToConfig(); + Config::getInstance()->save(); + $result['result'] = 'deleted'; + } else { + $result['result'] = 'not found'; + } + } + } + return $result; + } + + public function setDomainAction($uuid) + { + if ($this->request->isPost() && $this->request->hasPost("domain")) { + $mdlSetting = $this->getModel(); + if ($uuid != null) { + $node = $mdlSetting->getNodeByReference('domains.domain.' . $uuid); + if ($node != null) { + $result = array("result" => "failed", "validations" => array()); + $domainInfo = $this->request->getPost("domain"); + $node->setNodes($domainInfo); + $valMsgs = $mdlSetting->performValidation(); + foreach ($valMsgs as $field => $msg) { + $fieldnm = str_replace($node->__reference, "domain", $msg->getField()); + $result["validations"][$fieldnm] = $msg->getMessage(); + } + if (count($result['validations']) == 0) { + // save config if validated correctly + $mdlSetting->serializeToConfig(); + Config::getInstance()->save(); + $result = array("result" => "saved"); + } + return $result; + } + } + } + return array("result" => "failed"); + } + + public function toggle_handler($uuid, $elements, $element) + { + $result = array("result" => "failed"); + if ($this->request->isPost()) { + $mdlSetting = $this->getModel(); + if ($uuid != null) { + $node = $mdlSetting->getNodeByReference($elements . '.'. $element .'.' . $uuid); + if ($node != null) { + if ($node->enabled->__toString() == "1") { + $result['result'] = "Disabled"; + $node->enabled = "0"; + } else { + $result['result'] = "Enabled"; + $node->enabled = "1"; + } + // if item has toggled, serialize to config and save + $mdlSetting->serializeToConfig(); + Config::getInstance()->save(); + } + } + } + return $result; + } + + public function toggleDomainAction($uuid) + { + return $this->toggle_handler($uuid, 'domains', 'domain'); + } +} diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/GeneralController.php b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/GeneralController.php new file mode 100644 index 000000000..b01f39fea --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/GeneralController.php @@ -0,0 +1,76 @@ +request->isGet()) { + $mdlGeneral = new General(); + $result['general'] = $mdlGeneral->getNodes(); + } + return $result; + } + + public function setAction() + { + $result = array("result"=>"failed"); + if ($this->request->isPost()) { + // load model and update with provided data + $mdlGeneral = new General(); + $mdlGeneral->setNodes($this->request->getPost("general")); + + // perform validation + $valMsgs = $mdlGeneral->performValidation(); + foreach ($valMsgs as $field => $msg) { + if (!array_key_exists("validations", $result)) { + $result["validations"] = array(); + } + $result["validations"]["general.".$msg->getField()] = $msg->getMessage(); + } + + // serialize model to config and save + if ($valMsgs->count() == 0) { + $mdlGeneral->serializeToConfig(); + Config::getInstance()->save(); + $result["result"] = "saved"; + } + } + return $result; + } +} diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/ServiceController.php b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/ServiceController.php new file mode 100644 index 000000000..269363bfe --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/Api/ServiceController.php @@ -0,0 +1,159 @@ +configdRun("firmware plugin rspamd"); + return $response; + } + + /** + * start postfix service (in background) + * @return array + */ + public function startAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun('postfix start'); + return array("response" => $response); + } else { + return array("response" => array()); + } + } + + /** + * stop postfix service + * @return array + */ + public function stopAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun("postfix stop"); + return array("response" => $response); + } else { + return array("response" => array()); + } + } + + /** + * restart postfix service + * @return array + */ + public function restartAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun("postfix restart"); + return array("response" => $response); + } else { + return array("response" => array()); + } + } + + /** + * retrieve status of postfix + * @return array + * @throws \Exception + */ + public function statusAction() + { + $backend = new Backend(); + $mdlGeneral = new General(); + $response = $backend->configdRun("postfix status"); + + if (strpos($response, "not running") > 0) { + if ($mdlGeneral->enabled->__toString() == 1) { + $status = "stopped"; + } else { + $status = "disabled"; + } + } elseif (strpos($response, "is running") > 0) { + $status = "running"; + } elseif ($mdlGeneral->enabled->__toString() == 0) { + $status = "disabled"; + } else { + $status = "unkown"; + } + + + return array("status" => $status); + } + + /** + * reconfigure postfix, generate config and reload + */ + public function reconfigureAction() + { + if ($this->request->isPost()) { + // close session for long running action + $this->sessionClose(); + + $mdlGeneral = new General(); + $backend = new Backend(); + + $runStatus = $this->statusAction(); + + // stop postfix if it is running or not + $this->stopAction(); + + // generate template + $backend->configdRun('template reload OPNsense/Postfix'); + $backend->configdRun('postfix make-transport'); + + // (res)start daemon + if ($mdlGeneral->enabled->__toString() == 1) { + $this->startAction(); + } + + return array("status" => "ok"); + } else { + return array("status" => "failed"); + } + } +} diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/DomainController.php b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/DomainController.php new file mode 100644 index 000000000..1f4e7b844 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/DomainController.php @@ -0,0 +1,34 @@ +view->title = gettext("Postfix Domains"); + $this->view->formDialogEditPostfixDomain = $this->getForm("dialogEditPostfixDomain"); + $this->view->pick('OPNsense/Postfix/domain'); + } +} diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/GeneralController.php b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/GeneralController.php new file mode 100644 index 000000000..3714878b5 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/GeneralController.php @@ -0,0 +1,39 @@ +view->title = gettext("Postfix Settings"); + $this->view->generalForm = $this->getForm("general"); + $this->view->antispamForm = $this->getForm("antispam"); + $this->view->pick('OPNsense/Postfix/general'); + } +} diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/antispam.xml b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/antispam.xml new file mode 100644 index 000000000..9db8d64b3 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/antispam.xml @@ -0,0 +1,8 @@ +
+ + antispam.enable_rspamd + + checkbox + This will allow Postfix to connect to rspamd via milter protocol. + +
diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/dialogEditPostfixDomain.xml b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/dialogEditPostfixDomain.xml new file mode 100644 index 000000000..ce4c6b020 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/dialogEditPostfixDomain.xml @@ -0,0 +1,20 @@ +
+ + domain.enabled + + checkbox + This will enable or disable domain routing for this entry. + + + domain.domainname + + text + Set the unique domain name to relay for. + + + domain.destination + + text + Set the IP or FQDN to where to send the mails to. Empty means MX will be used. + +
diff --git a/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/general.xml b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/general.xml new file mode 100644 index 000000000..2e974c035 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/controllers/OPNsense/Postfix/forms/general.xml @@ -0,0 +1,112 @@ +
+ + general.enabled + + checkbox + This will activate the Postfix daemon. + + + general.myhostname + + text + The 'System Hostname' parameter specifies the internet hostname of this mail system. The default is to use the fully-qualified domain name from gethostname(). It is used as a default value for many other configuration parameters. + + + general.mydomain + + text + The 'System Domain' parameter specifies the local internet domain name. The default is to use 'System Hostname' minus the first component. It is used as a default value for many other configuration parameters. + + + general.myorigin + + text + The 'System Origin' parameter specifies the domain that locally-posted mail appears to come from. The default is to append 'System Hostname', which is fine for small sites. + + + general.inet_interfaces + + text + The 'Listen IPs' parameter specifies the IP address to listen to. Default is to listen on all interfaces. + + + general.mynetworks + + select_multiple + + true + The 'Trusted Networks' parameter specifies the list of trusted SMTP clients. In particular, trusted SMTP clients are allowed to relay mail through Postfix. Please use CIDR notation like 192.168.0.0/24 separated by spaces. IPv6 addresses have to be in square brackets like [::1]/128. + + + general.banner + + text + The smtpd_banner parameter specifies the text that follows the 220 code in the SMTP server's greeting banner. Default is "'System Hostname' ESMTP Postfix". + + + general.message_size_limit + + text + Set the max size for messages to accept, default is 501200000 Byte which is 50MB. Values must be entered in Bytes. + + + general.disable_ssl + + checkbox + Disable SSLv2 and SSLv3, only TLS allowed. + + + general.disable_weak_ciphers + + checkbox + This will disable known weak ciphers like DES, RC4 or MD5. + + + general.reject_unauth_pipelining + + checkbox + + + general.reject_unknown_sender_domain + + checkbox + This will reject mails from domains which do not exist. + + + general.reject_unknown_recipient_domain + + checkbox + + + general.reject_non_fqdn_sender + + checkbox + For example senders without a domain or only a hostname. + + + general.reject_non_fqdn_recipient + + checkbox + For example recipients without a domain or only a hostname. + + + general.permit_sasl_authenticated + + checkbox + + + general.permit_tls_clientcerts + + checkbox + + + general.permit_mynetworks + + checkbox + + + general.reject_unauth_destination + + checkbox + +
diff --git a/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/ACL/ACL.xml b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/ACL/ACL.xml new file mode 100644 index 000000000..65c0078e5 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/ACL/ACL.xml @@ -0,0 +1,9 @@ + + + Services: Postfix + + ui/postfix/* + api/postfix/* + + + diff --git a/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Antispam.php b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Antispam.php new file mode 100644 index 000000000..50598c8ca --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Antispam.php @@ -0,0 +1,34 @@ + + //OPNsense/postfix/antispam + Postfix Antispam configuration + 1.0.0 + + + 0 + Y + + + diff --git a/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Domain.php b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Domain.php new file mode 100644 index 000000000..2bcab6c9e --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Domain.php @@ -0,0 +1,30 @@ + + //OPNsense/postfix/domain + Postfix domain configuration + 1.0.0 + + + + + 1 + Y + + + + Y + + + + Y + + + + + diff --git a/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/General.php b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/General.php new file mode 100644 index 000000000..5fe1c41cd --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/General.php @@ -0,0 +1,34 @@ + + //OPNsense/postfix/general + Postfix configuration + 1.0.0 + + + 0 + Y + + + + N + + + + N + + + + N + + + all + Y + + + 127.0.0.0/8,[::ffff:127.0.0.0]/104,[::1]/128 + Y + + + + N + + + 51200000 + Y + + + 1 + Y + + + 1 + Y + + + + + 1 + Y + + + + + 1 + Y + + + 1 + Y + + + 1 + Y + + + 1 + Y + + + 1 + Y + + + 1 + Y + + + 1 + Y + + + 1 + Y + + + diff --git a/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Menu/Menu.xml b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Menu/Menu.xml new file mode 100644 index 000000000..6c9e95893 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/models/OPNsense/Postfix/Menu/Menu.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/domain.volt b/mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/domain.volt new file mode 100644 index 000000000..ccb964315 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/domain.volt @@ -0,0 +1,110 @@ +{# + +OPNsense® is Copyright © 2014 – 2017 by Deciso B.V. +Copyright (C) 2017 Michael Muenz +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +#} + + + +
+
+ + + + + + + + + + + + + + + + + + +
{{ lang._('Enabled') }}{{ lang._('Domain') }}{{ lang._('Destination') }}{{ lang._('ID') }}{{ lang._('Commands') }}
+ + +
+
+
+
+ +

+
+
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogEditPostfixDomain,'id':'dialogEditPostfixDomain','label':lang._('Edit Domain')])}} diff --git a/mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/general.volt b/mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/general.volt new file mode 100644 index 000000000..318606e52 --- /dev/null +++ b/mail/postfix/src/opnsense/mvc/app/views/OPNsense/Postfix/general.volt @@ -0,0 +1,100 @@ +{# + +OPNsense® is Copyright © 2014 – 2017 by Deciso B.V. +This file is Copyright © 2017 by Michael Muenz +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +#} + +
+
+
+ {{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}} +
+
+ +
+
+
+
+
+ + {{ partial("layout_partials/base_form",['fields':antispamForm,'id':'frm_antispam_settings'])}} +
+
+ +
+
+
+
+ + diff --git a/mail/postfix/src/opnsense/scripts/OPNsense/Postfix/setup.sh b/mail/postfix/src/opnsense/scripts/OPNsense/Postfix/setup.sh new file mode 100755 index 000000000..5a153a51e --- /dev/null +++ b/mail/postfix/src/opnsense/scripts/OPNsense/Postfix/setup.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +mkdir -p /var/spool/postfix/ +chown root:wheel /var/spool/postfix +chmod 755 /var/spool/postfix + +# Set defaults +POSTFIX_DIRS="/var/spool/postfix/active /var/spool/postfix/bounce /var/spool/postfix/corrupt /var/spool/postfix/defer /var/spool/postfix/deferred /var/spool/postfix/flush /var/spool/postfix/hold /var/spool/postfix/incoming /var/spool/postfix/private /var/spool/postfix/saved /var/spool/postfix/trace /var/db/postfix" +POSTFIX_USER=postfix +POSTFIX_GROUP=wheel + +for DIR in ${POSTFIX_DIRS}; do + mkdir -p ${DIR} + chmod -R 700 ${DIR} + chown -R ${POSTFIX_USER}:${POSTFIX_GROUP} ${DIR} +done + +# Some folders need special attention +mkdir -p /var/spool/postfix/maildrop +mkdir -p /var/spool/postfix/public +mkdir -p /var/spool/postfix/pid +chmod -R 730 /var/spool/postfix/maildrop +chmod -R 710 /var/spool/postfix/public +chmod -R 755 /var/spool/postfix/pid +chown -R postfix:maildrop /var/spool/postfix/maildrop +chown -R postfix:maildrop /var/spool/postfix/public +chown -R root:postfix /var/spool/postfix/pid + +# Create Transporttable +postmap /usr/local/etc/postfix/transport +postmap /usr/local/etc/postfix/recipient_access +postmap /usr/local/etc/postfix/sender_access diff --git a/mail/postfix/src/opnsense/service/conf/actions.d/actions_postfix.conf b/mail/postfix/src/opnsense/service/conf/actions.d/actions_postfix.conf new file mode 100644 index 000000000..f26c0d74e --- /dev/null +++ b/mail/postfix/src/opnsense/service/conf/actions.d/actions_postfix.conf @@ -0,0 +1,35 @@ +[start] +command:/usr/local/opnsense/scripts/OPNsense/Postfix/setup.sh;/usr/local/etc/rc.d/postfix start +parameters: +type:script +message:starting Postfix + +[stop] +command:/usr/local/etc/rc.d/postfix stop; exit 0 +parameters: +type:script +message:stopping Postfix + +[restart] +command:/usr/local/opnsense/scripts/OPNsense/Postfix/setup.sh;/usr/local/etc/rc.d/postfix restart +parameters: +type:script +message:restarting Postfix + +[reconfigure] +command:/usr/local/opnsense/scripts/OPNsense/Postfix/setup.sh;/usr/local/etc/rc.d/postfix reload +parameters: +type:script +message:reconfigure Postfix + +[status] +command:/usr/local/etc/rc.d/postfix status;exit 0 +parameters: +type:script_output +message:request Postfix status + +[make-transport] +command:postmap /usr/local/etc/postfix/transport +parameters: +type:script_output +message:rebuilding transport table diff --git a/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/+TARGETS b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/+TARGETS new file mode 100644 index 000000000..3cbe5f21d --- /dev/null +++ b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/+TARGETS @@ -0,0 +1,6 @@ +main.cf:/usr/local/etc/postfix/main.cf +master.cf:/usr/local/etc/postfix/master.cf +postfix:/etc/rc.conf.d/postfix +transport:/usr/local/etc/postfix/transport +recipient_access:/usr/local/etc/postfix/recipient_access +sender_access:/usr/local/etc/postfix/sender_access diff --git a/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/main.cf b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/main.cf new file mode 100644 index 000000000..b9f248b5b --- /dev/null +++ b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/main.cf @@ -0,0 +1,129 @@ +{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %} + +########################## +# START SYSTEM DEFAULTS +########################## +compatibility_level = 2 +queue_directory = /var/spool/postfix +command_directory = /usr/local/sbin +daemon_directory = /usr/local/libexec/postfix +data_directory = /var/db/postfix +mail_owner = postfix +unknown_local_recipient_reject_code = 550 +mynetworks_style = host +debug_peer_level = 2 +debugger_command = + PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin + ddd $daemon_directory/$process_name $process_id & sleep 5 + +sendmail_path = /usr/local/sbin/sendmail +newaliases_path = /usr/local/bin/newaliases +mailq_path = /usr/local/bin/mailq +setgid_group = maildrop +html_directory = no +manpage_directory = /usr/local/man +sample_directory = /usr/local/etc/postfix +readme_directory = no +inet_protocols = all +meta_directory = /usr/local/libexec/postfix +shlib_directory = /usr/local/lib/postfix +relay_domains = hash:/usr/local/etc/postfix/transport +transport_maps = hash:/usr/local/etc/postfix/transport +########################## +# END SYSTEM DEFAULTS +########################## + +{% if helpers.exists('OPNsense.postfix.general.myhostname') and OPNsense.postfix.general.myhostname != '' %} +myhostname = {{ OPNsense.postfix.general.myhostname }} +{% else %} +myhostname = {{ system.hostname }} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.mydomain') and OPNsense.postfix.general.mydomain != '' %} +mydomain = {{ OPNsense.postfix.general.mydomain }} +{% else %} +mydomain = {{ system.domain }} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.myorigin') and OPNsense.postfix.general.myorigin != '' %} +myorigin = {{ OPNsense.postfix.general.myorigin }} +{% else %} +myorigin = $myhostname +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.inet_interfaces') and OPNsense.postfix.general.inet_interfaces != '' %} +inet_interfaces = {{ OPNsense.postfix.general.inet_interfaces }} +{% else %} +inet_interfaces = all +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.mynetworks') and OPNsense.postfix.general.mynetworks != '' %} +mynetworks = {{ OPNsense.postfix.general.mynetworks.replace(',', ' ') }} +{% else %} +mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.banner') and OPNsense.postfix.general.banner != '' %} +smtpd_banner = {{ OPNsense.postfix.general.banner }} +{% else %} +smtpd_banner = $myhostname ESMTP Postfix +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.message_size_limit') and OPNsense.postfix.general.message_size_limit != '' %} +message_size_limit = {{ OPNsense.postfix.general.message_size_limit }} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.disable_ssl') and OPNsense.postfix.general.disable_ssl == '1' %} +smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3 +smtp_tls_mandatory_protocols=!SSLv2,!SSLv3 +smtpd_tls_protocols=!SSLv2,!SSLv3 +smtp_tls_protocols=!SSLv2,!SSLv3 +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.disable_weak_ciphers') and OPNsense.postfix.general.disable_weak_ciphers == '1' %} +smtpd_tls_exclude_ciphers = aNULL, eNULL, EXPORT, DES, RC4, MD5, PSK, aECDH, EDH-DSS-DES-CBC3-SHA, EDH-RSA-DES-CDC3-SHA, KRB5-DE5, CBC3-SHA +{% endif %} + +{% if helpers.exists('OPNsense.postfix.antispam.enable_rspamd') and OPNsense.postfix.antispam.enable_rspamd == '1' %} +smtpd_milters = inet:localhost:11332 +non_smtpd_milters = inet:localhost:11332 +milter_protocol = 6 +milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen} +milter_default_action = accept +{% endif %} + +{# Sender Restrictions #} +{% set smtpd_recipient_restrictions=[] %} +{% if helpers.exists('OPNsense.postfix.general.check_recipient_access') %} +{% do smtpd_recipient_restrictions.append('check_recipient_access hash:/usr/local/etc/postfix/recipient_access') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.reject_unauth_pipelining') and OPNsense.postfix.general.reject_unauth_pipelining == '1' %} +{% do smtpd_recipient_restrictions.append('reject_unauth_pipelining') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.check_sender_access') %} +{% do smtpd_recipient_restrictions.append('check_sender_access hash:/usr/local/etc/postfix/sender_access') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.reject_unknown_sender_domain') and OPNsense.postfix.general.reject_unknown_sender_domain == '1' %} +{% do smtpd_recipient_restrictions.append('reject_unknown_sender_domain') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.reject_unknown_recipient_domain') and OPNsense.postfix.general.reject_unknown_recipient_domain == '1' %} +{% do smtpd_recipient_restrictions.append('reject_unknown_recipient_domain') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.reject_non_fqdn_sender') and OPNsense.postfix.general.reject_non_fqdn_sender == '1' %} +{% do smtpd_recipient_restrictions.append('reject_non_fqdn_sender') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.reject_non_fqdn_recipient') and OPNsense.postfix.general.reject_non_fqdn_recipient == '1' %} +{% do smtpd_recipient_restrictions.append('reject_non_fqdn_recipient') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.permit_sasl_authenticated') and OPNsense.postfix.general.permit_sasl_authenticated == '1' %} +{% do smtpd_recipient_restrictions.append('permit_sasl_authenticated') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.permit_tls_clientcerts') and OPNsense.postfix.general.permit_tls_clientcerts == '1' %} +{% do smtpd_recipient_restrictions.append('permit_tls_clientcerts') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.permit_mynetworks') and OPNsense.postfix.general.permit_mynetworks == '1' %} +{% do smtpd_recipient_restrictions.append('permit_mynetworks') %} +{% endif %} +{% if helpers.exists('OPNsense.postfix.general.reject_unauth_destination') and OPNsense.postfix.general.reject_unauth_destination == '1' %} +{% do smtpd_recipient_restrictions.append('reject_unauth_destination') %} +{% endif %} + +{% if smtpd_recipient_restrictions|length >= 1 %} +smtpd_recipient_restrictions = {{ smtpd_recipient_restrictions | join(', ') }} +{% endif %} + +smtpd_helo_required = yes + +{% endif %} diff --git a/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/master.cf b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/master.cf new file mode 100644 index 000000000..4fb709e7f --- /dev/null +++ b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/master.cf @@ -0,0 +1,135 @@ +{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %} +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master" or +# on-line: http://www.postfix.org/master.5.html). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ========================================================================== +smtp inet n - n - - smtpd +#smtp inet n - n - 1 postscreen +#smtpd pass - - n - - smtpd +#dnsblog unix - - n - 0 dnsblog +#tlsproxy unix - - n - 0 tlsproxy +#submission inet n - n - - smtpd +# -o syslog_name=postfix/submission +# -o smtpd_tls_security_level=encrypt +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_tls_auth_only=yes +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= +# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +#smtps inet n - n - - smtpd +# -o syslog_name=postfix/smtps +# -o smtpd_tls_wrappermode=yes +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= +# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +#628 inet n - n - - qmqpd +pickup unix n - n 60 1 pickup +cleanup unix n - n - 0 cleanup +qmgr unix n - n 300 1 qmgr +#qmgr unix n - n 300 1 oqmgr +tlsmgr unix - - n 1000? 1 tlsmgr +rewrite unix - - n - - trivial-rewrite +bounce unix - - n - 0 bounce +defer unix - - n - 0 bounce +trace unix - - n - 0 bounce +verify unix - - n - 1 verify +flush unix n - n 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - n - - smtp +relay unix - - n - - smtp +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - n - - showq +error unix - - n - - error +retry unix - - n - - error +discard unix - - n - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - n - - lmtp +anvil unix - - n - 1 anvil +scache unix - - n - 1 scache +# +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== +# +# maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 +# +#maildrop unix - n n - - pipe +# flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} +# +# ==================================================================== +# +# See the Postfix UUCP_README file for configuration details. +# +#uucp unix - n n - - pipe +# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# ==================================================================== +# +# Other external delivery methods. +# +#ifmail unix - n n - - pipe +# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +# +#bsmtp unix - n n - - pipe +# flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient +# +#scalemail-backend unix - n n - 2 pipe +# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store +# ${nexthop} ${user} ${extension} +# +#mailman unix - n n - - pipe +# flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py +# ${nexthop} ${user} + + +{% endif %} diff --git a/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/postfix b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/postfix new file mode 100644 index 000000000..cf34c5829 --- /dev/null +++ b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/postfix @@ -0,0 +1,6 @@ +{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %} +postfix_opnsense_bootup_run="/usr/local/opnsense/scripts/OPNsense/Postfix/setup.sh" +postfix_enable="YES" +{% else %} +postfix_enable="NO" +{% endif %} diff --git a/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/recipient_access b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/recipient_access new file mode 100644 index 000000000..c82b63b8b --- /dev/null +++ b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/recipient_access @@ -0,0 +1,4 @@ +{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %} +{% if helpers.exists('OPNsense.postfix.general.check_recipient_access') %} +{% endif %} +{% endif %} diff --git a/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/sender_access b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/sender_access new file mode 100644 index 000000000..c82b63b8b --- /dev/null +++ b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/sender_access @@ -0,0 +1,4 @@ +{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %} +{% if helpers.exists('OPNsense.postfix.general.check_recipient_access') %} +{% endif %} +{% endif %} diff --git a/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/transport b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/transport new file mode 100644 index 000000000..8c058a078 --- /dev/null +++ b/mail/postfix/src/opnsense/service/templates/OPNsense/Postfix/transport @@ -0,0 +1,9 @@ +{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %} +{% if helpers.exists('OPNsense.postfix.domain.domains.domain') %} +{% for domain in helpers.toList('OPNsense.postfix.domain.domains.domain') %} +{% if domain.enabled == '1' %} +{{ domain.domainname }} smtp:{{ domain.destination }} +{% endif %} +{% endfor %} +{% endif %} +{% endif %} diff --git a/mail/rspamd/Makefile b/mail/rspamd/Makefile new file mode 100644 index 000000000..fc1f4ea2d --- /dev/null +++ b/mail/rspamd/Makefile @@ -0,0 +1,8 @@ +PLUGIN_NAME= rspamd +PLUGIN_VERSION= 0.1 +PLUGIN_COMMENT= Protect your network from spam +PLUGIN_DEPENDS= rspamd +PLUGIN_MAINTAINER= franz.fabian.94@gmail.com +PLUGIN_DEVEL= yes + +.include "../../Mk/plugins.mk" diff --git a/mail/rspamd/pkg-descr b/mail/rspamd/pkg-descr new file mode 100644 index 000000000..4f1eef47b --- /dev/null +++ b/mail/rspamd/pkg-descr @@ -0,0 +1,3 @@ +Rspamd is fast, modular and lightweight spam filter. It is designed to work +with big amount of mail and can be easily extended with own filters written in +lua. diff --git a/mail/rspamd/src/etc/inc/plugins.inc.d/rspamd.inc b/mail/rspamd/src/etc/inc/plugins.inc.d/rspamd.inc new file mode 100644 index 000000000..7b5699a7e --- /dev/null +++ b/mail/rspamd/src/etc/inc/plugins.inc.d/rspamd.inc @@ -0,0 +1,62 @@ +general->enabled == '1') { + return true; + } + + return false; +} + +function rspamd_firewall($fw) +{ + if (rspamd_enabled()) { + } +} + +function rspamd_services() +{ + $services = array(); + + if (rspamd_enabled()) { + $services[] = array( + 'description' => gettext('Rapid Spamfilter Daemon'), + 'configd' => array( + 'restart' => array('rspamd restart'), + 'start' => array('rspamd start'), + 'stop' => array('rspamd stop'), + ), + 'name' => 'rspamd', + 'pidfile' => '/var/run/rspamd/rspamd.pid' + ); + } + return $services; +} diff --git a/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/ServiceController.php b/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/ServiceController.php new file mode 100644 index 000000000..468707216 --- /dev/null +++ b/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/ServiceController.php @@ -0,0 +1,139 @@ +request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun('rspamd restart'); + return array('response' => $response); + } else { + return array('response' => array()); + } + } + + /** + * retrieve status of rspamd + * @return array + * @throws \Exception + */ + public function statusAction() + { + $backend = new Backend(); + $rspamd = new RSpamd(); + $response = $backend->configdRun('rspamd status'); + + if (strpos($response, 'not running') > 0) { + if ((string)$rspamd->general->enabled == 1) { + $status = 'stopped'; + } else { + $status = 'disabled'; + } + } elseif (strpos($response, 'is running') > 0) { + $status = 'running'; + } elseif ((string)$rspamd->general->enabled == 0) { + $status = 'disabled'; + } else { + $status = 'unknown'; + } + + + return array('status' => $status); + } + + /** + * reconfigure rspamd, generate config and reload + */ + public function reconfigureAction() + { + if ($this->request->isPost()) { + // close session for long running action + $this->sessionClose(); + + $rspamd = new RSpamd(); + $backend = new Backend(); + + $this->stopAction(); + + // generate template + $backend->configdRun('template reload OPNsense/Rspamd'); + + // (re)start daemon + if ((string)$rspamd->general->enabled == '1') { + $this->startAction(); + } + + return array('status' => 'ok'); + } else { + return array('status' => 'failed'); + } + } + + /** + * stop rspamd service + * @return array + */ + public function stopAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun('rspamd stop'); + return array('response' => $response); + } else { + return array('response' => array()); + } + } + /** + * start rspamd service + * @return array + */ + public function startAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun('rspamd start'); + return array('response' => $response); + } else { + return array('response' => array()); + } + } +} diff --git a/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/SettingsController.php b/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/SettingsController.php new file mode 100644 index 000000000..c4b1d8da4 --- /dev/null +++ b/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/Api/SettingsController.php @@ -0,0 +1,38 @@ +view->clamav_installed = (trim($backend->configdRun('firmware plugin clamav')) == '1'); + $this->view->redis_installed = (trim($backend->configdRun('firmware plugin redis')) == '1'); + $this->view->redis_plugin_enabled = ((string)((new RSpamd())->general->enable_redis_plugin)) == '1'; + $this->view->title = gettext("Rspamd Mail Protection"); + $this->view->settings = $this->getForm("settings"); + $this->view->pick('OPNsense/Rspamd/index'); + } +} diff --git a/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/forms/settings.xml b/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/forms/settings.xml new file mode 100644 index 000000000..a26568758 --- /dev/null +++ b/mail/rspamd/src/opnsense/mvc/app/controllers/OPNsense/Rspamd/forms/settings.xml @@ -0,0 +1,348 @@ +
+ + + + rspamd.general.enabled + + checkbox + Enable or disable the rspamd service. + + + rspamd.general.enable_redis_plugin + + checkbox + If you check this box, the local Redis server will be available to the modules (some do not work without it). + + + + + + + rspamd.graylist.expire + + text + Time after which the graylist state expires in days. + + + rspamd.graylist.timeout + + text + + + rspamd.graylist.max_data_len + + text + The limit of the length of data to hash. + + + rspamd.graylist.ipv4mask + + text + Mask bits are used to limit the network range from which the message may be resent. This is used to avoid a rejection if another server sends the second mail. + + + rspamd.graylist.ipv6mask + + text + Mask bits are used to limit the network range from which the message may be resent. This is used to avoid a rejection if another server sends the second mail. + + + + + + rspamd.dkim.cache_size + + text + + + rspamd.dkim.cache_expire + + text + + + rspamd.dkim.time_jitter + + text + + + rspamd.dkim.trusted_only + + checkbox + + + rspamd.dkim.skip_multi + + checkbox + + + + rspamd.dkim.allow_envfrom_empty + + checkbox + + + rspamd.dkim.allow_hdrfrom_mismatch + + checkbox + + + rspamd.dkim.allow_hdrfrom_multiple + + checkbox + + + rspamd.dkim.allow_username_mismatch + + checkbox + + + rspamd.dkim.auth_only + + checkbox + + + rspamd.dkim.sign_local + + checkbox + + + rspamd.dkim.try_fallback + + checkbox + + + rspamd.dkim.use_domain + + dropdown + + + rspamd.dkim.use_esld + + checkbox + + + + + rspamd.mx-check.enabled + + checkbox + + + rspamd.mx_check.expire + + text + + + + + rspamd.phishing.openphish_enabled + + checkbox + + + rspamd.phishing.openphish_premium_enabled + + checkbox + + + rspamd.phishing.phishtank_enabled + + checkbox + + + + + rspamd.rate_limit.per_recipient.count + + text + + + rspamd.rate_limit.per_recipient.time + + text + + + rspamd.rate_limit.per_recipient.time_unit + + dropdown + + + rspamd.rate_limit.per_ip.count + + text + + + rspamd.rate_limit.per_ip.time + + text + + + rspamd.rate_limit.per_ip.time_unit + + dropdown + + + rspamd.rate_limit.per_ip_from.count + + text + + + rspamd.rate_limit.per_ip_from.time + + text + + + rspamd.rate_limit.per_ip_from.time_unit + + dropdown + + + rspamd.rate_limit.bounce.count + + text + + + rspamd.rate_limit.bounce.time + + text + + + rspamd.rate_limit.bounce.time_unit + + dropdown + + + rspamd.rate_limit.bounce_ip.count + + text + + + rspamd.rate_limit.bounce_ip.time + + text + + + rspamd.rate_limit.bounce_ip.time_unit + + dropdown + + + rspamd.rate_limit.user.count + + text + + + rspamd.rate_limit.user.time + + text + + + rspamd.rate_limit.user.time_unit + + dropdown + + + rspamd.rate_limit.whitelisted_rcpts + + select_multiple + + true + + + rspamd.rate_limit.max_rcpt + + text + + + + + rspamd.spamtrap.enabled + + checkbox + Enable this if you want to enable the spam trap. + + + rspamd.spamtrap.fuzzy_learning + + checkbox + Enable this if you want to enable fuzzy learning. + + + rspamd.spamtrap.spam_learning + + checkbox + Enable this if you want to enable bayes learning. + + + rspamd.spamtrap.spam_recipients + + select_multiple + + true + Enter regular expressions in the form trap@example\.com into this field. The value is automatically enclosed in slashes and the case insensitive option is added. + + + + + rspamd.spf.spf_cache_size + + text + Enter the size of the SPF cache. + + + rspamd.spf.spf_cache_expire + + text + Enter how long SPF entries are valid. + + + + + + + rspamd.av.force-reject + + checkbox + If set, the mail will be rejected. + + + rspamd.av.attachments-only + + checkbox + If checked, only attached files are scanned and images are omitted. + + + rspamd.av.max-size + + text + If set, a message large than this size will not be scanned. + + + rspamd.av.whitelist + + select_multiple + + true + Mails from IPs entered here will not be scanned. + + + + + rspamd.surbl.whitelist + + select_multiple + + true + + + rspamd.surbl.exceptions + + select_multiple + + true + + + + + rspamd-general-settings +
diff --git a/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/ACL/ACL.xml b/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/ACL/ACL.xml new file mode 100644 index 000000000..f75c79bef --- /dev/null +++ b/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/ACL/ACL.xml @@ -0,0 +1,9 @@ + + + antispam + + ui/rspamd/* + api/rspamd/* + + + diff --git a/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/Menu/Menu.xml b/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/Menu/Menu.xml new file mode 100644 index 000000000..a7e9b27fb --- /dev/null +++ b/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/Menu/Menu.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/RSpamd.php b/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/RSpamd.php new file mode 100644 index 000000000..633e88ed1 --- /dev/null +++ b/mail/rspamd/src/opnsense/mvc/app/models/OPNsense/Rspamd/RSpamd.php @@ -0,0 +1,34 @@ + + //OPNsense/Rspamd + rspamd anti spam filter + + + + 0 + Y + + + 0 + Y + + + + + + N + 1 + + + N + 1 + + + N + + + 1 + N + 32 + A valid IPv4 mask must be between 1 and 32 bits. + 19 + + + 1 + N + 128 + 64 + A valid IPv6 mask must be between 1 and 128 bits. 64 bits are recommended as this is the recommended subnet size in IPv6. + + + + + + 1 + N + A valid cache size must be set. + + + 1 + N + A valid cache expiration must be set. + + + 1 + N + A valid time jitter must be set. + + + 0 + Y + + + 0 + Y + + + + 1 + Y + + + 0 + Y + + + 0 + Y + + + 0 + Y + + + 1 + Y + + + 1 + Y + + + 0 + Y + + + header + Y + +
Header
+ Envelope +
+
+ + 1 + Y + +
+ + + + 0 + Y + + + 1 + N + 86400 + A valid cache expiration must be set. + + + + + + 0 + Y + + + 0 + Y + + + 0 + Y + + + + + + + 1 + N + The count value must be a positive number. + + + + m + Y + + Seconds + Minutes + Hours + + + + + + 1 + N + The count value must be a positive number. + + + + m + Y + + Seconds + Minutes + Hours + + + + + + 1 + N + The count value must be a positive number. + + + + m + Y + + Seconds + Minutes + Hours + + + + + + 1 + N + The count value must be a positive number. + + + + m + Y + + Seconds + Minutes + Hours + + + + + + 1 + N + The count value must be a positive number. + + + + m + Y + + Seconds + Minutes + Hours + + + + + + 1 + N + The count value must be a positive number. + + + + m + Y + + Seconds + Minutes + Hours + + + + + postmaster,mailer-daemon + + + 1 + Y + 20 + + + + + + 0 + Y + + + 0 + Y + + + 1 + Y + + + N + + + + + + 1 + N + 2 + A valid cache size in kilobytes must be set. + + + 1 + N + A valid expiration time must be set. + + + + + + 1 + Y + + + 1 + Y + + + 1 + 20000000 + N + A valid maximum size in bytes must be set. + + + N + + + + + + N + + + N + + +
+ diff --git a/mail/rspamd/src/opnsense/mvc/app/views/OPNsense/Rspamd/index.volt b/mail/rspamd/src/opnsense/mvc/app/views/OPNsense/Rspamd/index.volt new file mode 100644 index 000000000..53dd4d589 --- /dev/null +++ b/mail/rspamd/src/opnsense/mvc/app/views/OPNsense/Rspamd/index.volt @@ -0,0 +1,166 @@ +{# + + Copyright (C) 2017 Fabian Franz + OPNsense® is Copyright © 2014 – 2015 by Deciso B.V. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + +#} + + + +{% if !clamav_installed %} + +{% endif %} + + + + +
+ {% for tab in settings['tabs']|default([]) %} + {% if tab['subtabs']|default(false) %} + {# Tab with dropdown #} + {% for subtab in tab['subtabs']|default({})%} +
+ {{ partial("layout_partials/base_form",['fields':subtab[2],'id':'frm_'~subtab[0],'data_title':subtab[1],'apply_btn_id':'save_'~subtab[0]]) }} +
+ {% endfor %} + {% endif %} + {% if tab['subtabs']|default(false)==false %} +
+ {{ partial("layout_partials/base_form",['fields':tab[2],'id':'frm_'~tab[0],'apply_btn_id':'save_'~tab[0]]) }} +
+ {% endif %} + {% endfor %} +
diff --git a/mail/rspamd/src/opnsense/scripts/rspamd/setup.sh b/mail/rspamd/src/opnsense/scripts/rspamd/setup.sh new file mode 100755 index 000000000..97f90dbfd --- /dev/null +++ b/mail/rspamd/src/opnsense/scripts/rspamd/setup.sh @@ -0,0 +1,8 @@ +#!/bin/sh +mkdir -p /var/db/rspamd +mkdir -p /var/log/rspamd +mkdir -p /var/run/rspamd + +chown nobody:nobody /var/db/rspamd +chown nobody:nobody /var/log/rspamd +chown nobody:nobody /var/run/rspamd diff --git a/mail/rspamd/src/opnsense/service/conf/actions.d/actions_rspamd.conf b/mail/rspamd/src/opnsense/service/conf/actions.d/actions_rspamd.conf new file mode 100644 index 000000000..e4711138a --- /dev/null +++ b/mail/rspamd/src/opnsense/service/conf/actions.d/actions_rspamd.conf @@ -0,0 +1,23 @@ +[start] +command:/usr/local/opnsense/scripts/rspamd/setup.sh;/usr/local/etc/rc.d/rspamd start +parameters: +type:script +message:starting rspamd + +[stop] +command:/usr/local/etc/rc.d/rspamd onestop +parameters: +type:script +message:stopping rspamd + +[restart] +command:/usr/local/opnsense/scripts/rspamd/setup.sh;/usr/local/etc/rc.d/rspamd restart +parameters: +type:script +message:restarting rspamd + +[status] +command:/usr/local/etc/rc.d/rspamd status;exit 0 +parameters: +type:script_output +message:request rspamd status diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/+TARGETS b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/+TARGETS new file mode 100644 index 000000000..0f83e7ba9 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/+TARGETS @@ -0,0 +1,15 @@ +rspamd:/etc/rc.conf.d/rspamd +antivirus.wl:/usr/local/etc/rspamd/local.d/antivirus.wl +antivirus.conf:/usr/local/etc/rspamd/local.d/antivirus.conf +dkim_signing.conf:/usr/local/etc/rspamd/local.d/dkim_signing.conf +dkim.conf:/usr/local/etc/rspamd/local.d/dkim.conf +spf.conf:/usr/local/etc/rspamd/local.d/spf.conf +spamtrap.conf:/usr/local/etc/rspamd/local.d/spamtrap.conf +surbl-whitelist.inc.local:/var/db/rspamd/surbl-whitelist.inc.local +2tld.inc.local:/var/db/rspamd/2tld.inc.local +greylist.conf:/usr/local/etc/rspamd/local.d/greylist.conf +phishing.conf:/usr/local/etc/rspamd/local.d/phishing.conf +mx_check.conf:/usr/local/etc/rspamd/local.d/mx_check.conf +ratelimit.conf:/usr/local/etc/rspamd/local.d/ratelimit.conf +redis.conf:/usr/local/etc/rspamd/local.d/redis.conf +spamtrap.map:/usr/local/etc/rspamd/maps.d/spamtrap.map diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/2tld.inc.local b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/2tld.inc.local new file mode 100644 index 000000000..7784d1b17 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/2tld.inc.local @@ -0,0 +1,5 @@ +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.surbl.exceptions') and OPNsense.Rspamd.surbl.exceptions != '' %} +{% for host in OPNsense.Rspamd.surbl.exceptions.split(',') %} +{{ host }} +{% endfor %} +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.conf new file mode 100644 index 000000000..3f191b265 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.conf @@ -0,0 +1,29 @@ +# +# Please don't modify this file as your changes might be overwritten with +# the next update. +# +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.av') %} + +clamav { +{% if helpers.exists('OPNsense.Rspamd.av.force-reject') and OPNsense.Rspamd.av['force-reject'] == '1' %} + action = "reject"; +{% endif %} +{% if helpers.exists('OPNsense.Rspamd.av.attachments-only') and OPNsense.Rspamd.av['attachments-only'] == '1' %} + attachments_only = true; +{% else %} + attachments_only = false; +{% endif %} +{% if helpers.exists('OPNsense.Rspamd.av.max-size') and OPNsense.Rspamd.av['max-size'] != '' %} + # If `max_size` is set, messages > n bytes in size are not scanned + max_size = {{ OPNsense.Rspamd.av['max-size'] }}; +{% endif %} + symbol = "CLAM_VIRUS"; + type = "clamav"; + #log_clean = true; + +{% if helpers.exists('OPNsense.clamav.general') and OPNsense.clamav.general.enabled == '1' %} + servers = "/var/run/clamav/clamd.sock"; +{% endif %} +} + +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.wl b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.wl new file mode 100644 index 000000000..234b45174 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/antivirus.wl @@ -0,0 +1,5 @@ +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.av.whitelist') and OPNsense.Rspamd.av.whitelist != '' %} +{% for host in OPNsense.Rspamd.av.whitelist.split(',') %} +{{ host }} +{% endfor %} +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim.conf new file mode 100644 index 000000000..b2c5dd1d7 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim.conf @@ -0,0 +1,13 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# + +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.dkim') %} + + dkim_cache_size = {{ OPNsense.Rspamd.dkim.cache_size|default('2') }}k; + dkim_cache_expire = {{ OPNsense.Rspamd.dkim.cache_expire|default('1') }}d; + time_jitter = {{ OPNsense.Rspamd.dkim.time_jitter|default('6') }}h; + trusted_only = {% if helpers.exists('OPNsense.Rspamd.dkim.trusted_only') and OPNsense.Rspamd.dkim.trusted_only == '1' %}true{% else %}false{% endif %}; + skip_multi = {% if helpers.exists('OPNsense.Rspamd.dkim.skip_multi') and OPNsense.Rspamd.dkim.skip_multi == '1' %}true{% else %}false{% endif %}; + +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim_signing.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim_signing.conf new file mode 100644 index 000000000..2e4c20d71 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/dkim_signing.conf @@ -0,0 +1,22 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# + +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.dkim') %} + allow_envfrom_empty = {% if helpers.exists('OPNsense.Rspamd.dkim.allow_envfrom_empty') and OPNsense.Rspamd.dkim.allow_envfrom_empty == '1' %}true{% else %}false{% endif %}; + allow_hdrfrom_mismatch = {% if helpers.exists('OPNsense.Rspamd.dkim.allow_hdrfrom_mismatch') and OPNsense.Rspamd.dkim.allow_hdrfrom_mismatch == '1' %}true{% else %}false{% endif %}; + allow_hdrfrom_multiple = {% if helpers.exists('OPNsense.Rspamd.dkim.allow_hdrfrom_multiple') and OPNsense.Rspamd.dkim.allow_hdrfrom_multiple == '1' %}true{% else %}false{% endif %}; + allow_username_mismatch = {% if helpers.exists('OPNsense.Rspamd.dkim.allow_username_mismatch') and OPNsense.Rspamd.dkim.allow_username_mismatch == '1' %}true{% else %}false{% endif %}; + auth_only = {% if helpers.exists('OPNsense.Rspamd.dkim.auth_only') and OPNsense.Rspamd.dkim.auth_only == '1' %}true{% else %}false{% endif %}; + #path = "/var/lib/rspamd/dkim/$domain.$selector.key"; + selector = "dkim"; + sign_local = {% if helpers.exists('OPNsense.Rspamd.dkim.sign_local') and OPNsense.Rspamd.dkim.sign_local == '1' %}true{% else %}false{% endif %}; + symbol = "DKIM_SIGNED"; + try_fallback = {% if helpers.exists('OPNsense.Rspamd.dkim.try_fallback') and OPNsense.Rspamd.dkim.try_fallback == '1' %}true{% else %}false{% endif %}; + use_domain = "{{ OPNsense.Rspamd.dkim.use_domain|default("header") }}"; + use_esld = {% if helpers.exists('OPNsense.Rspamd.dkim.use_esld') and OPNsense.Rspamd.dkim.use_esld == '1' %}true{% else %}false{% endif %}; + use_redis = false; + # Hash for DKIM keys in Redis + key_prefix = "DKIM_KEYS"; + +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/greylist.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/greylist.conf new file mode 100644 index 000000000..2af6f1e15 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/greylist.conf @@ -0,0 +1,14 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.graylist') %} + expire = {{ OPNsense.Rspamd.graylist.expire|default('1') }}d; + timeout = {{ OPNsense.Rspamd.graylist.timeout|default('1') }}min; # 5 minutes by default + key_prefix = "rg"; # default hash name + max_data_len = {{ OPNsense.Rspamd.graylist.max_data_len|default('10') }}k; + message = "Try again later"; + #symbol = "GREYLIST"; + action = "soft reject"; # default greylisted action + ipv4_mask = {{ OPNsense.Rspamd.graylist.ipv4mask|default('19') }}; + ipv6_mask = {{ OPNsense.Rspamd.graylist.ipv6mask|default('64') }}; +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/mx_check.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/mx_check.conf new file mode 100644 index 000000000..bb3069acb --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/mx_check.conf @@ -0,0 +1,9 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# + +{% if helpers.exists('OPNsense.Rspamd.mx-check.enabled') %} + timeout = 1.0; + expire = {{ OPNsense.Rspamd['mx-check'].expire|default('86400') }}; + enabled = {% if helpers.exists('OPNsense.Rspamd.mx-check.enabled') and OPNsense.Rspamd['mx-check'].enabled == '1' %}true{% else %}false{% endif %}; +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/phishing.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/phishing.conf new file mode 100644 index 000000000..e40fe63fa --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/phishing.conf @@ -0,0 +1,9 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.phishing') %} + openphish_enabled = {% if helpers.exists('OPNsense.Rspamd.phishing.openphish_enabled') and OPNsense.Rspamd.phishing.openphish_enabled == '1' %}true{% else %}false{% endif %}; + openphish_premium = {% if helpers.exists('OPNsense.Rspamd.phishing.openphish_premium_enabled') and OPNsense.Rspamd.phishing.openphish_premium_enabled == '1' %}true{% else %}false{% endif %}; + # Disabled by default + phishtank_enabled = {% if helpers.exists('OPNsense.Rspamd.phishing.phishtank_enabled') and OPNsense.Rspamd.phishing.phishtank_enabled == '1' %}true{% else %}false{% endif %}; +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/ratelimit.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/ratelimit.conf new file mode 100644 index 000000000..4caa7069b --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/ratelimit.conf @@ -0,0 +1,62 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# + +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.rate_limit') %} + +rates { + # Limit for all mail per recipient (rate 2 per minute) +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_recipient.count') and OPNsense.Rspamd.rate_limit.per_recipient.count != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_recipient.time') and OPNsense.Rspamd.rate_limit.per_recipient.time != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_recipient.time_unit') and OPNsense.Rspamd.rate_limit.per_recipient.time_unit != '' %} + to = "{{ OPNsense.Rspamd.rate_limit.per_recipient.count }} / {{ OPNsense.Rspamd.rate_limit.per_recipient.time }}{{ OPNsense.Rspamd.rate_limit.per_recipient.time_unit }}"; +{% endif %} +{% endif %} +{% endif %} + # Limit for all mail per one source ip +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_ip.count') and OPNsense.Rspamd.rate_limit.per_ip.count != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_ip.time') and OPNsense.Rspamd.rate_limit.per_ip.time != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_ip.time_unit') and OPNsense.Rspamd.rate_limit.per_ip.time_unit != '' %} + to_ip = "{{ OPNsense.Rspamd.rate_limit.per_ip.count }} / {{ OPNsense.Rspamd.rate_limit.per_ip.time }}{{ OPNsense.Rspamd.rate_limit.per_ip.time_unit }}"; +{% endif %} +{% endif %} +{% endif %} + # Limit for all mail per one source ip and from address (rate 1 per minute) +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_ip_from.count') and OPNsense.Rspamd.rate_limit.per_ip_from.count != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_ip_from.time') and OPNsense.Rspamd.rate_limit.per_ip_from.time != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.per_ip_from.time_unit') and OPNsense.Rspamd.rate_limit.per_ip_from.time_unit != '' %} + to_ip_from = "{{ OPNsense.Rspamd.rate_limit.per_ip_from.count }} / {{ OPNsense.Rspamd.rate_limit.per_ip_from.time }}{{ OPNsense.Rspamd.rate_limit.per_ip_from.time_unit }}"; +{% endif %} +{% endif %} +{% endif %} + # Limit for all bounce mail (rate 2 per hour) +{% if helpers.exists('OPNsense.Rspamd.rate_limit.bounce.count') and OPNsense.Rspamd.rate_limit.bounce.count != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.bounce.time') and OPNsense.Rspamd.rate_limit.bounce.time != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.bounce.time_unit') and OPNsense.Rspamd.rate_limit.bounce.time_unit != '' %} + bounce_to = "{{ OPNsense.Rspamd.rate_limit.bounce.count }} / {{ OPNsense.Rspamd.rate_limit.bounce.time }}{{ OPNsense.Rspamd.rate_limit.bounce.time_unit }}"; +{% endif %} +{% endif %} +{% endif %} + # Limit for bounce mail per one source ip +{% if helpers.exists('OPNsense.Rspamd.rate_limit.bounce_ip.count') and OPNsense.Rspamd.rate_limit.bounce_ip.count != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.bounce_ip.time') and OPNsense.Rspamd.rate_limit.bounce_ip.time != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.bounce_ip.time_unit') and OPNsense.Rspamd.rate_limit.bounce_ip.time_unit != '' %} + bounce_to_ip = "{{ OPNsense.Rspamd.rate_limit.bounce_ip.count }} / {{ OPNsense.Rspamd.rate_limit.bounce_ip.time }}{{ OPNsense.Rspamd.rate_limit.bounce_ip.time_unit }}"; +{% endif %} +{% endif %} +{% endif %} + # Limit for all mail per authenticated user (rate 1 per minute) +{% if helpers.exists('OPNsense.Rspamd.rate_limit.user.count') and OPNsense.Rspamd.rate_limit.user.count != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.user.time') and OPNsense.Rspamd.rate_limit.user.time != '' %} +{% if helpers.exists('OPNsense.Rspamd.rate_limit.user.time_unit') and OPNsense.Rspamd.rate_limit.user.time_unit != '' %} + user = "{{ OPNsense.Rspamd.rate_limit.user.count }} / {{ OPNsense.Rspamd.rate_limit.user.time }}{{ OPNsense.Rspamd.rate_limit.user.time_unit }}"; +{% endif %} +{% endif %} +{% endif %} +} +# If symbol is specified, then it is inserted instead of setting result +#symbol = "R_RATELIMIT"; +whitelisted_rcpts = "{{ OPNsense.Rspamd.rate_limit.whitelisted_rcpts|default('postmaster,mailer-daemon') }}"; +max_rcpt = {{ OPNsense.Rspamd.rate_limit.max_rcpt|default('20') }}; + +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/redis.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/redis.conf new file mode 100644 index 000000000..e3b39b780 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/redis.conf @@ -0,0 +1,28 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# +# You can modify '$LOCAL_CONFDIR/rspamd.conf.local.override' to redefine +# parameters defined on the top level +# +# You can modify '$LOCAL_CONFDIR/rspamd.conf.local' to add +# parameters defined on the top level +# +# For specific modules or configuration you can also modify +# '$LOCAL_CONFDIR/local.d/file.conf' - to add your options or rewrite defaults +# '$LOCAL_CONFDIR/override.d/file.conf' - to override the defaults +# +# See https://rspamd.com/doc/configuration/redis.html + +{% if helpers.exists('OPNsense.Rspamd.general.enable_redis_plugin') and OPNsense.Rspamd.general.enable_redis_plugin == '1' %} +{% if helpers.exists('OPNsense.redis.general.enabled') and OPNsense.redis.general.enabled == '1' %} + +servers = "::1"; +write_servers = "::1"; +timeout = 10s; +#db = "0"; +{% if helpers.exists('OPNsense.redis.security.password') and OPNsense.redis.security.password != '' %} +password = "{{ OPNsense.redis.security.password.replace('"',"\\\"") }}"; +{% endif %} + +{% endif %} +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/rspamd b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/rspamd new file mode 100644 index 000000000..bb02f63f2 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/rspamd @@ -0,0 +1,6 @@ +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' %} +rspamd_enable="YES" +rspamd_opnsense_bootup_run="/usr/local/opnsense/scripts/rspamd/setup.sh" +{% else %} +rspamd_enable="NO" +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.conf new file mode 100644 index 000000000..14edad5b6 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.conf @@ -0,0 +1,28 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# + + +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.spamtrap') %} + # Optionally set an action + #action = "no action"; + # A map file containing regexp entries for spamtrap emails and domains + map = file://$LOCAL_CONFDIR/maps.d/spamtrap.map + # Name of the symbol + #symbol = "SPAMTRAP"; + # A score for this module + #score = 0.0; + # Flag to enable fuzzy learning + learn_fuzzy = {% if helpers.exists('OPNsense.Rspamd.spamtrap.fuzzy_learning') and OPNsense.Rspamd.spamtrap.fuzzy_learning == '1' %}true{% else %}false{% endif %}; + # Flag to enable bayes spam learning + learn_spam = {% if helpers.exists('OPNsense.Rspamd.spamtrap.spam_learning') and OPNsense.Rspamd.spamtrap.spam_learning == '1' %}true{% else %}false{% endif %}; + # Fuzzy flag + #fuzzy_flag = 1; + # Fuzzy weight + #fuzy_weight = 10; + # Redis key prefix + #key_prefix = 'sptr_'; + + # !!! Disabled by default !!! + enabled = {% if helpers.exists('OPNsense.Rspamd.spamtrap.enabled') and OPNsense.Rspamd.spamtrap.enabled == '1' %}true{% else %}false{% endif %}; +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.map b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.map new file mode 100644 index 000000000..f2cfd0041 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spamtrap.map @@ -0,0 +1,5 @@ +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.spamtrap.spam_recipients') %} +{% for recipient in OPNsense.Rspamd.spamtrap.spam_recipients.split(',') %} +/{{ recipient }}/i +{% endfor %} +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spf.conf b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spf.conf new file mode 100644 index 000000000..0a81e7a87 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/spf.conf @@ -0,0 +1,9 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.spf') %} + + spf_cache_size = {{ OPNsense.Rspamd.spf.spf_cache_size|default("2") }}k; + spf_cache_expire = {{ OPNsense.Rspamd.spf.spf_cache_expire|default("1") }}d; + +{% endif %} diff --git a/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/surbl-whitelist.inc.local b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/surbl-whitelist.inc.local new file mode 100644 index 000000000..2098ba554 --- /dev/null +++ b/mail/rspamd/src/opnsense/service/templates/OPNsense/Rspamd/surbl-whitelist.inc.local @@ -0,0 +1,5 @@ +{% if helpers.exists('OPNsense.Rspamd.general.enabled') and OPNsense.Rspamd.general.enabled == '1' and helpers.exists('OPNsense.Rspamd.surbl.whitelist') and OPNsense.Rspamd.surbl.whitelist != '' %} +{% for host in OPNsense.Rspamd.surbl.whitelist.split(',') %} +{{ host }} +{% endfor %} +{% endif %}