Add mail roles
This commit is contained in:
35
package-postfix_filter/defaults/main.yml
Normal file
35
package-postfix_filter/defaults/main.yml
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
# Default configurations
|
||||
# I populate these from external configs; I indicate what the are as inline comments
|
||||
|
||||
# Postfix
|
||||
|
||||
# A list of relay domains and their target (square-bracked hostname/IP + port); examples follow
|
||||
relay_domains: "{{ blse_relaydomains }}"
|
||||
# - domain: "some.domain.tld"
|
||||
# relay: "[mail.domain.tld]"
|
||||
# - domain: "other.domain.tld"
|
||||
# relay: "[secure.domain.tld]:465"
|
||||
|
||||
# A list of RBLs to check for rejecting incoming mail
|
||||
remote_block_lists:
|
||||
- bl.spamcop.net
|
||||
- zen.spamhaus.org
|
||||
- cbl.abuseat.org
|
||||
|
||||
# Enable TLS (literal yes/no only) and, if yes, the cert and key files
|
||||
tls_enabled: yes
|
||||
tls_cert: "/etc/ssl/{{ ansible_fqdn }}.crt"
|
||||
tls_key: "/etc/ssl/{{ ansible_fqdn }}.key"
|
||||
|
||||
# Virtual address maps
|
||||
virtual_maps:
|
||||
- regex: "/^postmaster@/"
|
||||
map: "root@{{ blsedomains_admindomain }}"
|
||||
|
||||
# SpamAssassin
|
||||
notify_admin: "joshua@boniface.me" # Administrative address to notify
|
||||
notify_method: "smtp:{{ blsecluster_smtphost }}:25"
|
||||
custom_sender_scores:
|
||||
- [qr'^(offers)@'i => 1.0]
|
||||
- [qr'^.*@pizzanova.com'i => 1.0]
|
2
package-postfix_filter/files/ham-sample/README
Normal file
2
package-postfix_filter/files/ham-sample/README
Normal file
@ -0,0 +1,2 @@
|
||||
Populate me with spam-tagged legit emails.
|
||||
Then `tar -cvJf ham-sample.txz ham-sample/` in the parent directory.
|
2
package-postfix_filter/files/spam-sample/README
Normal file
2
package-postfix_filter/files/spam-sample/README
Normal file
@ -0,0 +1,2 @@
|
||||
Populate me with spam-tagged legit emails.
|
||||
Then `tar -cvJf ham-sample.txz ham-sample/` in the parent directory.
|
19
package-postfix_filter/handlers/main.yml
Normal file
19
package-postfix_filter/handlers/main.yml
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
- name: postmap transport
|
||||
command: "postmap /etc/postfix/transport"
|
||||
- name: restart amavis
|
||||
service:
|
||||
name: "amavis"
|
||||
state: "restarted"
|
||||
- name: restart saslauthd
|
||||
service:
|
||||
name: "saslauthd"
|
||||
state: "restarted"
|
||||
- name: restart postfix
|
||||
service:
|
||||
name: "postfix"
|
||||
state: "restarted"
|
||||
- name: restart spamassassin
|
||||
service:
|
||||
name: "spamassassin"
|
||||
state: "restarted"
|
220
package-postfix_filter/tasks/main.yml
Normal file
220
package-postfix_filter/tasks/main.yml
Normal file
@ -0,0 +1,220 @@
|
||||
---
|
||||
#
|
||||
# Install role packages
|
||||
#
|
||||
|
||||
- name: install filtering packages and monitoring components
|
||||
apt:
|
||||
name:
|
||||
- postfix
|
||||
- postfix-pcre
|
||||
- mailgraph
|
||||
- amavis
|
||||
- spamassassin
|
||||
- clamav-daemon
|
||||
- libnet-dns-perl
|
||||
- libmail-spf-perl
|
||||
- postfix-policyd-spf-python
|
||||
- pfqueue
|
||||
state: latest
|
||||
|
||||
- name: install compression algorithms for scanning
|
||||
apt:
|
||||
name:
|
||||
- p7zip-full
|
||||
- arj
|
||||
- bzip2
|
||||
- cabextract
|
||||
- cpio
|
||||
- file
|
||||
- gzip
|
||||
- lhasa
|
||||
- liblz4-tool
|
||||
- lrzip
|
||||
- lzop
|
||||
- nomarch
|
||||
- pax
|
||||
- rar
|
||||
- rpm
|
||||
- unrar-free
|
||||
- unzip
|
||||
- xz-utils
|
||||
- zip
|
||||
state: latest
|
||||
|
||||
#
|
||||
# ClamAV
|
||||
#
|
||||
|
||||
- name: ensure clamav is in amavis group
|
||||
user:
|
||||
name: "clamav"
|
||||
append: "yes"
|
||||
groups: "amavis"
|
||||
|
||||
- name: ensure amavis is in clamav group
|
||||
user:
|
||||
name: "amavis"
|
||||
append: "yes"
|
||||
groups: "clamav"
|
||||
|
||||
#
|
||||
# policyd SPF
|
||||
#
|
||||
|
||||
- name: install policyd-spf config
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/postfix-policyd-spf-python/{{ item }}"
|
||||
notify:
|
||||
- restart postfix
|
||||
with_items:
|
||||
- "policyd-spf.conf"
|
||||
|
||||
#
|
||||
# SpamAssassin
|
||||
#
|
||||
|
||||
- name: install SpamAssassin config
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/spamassassin/{{ item }}"
|
||||
notify:
|
||||
- restart spamassassin
|
||||
- restart amavis
|
||||
with_items:
|
||||
- "local.cf"
|
||||
- "90_customrules.cf"
|
||||
|
||||
#
|
||||
# Amavis
|
||||
#
|
||||
|
||||
- name: install Amavis configs
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/amavis/conf.d/{{ item }}"
|
||||
notify:
|
||||
- restart amavis
|
||||
with_items:
|
||||
- "15-content_filter_mode"
|
||||
- "50-user"
|
||||
|
||||
#
|
||||
# Postfix
|
||||
#
|
||||
|
||||
- name: create the Postfix local config dir
|
||||
file:
|
||||
state: directory
|
||||
dest: "/etc/postfix/local"
|
||||
|
||||
- name: install the Postfix main configs
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/postfix/{{ item }}"
|
||||
notify:
|
||||
- restart postfix
|
||||
with_items:
|
||||
- "main.cf"
|
||||
- "master.cf"
|
||||
|
||||
- name: install the Postfix local configs
|
||||
template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "/etc/postfix/local/{{ item }}"
|
||||
notify:
|
||||
- restart postfix
|
||||
with_items:
|
||||
- helo_access
|
||||
- recipient_access
|
||||
- relay_domains
|
||||
- transport
|
||||
- virtual
|
||||
|
||||
- name: link /etc/mailname to /etc/hostname
|
||||
file:
|
||||
dest: "/etc/mailname"
|
||||
src: "/etc/hostname"
|
||||
state: "link"
|
||||
force: "yes"
|
||||
|
||||
#
|
||||
# Verify and enable services
|
||||
#
|
||||
|
||||
- name: verify and enable services
|
||||
service:
|
||||
name: "{{ item }}"
|
||||
state: "started"
|
||||
enabled: "yes"
|
||||
with_items:
|
||||
- "postfix"
|
||||
- "amavis"
|
||||
- "clamav-daemon"
|
||||
|
||||
#
|
||||
# SpamAssassin training
|
||||
#
|
||||
|
||||
- name: download spam sample archive
|
||||
copy:
|
||||
src: "spam-sample.txz"
|
||||
dest: "/var/cache/spam-sample.txz"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "400"
|
||||
register: spamsample
|
||||
|
||||
- name: make temporary directory
|
||||
command: "mktemp -d"
|
||||
register: tempdirspam
|
||||
when: spamsample.changed
|
||||
|
||||
- name: extract spam sample archive to temporary directory
|
||||
unarchive:
|
||||
remote_src: "yes"
|
||||
src: "/var/cache/spam-sample.txz"
|
||||
dest: "{{ tempdirspam.stdout }}/"
|
||||
when: spamsample.changed
|
||||
|
||||
- name: sa-learn from the spam sample
|
||||
command: "sa-learn --spam {{ tempdirspam.stdout }}/spam-sample/"
|
||||
when: spamsample.changed
|
||||
|
||||
- name: remove temporary directory
|
||||
file:
|
||||
dest: "{{ tempdirspam.stdout }}"
|
||||
state: "absent"
|
||||
when: spamsample.changed
|
||||
|
||||
- name: download ham sample archive
|
||||
copy:
|
||||
src: "ham-sample.txz"
|
||||
dest: "/var/cache/ham-sample.txz"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "400"
|
||||
register: hamsample
|
||||
|
||||
- name: make temporary directory
|
||||
command: "mktemp -d"
|
||||
register: tempdirham
|
||||
when: hamsample.changed
|
||||
|
||||
- name: extract ham sample archive to temporary directory
|
||||
unarchive:
|
||||
remote_src: "yes"
|
||||
src: "/var/cache/ham-sample.txz"
|
||||
dest: "{{ tempdirham.stdout }}/"
|
||||
when: hamsample.changed
|
||||
|
||||
- name: sa-learn from the ham sample
|
||||
command: "sa-learn --ham {{ tempdirham.stdout }}/ham-sample/"
|
||||
when: hamsample.changed
|
||||
|
||||
- name: remove temporary directory
|
||||
file:
|
||||
dest: "{{ tempdirham.stdout }}"
|
||||
state: "absent"
|
||||
when: hamsample.changed
|
12
package-postfix_filter/templates/15-content_filter_mode.j2
Normal file
12
package-postfix_filter/templates/15-content_filter_mode.j2
Normal file
@ -0,0 +1,12 @@
|
||||
use strict;
|
||||
|
||||
# Amavis filter configuration
|
||||
# {{ ansible_managed }}
|
||||
|
||||
@bypass_virus_checks_maps = (
|
||||
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
|
||||
|
||||
@bypass_spam_checks_maps = (
|
||||
\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
|
||||
|
||||
1; # ensure a defined return
|
40
package-postfix_filter/templates/50-user.j2
Normal file
40
package-postfix_filter/templates/50-user.j2
Normal file
@ -0,0 +1,40 @@
|
||||
use strict;
|
||||
|
||||
@local_domains_acl = ( "." );
|
||||
$sa_tag_level_deflt = -9999;
|
||||
$sa_tag2_level_deflt = 5;
|
||||
$sa_kill_level_deflt = 9999;
|
||||
$sa_spam_subject_tag = '*** SPAM *** ';
|
||||
$final_spam_destiny = 'D_PASS';
|
||||
|
||||
$bad_header_quarantine_method = undef;
|
||||
|
||||
$notify_method = '{{ notify_method }}';
|
||||
|
||||
$newvirus_admin = '{{ notify_admin }}';
|
||||
$virus_admin = '{{ notify_admin }}';
|
||||
$spam_admin = '{{ notify_admin }}';
|
||||
|
||||
$banned_admin = \@virus_admin_maps; # for compatibility with pre-2.2.1
|
||||
$bad_header_admin = \@virus_admin_maps; # for compatibility with pre-2.2.1
|
||||
@newvirus_admin_maps = (\$newvirus_admin);
|
||||
@virus_admin_maps = (\%virus_admin, \$virus_admin);
|
||||
@spam_admin_maps = (\%spam_admin, \$spam_admin);
|
||||
@banned_admin_maps = (\$banned_admin);
|
||||
@bad_header_admin_maps= (\$bad_header_admin);
|
||||
|
||||
{% if custom_sender_scores is defined %}
|
||||
# Custom sender_map scores
|
||||
@score_sender_maps = ({
|
||||
'.' => [
|
||||
new_RE(
|
||||
{% for score in custom_sender_scores %}
|
||||
{{ score }},
|
||||
{% endfor %}
|
||||
),
|
||||
],
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
#------------ Do not modify anything below this line -------------
|
||||
1; # ensure a defined return
|
7
package-postfix_filter/templates/90_customrules.cf.j2
Normal file
7
package-postfix_filter/templates/90_customrules.cf.j2
Normal file
@ -0,0 +1,7 @@
|
||||
# Adjustments to default SpamAssassin scoring
|
||||
# {{ ansible_managed }}
|
||||
score RCVD_IN_PSBL 3.5 # Increase default score significantly
|
||||
score URIBL_BLACK 3.5 # Increase default score significantly
|
||||
score LOTS_OF_MONEY 2 # Increase default score a little
|
||||
score ADVANCE_FEE_4_NEW 2 # Increase default score a little
|
||||
score RDNS_NONE 0.5 # Decrease default score a little
|
2
package-postfix_filter/templates/helo_access.j2
Normal file
2
package-postfix_filter/templates/helo_access.j2
Normal file
@ -0,0 +1,2 @@
|
||||
/^\[[0-9]{1,3}(\.[0-9]{1,3}){3}\]$/ DUNNO announced self using an address literal
|
||||
/^[0-9]{1,3}(\.[0-9]{1,3}){3}$/ REJECT announced self with an IP address instead of a domain name
|
27
package-postfix_filter/templates/local.cf.j2
Normal file
27
package-postfix_filter/templates/local.cf.j2
Normal file
@ -0,0 +1,27 @@
|
||||
# SpamAssassin local config
|
||||
# {{ ansible_managed }}
|
||||
|
||||
report_safe 1
|
||||
required_score 4.5
|
||||
|
||||
use_bayes 1
|
||||
bayes_auto_learn 1
|
||||
bayes_auto_learn_threshold_nonspam -0.1
|
||||
bayes_auto_learn_threshold_spam 9.0
|
||||
|
||||
score BAYES_00 -4
|
||||
score BAYES_05 -2
|
||||
score BAYES_80 2
|
||||
score BAYES_95 6
|
||||
score BAYES_99 8
|
||||
|
||||
bayes_ignore_header X-Bogosity
|
||||
bayes_ignore_header X-Spam-Flag
|
||||
bayes_ignore_header X-Spam-Status
|
||||
|
||||
bayes_path /var/spamassassin/bayes_db/bayes
|
||||
bayes_file_mode 0777
|
||||
|
||||
skip_rbl_checks 0
|
||||
ok_languages all
|
||||
ok_locales all
|
91
package-postfix_filter/templates/main.cf.j2
Normal file
91
package-postfix_filter/templates/main.cf.j2
Normal file
@ -0,0 +1,91 @@
|
||||
# Main Postfix configuration
|
||||
# {{ ansible_managed }}
|
||||
|
||||
myorigin = /etc/mailname
|
||||
myhostname = {{ ansible_fqdn }}
|
||||
|
||||
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
||||
message_size_limit = 26214400
|
||||
mailbox_size_limit = 0
|
||||
default_process_limit = 1000
|
||||
recipient_delimiter = +
|
||||
inet_interfaces = all
|
||||
|
||||
smtpd_banner = {{ ansible_fqdn }} ESMTP $mail_name (Debian/GNU)
|
||||
biff = no
|
||||
append_dot_mydomain = no
|
||||
delay_warning_time = 48h
|
||||
maximal_queue_lifetime = 14d
|
||||
bounce_queue_lifetime = 14d
|
||||
readme_directory = no
|
||||
compatibility_level = 2
|
||||
|
||||
smtpd_use_tls={{ tls_enabled }}
|
||||
smtpd_tls_dh1024_param_file = /etc/ssl/dhparams.pem
|
||||
smtpd_tls_cert_file={{ tls_cert }}
|
||||
smtpd_tls_key_file={{ tls_key }}
|
||||
smtpd_tls_ask_ccert = yes
|
||||
smtpd_tls_received_header = yes
|
||||
smtpd_tls_loglevel = 1
|
||||
smtpd_tls_session_cache_database = btree:$data_directory/smtpd_scache
|
||||
smtpd_tls_security_level = may
|
||||
smtpd_tls_protocols = !SSLv2,!SSLv3
|
||||
smtpd_tls_ciphers = medium
|
||||
smtpd_tls_exclude_ciphers = RC4, CAMELLIA, SEED, 3DES
|
||||
|
||||
smtp_use_tls={{ tls_enabled }}
|
||||
smtp_tls_cert_file={{ tls_cert }}
|
||||
smtp_tls_key_file={{ tls_key }}
|
||||
smtp_tls_session_cache_database = btree:$data_directory/smtp_scache
|
||||
smtp_tls_loglevel = 1
|
||||
smtp_tls_security_level = may
|
||||
smtp_tls_protocols = $smtpd_tls_protocols
|
||||
smtp_tls_ciphers = $smtpd_tls_ciphers
|
||||
smtp_tls_exclude_ciphers = $smtpd_tls_exclude_ciphers
|
||||
|
||||
mydestination =
|
||||
local_recipient_maps =
|
||||
alias_maps =
|
||||
alias_database =
|
||||
virtual_alias_maps = pcre:$config_directory/local/virtual
|
||||
local_transport = error:local mail delivery is disabled
|
||||
transport_maps = pcre:$config_directory/local/transport
|
||||
relay_domains = $config_directory/local/relay_domains
|
||||
|
||||
content_filter = smtp-amavis:[127.0.0.1]:10024
|
||||
smtpd_client_recipient_rate_limit = 250
|
||||
strict_rfc821_envelopes = yes
|
||||
receive_override_options = no_address_mappings
|
||||
policyd-spf_time_limit = 3600
|
||||
smtpd_relay_restrictions =
|
||||
permit_mynetworks
|
||||
reject_unauth_destination
|
||||
check_policy_service unix:private/policyd-spf
|
||||
{% for rbl in remote_block_lists %}
|
||||
reject_rbl_client {{ rbl }}
|
||||
{% endfor %}
|
||||
warn_if_reject reject_unknown_client
|
||||
|
||||
smtpd_helo_required = yes
|
||||
smtpd_helo_restrictions =
|
||||
check_helo_access pcre:$config_directory/local/helo_access
|
||||
reject_invalid_hostname
|
||||
|
||||
smtpd_sender_restrictions =
|
||||
check_sender_mx_access cidr:$config_directory/local/mx_access
|
||||
reject_unknown_sender_domain
|
||||
reject_non_fqdn_sender
|
||||
check_sender_access pcre:$config_directory/local/sender_access
|
||||
|
||||
smtpd_recipient_restrictions =
|
||||
reject_unknown_recipient_domain
|
||||
reject_non_fqdn_recipient
|
||||
reject_unauth_pipelining
|
||||
reject_unauth_destination
|
||||
check_policy_service unix:private/policyd-spf
|
||||
check_recipient_access pcre:$config_directory/local/recipient_access
|
||||
reject_unverified_recipient
|
||||
|
||||
smtpd_data_restrictions =
|
||||
reject_multi_recipient_bounce
|
||||
reject_unauth_pipelining
|
62
package-postfix_filter/templates/master.cf.j2
Normal file
62
package-postfix_filter/templates/master.cf.j2
Normal file
@ -0,0 +1,62 @@
|
||||
# Postfix master process configuration file
|
||||
# {{ ansible_managed }}
|
||||
|
||||
# ==========================================================================
|
||||
# service type private unpriv chroot wakeup maxproc command + args
|
||||
# (yes) (yes) (yes) (never) (100)
|
||||
# ==========================================================================
|
||||
smtp inet n - y - - smtpd
|
||||
pickup unix n - y 60 1 pickup
|
||||
-o content_filter=
|
||||
-o receive_override_options=no_header_body_checks
|
||||
cleanup unix n - y - 0 cleanup
|
||||
qmgr unix n - n 300 1 qmgr
|
||||
tlsmgr unix - - y 1000? 1 tlsmgr
|
||||
rewrite unix - - y - - trivial-rewrite
|
||||
bounce unix - - y - 0 bounce
|
||||
defer unix - - y - 0 bounce
|
||||
trace unix - - y - 0 bounce
|
||||
verify unix - - y - 1 verify
|
||||
flush unix n - y 1000? 0 flush
|
||||
proxymap unix - - n - - proxymap
|
||||
proxywrite unix - - n - 1 proxymap
|
||||
smtp unix - - y - - smtp
|
||||
relay unix - - y - - smtp
|
||||
showq unix n - y - - showq
|
||||
error unix - - y - - error
|
||||
retry unix - - y - - error
|
||||
discard unix - - y - - discard
|
||||
local unix - n n - - local
|
||||
virtual unix - n n - - virtual
|
||||
lmtp unix - - y - - lmtp
|
||||
anvil unix - - y - 1 anvil
|
||||
scache unix - - y - 1 scache
|
||||
|
||||
policyd-spf unix - n n - 0 spawn
|
||||
user=policyd-spf argv=/usr/bin/policyd-spf
|
||||
|
||||
smtp-amavis unix - - y - 2 smtp
|
||||
-o smtp_data_done_timeout=1200
|
||||
-o smtp_send_xforward_command=yes
|
||||
-o disable_dns_lookups=yes
|
||||
-o max_use=20
|
||||
|
||||
127.0.0.1:10025 inet n - y - - smtpd
|
||||
-o content_filter=
|
||||
-o local_recipient_maps=
|
||||
-o relay_recipient_maps=
|
||||
-o smtpd_restriction_classes=
|
||||
-o smtpd_delay_reject=no
|
||||
-o smtpd_client_restrictions=permit_mynetworks,reject
|
||||
-o smtpd_helo_restrictions=
|
||||
-o smtpd_sender_restrictions=
|
||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||
-o smtpd_data_restrictions=reject_unauth_pipelining
|
||||
-o smtpd_end_of_data_restrictions=
|
||||
-o mynetworks=127.0.0.0/8
|
||||
-o smtpd_error_sleep_time=0
|
||||
-o smtpd_soft_error_limit=1001
|
||||
-o smtpd_hard_error_limit=1000
|
||||
-o smtpd_client_connection_count_limit=0
|
||||
-o smtpd_client_connection_rate_limit=0
|
||||
-o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
|
12
package-postfix_filter/templates/policyd-spf.conf.j2
Normal file
12
package-postfix_filter/templates/policyd-spf.conf.j2
Normal file
@ -0,0 +1,12 @@
|
||||
# policyd SPF config
|
||||
# {{ ansible_managed }}
|
||||
|
||||
debugLevel = 1
|
||||
|
||||
HELO_reject = False
|
||||
Mail_From_reject = False
|
||||
|
||||
PermError_reject = False
|
||||
TempError_Defer = False
|
||||
|
||||
skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0/104,::1
|
4
package-postfix_filter/templates/recipient_access.j2
Normal file
4
package-postfix_filter/templates/recipient_access.j2
Normal file
@ -0,0 +1,4 @@
|
||||
/[%!@].*[%!@]/ REJECT sender-specified routing in recipient address
|
||||
/&.*@/ REJECT invalid user
|
||||
/^(daemon|bin|sys|sync|games|man|lp|news|uucp|proxy|www-data|backup|list|irc|gnats|nobody)@/ REJECT reserved system user
|
||||
/^(ntp|sshd|munin|postfix|clamav|sqlgrey|policyd-spf|bind|statd|freerad|mysql|smokeping|systemd-.+|)@/ REJECT reserved system user
|
3
package-postfix_filter/templates/relay_domains.j2
Normal file
3
package-postfix_filter/templates/relay_domains.j2
Normal file
@ -0,0 +1,3 @@
|
||||
{% for domain in relay_domains %}
|
||||
{{ domain.domain }}
|
||||
{% endfor %}
|
3
package-postfix_filter/templates/transport.j2
Normal file
3
package-postfix_filter/templates/transport.j2
Normal file
@ -0,0 +1,3 @@
|
||||
{% for domain in relay_domains %}
|
||||
/@{{ domain.domain }}$/ relay:{{ domain.relay }}
|
||||
{% endfor %}
|
3
package-postfix_filter/templates/virtual.j2
Normal file
3
package-postfix_filter/templates/virtual.j2
Normal file
@ -0,0 +1,3 @@
|
||||
{% for map in virtual_maps %}
|
||||
{{ map.regex }} {{ map.map }}
|
||||
{% endfor %}
|
Reference in New Issue
Block a user