Commit 492171d1 authored by Jesse Norell's avatar Jesse Norell
Browse files

verify recipient addrs for amavis from downstream smtpd

parent f719d25d
Pipeline #9477 passed with stage
in 10 minutes and 29 seconds
......@@ -1107,7 +1107,7 @@ class installer_base {
$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
unset($server_ini_rec);
//* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removeal after an update
//* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removal after an update
$rbl_list = '';
if (@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') {
$rbl_hosts = explode(",", str_replace(" ", "", $server_ini_array['mail']['realtime_blackhole_list']));
......@@ -1647,6 +1647,12 @@ class installer_base {
public function configure_amavis() {
global $conf;
//* These postconf commands will be executed on installation and update
$server_ini_rec = $this->db->queryOneRecord("SELECT mail_server, config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
$mail_server = ($server_ini_rec['mail_server']) ? true : false;
unset($server_ini_rec);
// amavisd user config file
$configfile = 'amavisd_user_config';
if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user')) copy($conf['amavis']['config_dir'].'/conf.d/50-user', $conf['amavis']['config_dir'].'/50-user~');
......@@ -1660,63 +1666,85 @@ class installer_base {
wf($conf['amavis']['config_dir'].'/conf.d/50-user', $content);
chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640);
// TODO: chmod and chown on the config file
$mail_config = $server_ini_array['mail'];
//* only change postfix config if amavisd is active filter
if($mail_server && $mail_config['content_filter'] === 'amavisd') {
// test if lmtp if available
$configure_lmtp = $this->get_postfix_service('lmtp','unix');
// test if lmtp if available
$configure_lmtp = $this->get_postfix_service('lmtp','unix');
// Adding the amavisd commands to the postfix configuration
$postconf_commands = array ();
// Adding the amavisd commands to the postfix configuration
// Add array for no error in foreach and maybe future options
$postconf_commands = array ();
// Check for amavisd -> pure webserver with postfix for mailing without antispam
if ($conf['amavis']['installed']) {
$content_filter_service = ($configure_lmtp) ? 'lmtp' : 'amavis';
$postconf_commands[] = "content_filter = ${content_filter_service}:[127.0.0.1]:10024";
$postconf_commands[] = 'receive_override_options = no_address_mappings';
$postconf_commands[] = 'address_verify_virtual_transport = smtp:[127.0.0.1]:10025';
$postconf_commands[] = 'address_verify_transport_maps = static:smtp:[127.0.0.1]:10025';
}
// Check for amavisd -> pure webserver with postfix for mailing without antispam
if ($conf['amavis']['installed']) {
$content_filter_service = ($configure_lmtp) ? 'lmtp' : 'amavis';
$postconf_commands[] = "content_filter = ${content_filter_service}:[127.0.0.1]:10024";
$postconf_commands[] = 'receive_override_options = no_address_mappings';
}
$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
$new_options = array();
foreach ($options as $value) {
$value = trim($value);
if ($value == '') continue;
if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
continue;
}
$new_options[] = $value;
}
if ($configure_lmtp) {
for ($i = 0; isset($new_options[$i]); $i++) {
if ($new_options[$i] == 'reject_unlisted_recipient') {
array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${config_dir}/mysql-verify_recipients.cf"));
break;
}
}
# postfix < 3.3 needs this when using reject_unverified_recipient:
if(version_compare($postfix_version, 3.3, '<')) {
$postconf_commands[] = "enable_original_recipient = yes";
}
}
$postconf_commands[] = "smtpd_recipient_restrictions = ".implode(", ", $new_options);
// Make a backup copy of the main.cf file
copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~2');
// Make a backup copy of the main.cf file
copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~2');
// Executing the postconf commands
foreach($postconf_commands as $cmd) {
$command = "postconf -e '$cmd'";
caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
// Executing the postconf commands
foreach($postconf_commands as $cmd) {
$command = "postconf -e '$cmd'";
caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
$config_dir = $conf['postfix']['config_dir'];
$config_dir = $conf['postfix']['config_dir'];
// Adding amavis-services to the master.cf file if the service does not already exists
// $add_amavis = !$this->get_postfix_service('amavis','unix');
// $add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
// $add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
//*TODO: check templates against existing postfix-services to make sure we use the template
// Or just remove the old service definitions and add them again?
$add_amavis = $this->remove_postfix_service('amavis','unix');
$add_amavis_10025 = $this->remove_postfix_service('127.0.0.1:10025','inet');
$add_amavis_10027 = $this->remove_postfix_service('127.0.0.1:10027','inet');
if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
//* backup master.cf
if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
// adjust amavis-config
if($add_amavis) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
if ($add_amavis_10025) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
af($config_dir.'/master.cf', $content);
unset($content);
// Adding amavis-services to the master.cf file if the service does not already exists
// (just remove the old service definitions and add them again)
$add_amavis = $this->remove_postfix_service('amavis','unix');
$add_amavis_10025 = $this->remove_postfix_service('127.0.0.1:10025','inet');
$add_amavis_10027 = $this->remove_postfix_service('127.0.0.1:10027','inet');
if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
//* backup master.cf
if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
// adjust amavis-config
if($add_amavis) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
if ($add_amavis_10025) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
if ($add_amavis_10027) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
}
if ($add_amavis_10027) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
}
// Add the clamav user to the amavis group
......@@ -1746,14 +1774,18 @@ class installer_base {
global $conf;
//* These postconf commands will be executed on installation and update
$server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
$server_ini_rec = $this->db->queryOneRecord("SELECT mail_server, config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
$mail_server = ($server_ini_rec['mail_server']) ? true : false;
unset($server_ini_rec);
$mail_config = $server_ini_array['mail'];
if($mail_config['content_filter'] === 'rspamd') {
exec("postconf -X 'receive_override_options'");
exec("postconf -X 'content_filter'");
//* only change postfix config if rspamd is active filter
if($mail_server && $mail_config['content_filter'] === 'rspamd') {
exec("postconf -X receive_override_options");
exec("postconf -X content_filter");
exec("postconf -X address_verify_virtual_transport");
exec("postconf -X address_verify_transport_maps");
exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
......@@ -1804,6 +1836,9 @@ class installer_base {
if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
continue;
}
if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
continue;
}
$new_options[] = $value;
}
exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
......
......@@ -2,5 +2,5 @@
amavis unix - - - - 2 smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o smtp_bind_address=
-o smtp_bind_address=
......@@ -14,4 +14,6 @@
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o address_verify_virtual_transport=$virtual_transport
-o address_verify_transport_maps=$transport_maps
......@@ -13,7 +13,9 @@
-o strict_rfc821_envelopes=yes
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtp_send_xforward_command=yes
-o milter_default_action=accept
-o milter_macro_daemon_name=ORIGINATING
-o disable_dns_lookups=yes
-o address_verify_virtual_transport=$virtual_transport
-o address_verify_transport_maps=$transport_maps
-o milter_default_action=accept
-o milter_macro_daemon_name=ORIGINATING
......@@ -45,9 +45,6 @@ class validate_mail_relay_domain {
function validate_domain($field_name, $field_value, $validator) {
global $app, $conf;
if(empty($field_value) || $field_name != 'domain') return;
if(isset($app->remoting_lib->primary_id)) {
$id = $app->remoting_lib->primary_id;
} else {
......@@ -56,7 +53,7 @@ class validate_mail_relay_domain {
// mail_relay_domain.domain must be unique per server
$sql = "SELECT relay_domain_id, domain FROM mail_relay_domain WHERE domain = ? AND server_id = ? AND relay_domain_id != ?";
$domain_check = $app->db->queryOneRecord($sql, $field_value, $conf['server_id'], $id);
$domain_check = $app->db->queryOneRecord($sql, $field_value, $app->tform_actions->dataRecord['server_id'], $id);
if($domain_check) return $this->get_error('domain_error_unique');
}
......
......@@ -72,6 +72,12 @@ class postfix_server_plugin {
global $app, $conf;
$postfix_restart = false;
// Plugin should only run on mail servers
if(! $data['new']['mail_server']) {
$app->log("postfix_server_plugin: plugin is enabled but this server is not configured as a mail server.", LOGLEVEL_WARN);
return false;
}
// get the config
$app->uses("getconf,system");
$old_ini_data = $app->ini_parser->parse_ini_string($data['old']['config']);
......@@ -341,6 +347,10 @@ class postfix_server_plugin {
for ($i = 0; isset($new_options[$i]); $i++) {
if ($new_options[$i] == 'reject_unlisted_recipient') {
array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${quoted_postfix_config_dir}/mysql-verify_recipients.cf"));
$app->system->exec_safe("postconf -e ?", 'address_verify_virtual_transport = smtp:[127.0.0.1]:10025');
$app->system->exec_safe("postconf -e ?", 'address_verify_transport_maps = static:smtp:[127.0.0.1]:10025');
break;
}
}
......@@ -351,62 +361,64 @@ class postfix_server_plugin {
}
exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
if($mail_config['content_filter'] != $old_ini_data['mail']['content_filter']) {
$rslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_sender_login_mismatch," : "";
$raslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_authenticated_sender_login_mismatch," : "";
if($mail_config['content_filter'] == 'rspamd'){
exec("postconf -X 'receive_override_options'");
exec("postconf -X 'content_filter'");
$rslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_sender_login_mismatch," : "";
$raslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_authenticated_sender_login_mismatch," : "";
exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
exec("postconf -e 'milter_protocol = 6'");
exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'");
exec("postconf -e 'milter_default_action = accept'");
if($mail_config['content_filter'] == 'rspamd'){
exec("postconf -X 'receive_override_options'");
exec("postconf -X 'content_filter'");
exec("postconf -X address_verify_virtual_transport");
exec("postconf -X address_verify_transport_maps");
exec("postconf -e 'smtpd_sender_restrictions = ${raslm} permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender'");
exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
exec("postconf -e 'milter_protocol = 6'");
exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'");
exec("postconf -e 'milter_default_action = accept'");
exec("postconf -e 'smtpd_sender_restrictions = ${raslm} permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender'");
$new_options = array();
$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
foreach ($options as $key => $value) {
$value = trim($value);
if ($value == '') continue;
if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
continue;
}
$new_options[] = $value;
}
exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
// get all domains that have dkim enabled
if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
$new_options = array();
$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
foreach ($options as $key => $value) {
$value = trim($value);
if ($value == '') continue;
if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
continue;
}
$dkim_domains = $app->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM `mail_domain` WHERE `dkim` = ? ORDER BY `domain` ASC', 'y');
$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
foreach($dkim_domains as $dkim_domain) {
fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector'] . "\n");
if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_postfix_config_dir}/mysql-verify_recipients.cf|", $value)) {
continue;
}
fclose($fpp);
fclose($fps);
unset($dkim_domains);
} else {
exec("postconf -X 'smtpd_milters'");
exec("postconf -X 'non_smtpd_milters'");
exec("postconf -X 'milter_protocol'");
exec("postconf -X 'milter_mail_macros'");
exec("postconf -X 'milter_default_action'");
exec("postconf -e 'receive_override_options = no_address_mappings'");
exec("postconf -e 'content_filter = " . ($configure_lmtp ? "lmtp" : "amavis" ) . ":[127.0.0.1]:10024'");
$new_options[] = $value;
}
exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
// fixme: should read this from conf templates
exec("postconf -e 'smtpd_sender_restrictions = ${raslm} check_sender_access regexp:/etc/postfix/tag_as_originating.re, permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:/etc/postfix/tag_as_foreign.re'");
// get all domains that have dkim enabled
if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
}
$dkim_domains = $app->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM `mail_domain` WHERE `dkim` = ? ORDER BY `domain` ASC', 'y');
$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
foreach($dkim_domains as $dkim_domain) {
fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector'] . "\n");
}
fclose($fpp);
fclose($fps);
unset($dkim_domains);
} else {
exec("postconf -X 'smtpd_milters'");
exec("postconf -X 'non_smtpd_milters'");
exec("postconf -X 'milter_protocol'");
exec("postconf -X 'milter_mail_macros'");
exec("postconf -X 'milter_default_action'");
exec("postconf -e 'receive_override_options = no_address_mappings'");
exec("postconf -e 'content_filter = " . ($configure_lmtp ? "lmtp" : "amavis" ) . ":[127.0.0.1]:10024'");
// fixme: should read this from conf templates
exec("postconf -e 'smtpd_sender_restrictions = ${raslm} check_sender_access regexp:/etc/postfix/tag_as_originating.re, permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:/etc/postfix/tag_as_foreign.re'");
}
if($mail_config['content_filter'] == 'rspamd' && ($mail_config['rspamd_password'] != $old_ini_data['mail']['rspamd_password'] || $mail_config['content_filter'] != $old_ini_data['mail']['content_filter'])) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment