feat(maddy): add mail stack
This commit is contained in:
@@ -49,8 +49,7 @@ define PORTS_DHCP = { 67, 68, 546, 547 }
|
||||
define PORTS_DNS = 53
|
||||
define PORTS_NTP = 123
|
||||
define PORTS_VPN = 11290
|
||||
define PORTS_CROWDSEC = 8080
|
||||
define PORTS_NAS = { 5000, 5001 }
|
||||
define PORTS_CROWDSEC = {{ services['crowdsec']['ports']['https'] }}
|
||||
|
||||
table inet nat {
|
||||
chain prerouting {
|
||||
|
||||
@@ -9,15 +9,19 @@ define HOSTS4_CONSOLE = { {{ hostvars['fw']['network4']['console'].values() | jo
|
||||
define HOSTS6_CONSOLE = { {{ hostvars['fw']['network6']['console'].values() | join(', ') }} }
|
||||
define PORTS_SSH = 22
|
||||
define PORTS_DB = 5432
|
||||
define PORTS_CA = 9000
|
||||
define PORTS_CA = {{ services['ca']['ports']['https'] }}
|
||||
define PORTS_LDAPS = 636
|
||||
define PORTS_LDAPS_FORWARD = 6360
|
||||
define PORTS_LDAPS_FORWARD = {{ services['ldap']['ports']['ldaps'] }}
|
||||
define PORTS_HTTP = 80
|
||||
define PORTS_HTTP_FORWARD = 2080
|
||||
define PORTS_HTTPS = 443
|
||||
define PORTS_HTTPS_FORWARD = 2443
|
||||
define PORTS_PROMETHEUS = 9090
|
||||
define PORTS_LOKI = 3100
|
||||
define PORTS_PROMETHEUS = {{ services['prometheus']['ports']['https'] }}
|
||||
define PORTS_LOKI = {{ services['loki']['ports']['https'] }}
|
||||
define PORTS_SMTP = 587
|
||||
define PORTS_SMTP_FORWARD = {{ services['maddy']['ports']['smtp'] }}
|
||||
define PORTS_IMAPS = 993
|
||||
define PORTS_IMAPS_FORWARD = {{ services['maddy']['ports']['imaps'] }}
|
||||
|
||||
table inet nat {
|
||||
chain prerouting {
|
||||
@@ -25,6 +29,8 @@ table inet nat {
|
||||
tcp dport $PORTS_HTTP dnat to :$PORTS_HTTP_FORWARD comment "DNAT http ports to $PORTS_HTTP_FORWARD"
|
||||
tcp dport $PORTS_HTTPS dnat to :$PORTS_HTTPS_FORWARD comment "DNAT https ports to $PORTS_HTTPS_FORWARD"
|
||||
tcp dport $PORTS_LDAPS dnat to :$PORTS_LDAPS_FORWARD comment "DNAT ldaps ports to $PORTS_LDAPS_FORWARD"
|
||||
tcp dport $PORTS_SMTP dnat to :$PORTS_SMTP_FORWARD comment "DNAT smtp ports to $PORTS_SMTP_FORWARD"
|
||||
tcp dport $PORTS_IMAPS dnat to :$PORTS_IMAPS_FORWARD comment "DNAT imaps ports to $PORTS_IMAPS_FORWARD"
|
||||
}
|
||||
chain postrouting {
|
||||
|
||||
@@ -34,6 +40,8 @@ table inet nat {
|
||||
oifname "lo" tcp dport $PORTS_HTTP dnat to :$PORTS_HTTP_FORWARD comment "DNAT http ports to $PORTS_HTTP_FORWARD out of LOCALHOST"
|
||||
oifname "lo" tcp dport $PORTS_HTTPS dnat to :$PORTS_HTTPS_FORWARD comment "DNAT https ports to $PORTS_HTTPS_FORWARD out of LOCALHOST"
|
||||
oifname "lo" tcp dport $PORTS_LDAPS dnat to :$PORTS_LDAPS_FORWARD comment "DNAT ldaps ports to $PORTS_LDAPS_FORWARD out of LOCALHOST"
|
||||
oifname "lo" tcp dport $PORTS_SMTP dnat to :$PORTS_SMTP_FORWARD comment "DNAT smtp ports to $PORTS_SMTP_FORWARD"
|
||||
oifname "lo" tcp dport $PORTS_IMAPS dnat to :$PORTS_IMAPS_FORWARD comment "DNAT imaps ports to $PORTS_IMAPS_FORWARD"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +68,10 @@ table inet filter {
|
||||
ip6 saddr $NET6_SERVER tcp dport $PORTS_PROMETHEUS accept comment "allow ipv6 prometheus connection: SERVER > INFRA"
|
||||
ip saddr $NET4_SERVER tcp dport $PORTS_LOKI accept comment "allow ipv4 loki connection: SERVER > INFRA"
|
||||
ip6 saddr $NET6_SERVER tcp dport $PORTS_LOKI accept comment "allow ipv6 loki connection: SERVER > INFRA"
|
||||
ip saddr $NET4_SERVER tcp dport $PORTS_SMTP_FORWARD ct original proto-dst $PORTS_SMTP accept comment "allow ipv4 smtp connection: SERVER > INFRA"
|
||||
ip6 saddr $NET6_SERVER tcp dport $PORTS_SMTP_FORWARD ct original proto-dst $PORTS_SMTP accept comment "allow ipv6 smtp connection: SERVER > INFRA"
|
||||
ip saddr $NET4_SERVER tcp dport $PORTS_IMAPS_FORWARD ct original proto-dst $PORTS_IMAPS accept comment "allow ipv4 imaps connection: SERVER > INFRA"
|
||||
ip6 saddr $NET6_SERVER tcp dport $PORTS_IMAPS_FORWARD ct original proto-dst $PORTS_IMAPS accept comment "allow ipv6 imaps connection: SERVER > INFRA"
|
||||
}
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy drop;
|
||||
|
||||
@@ -126,6 +126,7 @@ postgresql:
|
||||
postgres: ENC[AES256_GCM,data:XlpsKT0/3VgNesMdifvHlYZ2dh7mlMEnxi0MJpQZiQ+1tZ0/3zMxQ7+vwec=,iv:akcPRmDZQfFLxelG7V87UnNB8ez28PPLCmY1MYfzStU=,tag:14jvIKP7Htfh+/oMwLYC2Q==,type:str]
|
||||
alloy: ENC[AES256_GCM,data:ifgJH2e7MTAJ/+ppdWHEmLC3DAsKHWNi8j4w1ZVjUh4tN1cDLDJR3EvJTl0=,iv:rDYUkVe6idIf5Si5E9V+mvBaIdYQTJJCB2rOV0Suvr0=,tag:xDCL25NwuTp6H1DOGTIm4w==,type:str]
|
||||
ldap: ENC[AES256_GCM,data:mJrxIhXynHxJhncw3upHpOkXIw+Ka9bmDBJwkDjYl+D9Pg4RDvL6WzBjthw=,iv:y8MUYo6VhgTzbWh/+n7/hf1Jw+L2KcdxKvulPJ67xn8=,tag:4ZFpj1UdOwXmaZjYvC/s3A==,type:str]
|
||||
maddy: ENC[AES256_GCM,data:D8cFa65up8DVGBiIAXvh/2BdYoeZ9X4wPZmCU6aQ6p37+4edBhsl6VWYhH4=,iv:AORId0QsAkeIQH2IMcI+HKFKW7NLrZ0GXi0yCn2NK5Y=,tag:RtI/Vn8WydkjIiNZB9om/w==,type:str]
|
||||
grafana: ENC[AES256_GCM,data:P9okJ7bcsqmeGstkSwbDq/RgnG+lFrgAOvcj8A5lOTpmHaSlXGiKG+ybXa0=,iv:Di1ghnxIbAb/u7uo/mJCC3QYVjdweTHaQDZmXTx8OG4=,tag:DT3a1zgU9sTr0BXpyoZ/SQ==,type:str]
|
||||
authelia: ENC[AES256_GCM,data:OqyloAADO6KKEaBjGLsJc9GTe77wn6IvA1VCD2dfCWxx+zgzUYh87fK1XX8=,iv:QIOHNTdNnzcY/f3Co8dPdNHykhBnYRhm43nt35hbALM=,tag:DLQq58GrZd+Ul7MSn6s9uQ==,type:str]
|
||||
vaultwarden: ENC[AES256_GCM,data:BPj5eFo54DTZ82n3yTIqEbm7kb/jWT0n2kZY//oV5q48eRch3C2RBuxn/Ko=,iv:DGC4ipHMyVs25gc4sNMt8LN1RsHjiR/b303vgiFoxMY=,tag:k1eb4DoRPLKvvMstSI1faQ==,type:str]
|
||||
@@ -156,6 +157,7 @@ ldap:
|
||||
admin: ENC[AES256_GCM,data:xMBoPycO/5wDae2AMZlgomoXjB98BpCOQkxek3W7t7Wk+az1GMqJhdB0osY=,iv:E6nNmNNKlJoNC7KwE0PaDIB8QyGM0MuNutQty3bi1Pc=,tag:yc8nlegBUOX2hfaMBoNaCw==,type:str]
|
||||
authelia: ENC[AES256_GCM,data:1hHNPWgiRte/TJr4gBuwFt3zMHPivgRp7Z2kurYG+bT96HWmwk1+4iKSQVM=,iv:cpV2P14daWabaDuQ9KgrGs8bN+4pc7sXbAUE2mjWQL0=,tag:lsLgHkkhgSPfwxC6vu5JEg==,type:str]
|
||||
grafana: ENC[AES256_GCM,data:42rnv/NMwmvHdyWW6PZj1Lto5mRDTHp6h55OuRYd9xMOtmenX5zBJzGMvnE=,iv:jUKuPisxa/S9erKjXHl3y0zJR+Tfe36O85/BdGmN+gE=,tag:h1InzKaa+bWjlmIq9OZRpw==,type:str]
|
||||
maddy: ENC[AES256_GCM,data:+E8ggJax1s7Nwdc8EpAWHnVuM0ceJqpW++z4UGeTpPN0DYDPqNSBi/7rW6s=,iv:n+iMKOBjuyeVNRLZQTr+3/Fuu3KEYolLjCXLZ9lTBvk=,tag:B5NZO7zKxh+7nN29vvE1Jw==,type:str]
|
||||
users:
|
||||
il: ENC[AES256_GCM,data:GcOsUe7yJFLdhPp2H7i2,iv:T4NGNvYe5beYbxr+ezfT86aS5lCBa/TG3bUWuUrCZ+A=,tag:rrdHtLyZI7pdTGq5qmptYw==,type:str]
|
||||
morsalin: ENC[AES256_GCM,data:86+imwqNJ5Xg,iv:Lgt1I12gtDsjvE1yMjiyed0sZEeExQZoJPD+xKzHBqk=,tag:YiQgczFZnzh7p1t+KIzM6Q==,type:str]
|
||||
@@ -163,9 +165,9 @@ ldap:
|
||||
#
|
||||
#
|
||||
#ENC[AES256_GCM,data:6RVyF1gPUfKEvkV3RQ==,iv:0MTKlm5kE0kZi3E013Kk/Wo642BizBRmcHXR+Zwf/W8=,tag:SaQJ7lvFUuALxXWf41C24A==,type:comment]
|
||||
mail:
|
||||
key: ENC[AES256_GCM,data:2iT93HHmX3eCTtKb8/C5mI2uEwdck7R6TCXoLuWprfs6KMza8mwd+qDeYGauUHUojEplmopycWup1cVWyQRN2B3udxd7nR9YXcdL0ZNvjmEcjRKDicHEhIw3DVb7N5GuGkFDhc4dEx4gen5Lwu3c+b2hpL58fvZNmrldKV1Qs2jnyi4LcFxEaldPNAiJJA5CYC3M/FFrEDw+Zh1VP6rliz0wYvEoqsIanKgDs5sVkSw7IT9iBidg8EagPrlSEcYJOSHlNVJU2a28P45az0G1drw4BWiXASmCWk6CNr2WT26vz24=,iv:8h45V8wA83AHrej7ajzV3z3KUS2eu0fegjPJk7l8YoQ=,tag:kD+QVBEur6xSI0iLEthWeg==,type:str]
|
||||
crt: ENC[AES256_GCM,data:v1nr+IQowiph7eRyENALTAXHt7NPoEdbyBcb3lVxUp9Ga6nGs7IPSyzMTfc3Am4cZ/6kRpXJG30cjINWpfhFkruS6SCPqMUcsxkVw6oLArbN62wV4umws6xh0pQNajTGY8ZNhya4RudWSLAtmIlbI0aneJKxrypPQKXeX+nML48TLcV8PicAhr4gyEk967IaHLCPK3GAuDwrD/b5NsaU3sVb5bHwcSsUKUBzdAYdHTDwsuOVwbrYT0egQ+Bcn44bY/EWw8SbIa90A+iqU6R4G9V2+/eHCSdqaNX27Yp+h3YgRJH+NqItiMlgeJ99bjvYjdSaOucmUE9gcUt7BFHpEuCI6nBGduFu/PEsFd1vNB/jKjLidN/wjcHHXXfmLy1vw8ut8ns9cl3Ufyk2VcwTfexKTuZbcAIlDdc2HGB03Z8bju8Ci96+j6cZEgv04eUZSl/5erRuyrIrA/erC09J3gqz3ojMTPsGxmQs8Rbkv6ZWM2mrsBizZq3K3XMCAP/eC1072pnOjgE91PzDUmQwBSm2xxyvjDDjJxp0M5EVdTQ/GiJXtV/Fwq8NvhI1P3nkQoDOEz+i3I1ZNrsRPLoaC+HKd+DdnO24slTUXXYO2/j9/Y3z+gjj25WR3Q1iFzKXcVH5pPVToDavMKLhlchcXI0FvqjKPYyqAY1uNEg1oVlqcyD/CcOUur1ugNQGriXPf+//nb3WZgxfcZiCwyee4oCAa3OxSMIaENn3QQ6QVGNocNanvulcA9LwIMU8qXp0+AixtFvbTlM/LHBWy10YDH2LKg7kZ9ePd6JnSFYIdB8gKhnbolrtLVIpC9NDcyzYosFrZ1NsvGgEiy+5+tLl+XERaZunulZ3VBG+4w583/PfeIZ4l7kRde1HWkym5oI0IluQG9MagyIv2a2fSScZEIClDPkOJqFaL6WszVViAgB3pAL3dEr8+48=,iv:bByFvLj8L+yZ2ErlkDBHGRhnNVQsFOe7q3WwyGVWQOU=,tag:VK8iwa8m0thEBNyTvEZOZw==,type:str]
|
||||
maddy:
|
||||
key: ENC[AES256_GCM,data:NN1w/AQAOac7898/tk2W8qDe0TA1W4rwe2USinUW3CxvQO3Gy2oGgcHT7xKDOxnqz/Ec3rBBFZ3v1rAH7236L6GNQ700pFRuddn0qdMukLHJGbY3mWGRWVQYwV1JX3WVdM2HMrrmLKXe1ArsiTfRVjSvVj0kVNjnMwCSFl/zNe2PgwIMSLi+L5KeJ+G5OOywmR3ctQPJQQefeu+eXXkDFPRwENQlD8i5H1K9vSwRVy09DKzFtc74Xi3srVozWE6U+bCTE/rRdxWN+N0wJNl8tUO9Ndbw98rRaD6WdARRXta6nfU=,iv:MpSJnnrragy8hCOwytSuTfJ3i8+8DnSEYUemDK6rBCM=,tag:pjWVUZSUhVsx2nCMzNpXSQ==,type:str]
|
||||
crt: ENC[AES256_GCM,data:O912cPVNMp7H/pEtrzaqv3QckgoAdf3E36E0G4yvVVUwfhfnxTwlLkQ3uk2FGA6VpCuwOvSBYiSnngL0/55hfulVTWmW32oT5pkW9c8UhyA+769o4YrDiX7yG/4YbFyO4JK44f/J/z1zZc7E6Oni5z9GOTQuo4SjRqM3iT+pDqnTRnB26HVSSAZBgGJpL/6lFM/WKheDGrzh/SVJmgr+/uHEWJTuo/L+CsxZ1Qn3WDj4/s7HtCu8I5qvEUPwII86wo6FNXmhTapjIyNDsbgvr/QgNGEvSvVQtSaMyoKWEOKPRIOhdvcZ36qSegqVLO6pvBtvrZabMsNDnTyraAUo7ePs4t+5NM9xAfwJ8vrkqkqYMS22prdHBy5mYebczFQdxGhr+kDi0itAVWZULIXnc/7fptrwoB7jJjO3i9bHSfrXx3DdpU8ivIi/snwKDsA24g1tqK5/y4dgCNakzp1GhZVrPT3WKnqCUPapn7vjEjucClg3m+5poNmdUZs1SgGRhqpeBz1inUzhsBPrk+qIPXXY5eSZ37DH8hQG0NnxsgFiPpLAn/5yfHUI3eVoS6i2kNbK4KkpD2sJ/amRX7Pxder5+tIIu8GzmN8EgfgucV8/DlrX+Z0u6HvA9lOxDxMR+/Bast5e9jc7dCKY25x8oun3OAiG0kAAsJYVcB0/wvskYJoBoKOICRjF8kf0w27kxMgCuFh4LLaqeBbtBXh7lKXjD3gEcTZgPWnxeb63RCWZqoTBGeyUcBkGByAIclhbOHClDG/X397pM0Rn+QbaR04LSGgRPF5NCKqbwmvh8z24b0n6mvyrBpBqhCxdlBz1f5RqlIaCGuy/oR0E2vEfeMiz5LAFZydALZM1v7GkoiRPPasYgMhoHfeSPfCgCyFugtGfU0SqtyksJQxYQUzKAuchALHAi/PCQ7YtXq/1K6C7aK4/Z8+Fy+0=,iv:+MJeh6rwG6PtAp5o5v2wtlhd1wrXkPCdHmEed70F0eQ=,tag:xH9CxCF8mC7PCV0xeE9UCA==,type:str]
|
||||
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||
#
|
||||
#
|
||||
@@ -343,7 +345,7 @@ sops:
|
||||
k+uyWPPi+enFkVaceSwMFrA66uaWWrwAj11sXEB7yzvGFPrnAGezjQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age120wuwcmsm845ztsvsz46pswj5je53uc2n35vadklrfqudu6cxuusxetk7y
|
||||
lastmodified: "2026-06-25T00:07:39Z"
|
||||
mac: ENC[AES256_GCM,data:XNOyATqwo6BygVz6nzBZx6Jn8YONifcvwRKFxWsVxy+aqRRCbUA4eY3g9s6EstpZwHLpf1KeH6iS1ogzwlZfw1Xp8xaWjXgZTEV9R6jEKRzZ4pwPnmC6UVTfrJ2XBB/mjTel0jSR6gbKSgXMJw4rsEyvth+tPxMAaHvrIEcFGqE=,iv:2W2ohbVz4zFDFHG6T5loayab6nOsZaJ/OwqTfNNhEYs=,tag:TNoVHAW5g4/pAOdqolmD7Q==,type:str]
|
||||
lastmodified: "2026-06-25T05:44:30Z"
|
||||
mac: ENC[AES256_GCM,data:eVRWoJ48BjmflUJoXy3hJpf48H4+7zum47xBHZi674UFH4wSWa/01ctq94fXLNeGpovbaPnh2997c33lm26JVXNfSUPzkjALzf5e7pzMLoxnMbpHrAqyctfcx8PxLXWW1DBNOym0Bi0CM8F4BDsuroQPDDtVGzZk2mouzl0iJqo=,iv:ZRqcYFRxae2cnhwAEbHlq66ydV7PbvSdDlu+Nl2dYlw=,tag:bIAhfpzaJhO+STMC34Qxnw==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.13.1
|
||||
|
||||
@@ -15,7 +15,7 @@ root_ca_cert = "/etc/ssl/grafana/{{ root_cert_filename }}"
|
||||
# client_key = "/path/to/client.key"
|
||||
|
||||
bind_dn = "uid=grafana,ou=people,{{ domain['dc'] }}"
|
||||
bind_password = "$__file{/run/secrets/LDAP_BIND_PASSWORD}"
|
||||
bind_password = "$__file{/run/secrets/GF_LDAP_BIND_PASSWORD}"
|
||||
|
||||
search_filter = "(&(|(uid=%s)(mail=%s))(|(memberOf=cn=admins,ou=groups,{{ domain['dc'] }})(memberOf=cn=users,ou=groups,{{ domain['dc'] }})))"
|
||||
search_base_dns = ["{{ domain['dc'] }}"]
|
||||
|
||||
@@ -31,7 +31,7 @@ Environment="GF_PATHS_CONFIG=/etc/grafana/grafana.ini"
|
||||
Environment="GF_FEATURE_TOGGLES_EXPAND_ENV_VARS=true"
|
||||
|
||||
Secret=GF_DB_PASSWORD,target=/run/secrets/GF_DB_PASSWORD
|
||||
Secret=LDAP_BIND_PASSWORD,target=/run/secrets/LDAP_BIND_PASSWORD
|
||||
Secret=GF_LDAP_BIND_PASSWORD,target=/run/secrets/GF_LDAP_BIND_PASSWORD
|
||||
Secret=GF_ADMIN_PASSWORD,target=/run/secrets/GF_ADMIN_PASSWORD
|
||||
|
||||
[Service]
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
# Base
|
||||
|
||||
$(hostname) = {{ services['maddy']['domain']['internal'] }}.{{ domain['internal'] }}
|
||||
$(primary_domain) = {{ domain['internal'] }}
|
||||
$(local_domains) = $(primary_domain)
|
||||
state_dir /data
|
||||
runtime_dir /tmp/maddy
|
||||
hostname $(hostname)
|
||||
tls file /etc/ssl/maddy/maddy.crt /etc/ssl/maddy/maddy.key {
|
||||
protocols tls1.2 tls1.3
|
||||
}
|
||||
|
||||
# LDAP
|
||||
auth.ldap smtp_ldap {
|
||||
urls ldaps://{{ services['ldap']['domain']['internal'] }}.{{ domain['internal'] }}
|
||||
bind plain "uid=maddy,ou=people,{{ domain['dc'] }}" "{env:MADDY_LDAP_BIND_PASSWORD}"
|
||||
base_dn "ou=people,{{ domain['dc'] }}"
|
||||
filter "(&(uid={username})(objectClass=person)(|(memberOf=cn=admins,ou=groups,{{ domain['dc'] }})(memberOf=cn=users,ou=groups,{{ domain['dc'] }})(memberOf=cn=services,ou=groups,{{ domain['dc'] }})))"
|
||||
starttls off
|
||||
tls_client {
|
||||
root_ca /etc/ssl/maddy/{{ root_cert_filename }}
|
||||
}
|
||||
}
|
||||
auth.ldap imap_ldap {
|
||||
urls ldaps://{{ services['ldap']['domain']['internal'] }}.{{ domain['internal'] }}
|
||||
bind plain "uid=maddy,ou=people,{{ domain['dc'] }}" "{env:MADDY_LDAP_BIND_PASSWORD}"
|
||||
base_dn "ou=people,{{ domain['dc'] }}"
|
||||
filter "(&(uid={username})(objectClass=person)(|(memberOf=cn=admins,ou=groups,{{ domain['dc'] }})(memberOf=cn=users,ou=groups,{{ domain['dc'] }})))"
|
||||
starttls off
|
||||
tls_client {
|
||||
root_ca /etc/ssl/maddy/{{ root_cert_filename }}
|
||||
}
|
||||
}
|
||||
|
||||
storage.imapsql local_mailboxes {
|
||||
driver postgres
|
||||
dsn "{env:MADDY_POSTGRES_URL}"
|
||||
msg_store fs messages/
|
||||
delivery_map email_localpart
|
||||
delivery_normalize precis_casefold_email
|
||||
}
|
||||
|
||||
table.chain local_rewrites {
|
||||
optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3"
|
||||
|
||||
optional_step static {
|
||||
entry postmaster postmaster@$(primary_domain)
|
||||
}
|
||||
}
|
||||
|
||||
msgpipeline local_routing {
|
||||
destination postmaster $(local_domains) {
|
||||
modify {
|
||||
replace_rcpt &local_rewrites
|
||||
}
|
||||
|
||||
deliver_to &local_mailboxes
|
||||
}
|
||||
|
||||
default_destination {
|
||||
reject 550 5.1.1 "User doesn't exist"
|
||||
}
|
||||
}
|
||||
|
||||
submission tcp://0.0.0.0:587 {
|
||||
hostname $(hostname)
|
||||
|
||||
limits {
|
||||
all rate 20 1s
|
||||
all concurrency 20
|
||||
}
|
||||
|
||||
auth &smtp_ldap
|
||||
insecure_auth no
|
||||
sasl_login yes
|
||||
max_message_size 32M
|
||||
|
||||
source $(local_domains) {
|
||||
check {
|
||||
authorize_sender {
|
||||
prepare_email &local_rewrites
|
||||
|
||||
auth_normalize precis_casefold
|
||||
from_normalize precis_casefold_email
|
||||
user_to_email regexp "(.*)" "$1@$(primary_domain)"
|
||||
|
||||
check_header yes
|
||||
}
|
||||
}
|
||||
|
||||
destination postmaster $(local_domains) {
|
||||
deliver_to &local_routing
|
||||
}
|
||||
|
||||
default_destination {
|
||||
reject 550 5.7.1 "External delivery is disabled"
|
||||
}
|
||||
}
|
||||
|
||||
default_source {
|
||||
reject 550 5.7.1 "Non-local sender domain"
|
||||
}
|
||||
}
|
||||
|
||||
imap tls://0.0.0.0:993 {
|
||||
auth &imap_ldap
|
||||
storage &local_mailboxes
|
||||
|
||||
insecure_auth no
|
||||
sasl_login yes
|
||||
|
||||
storage_map identity
|
||||
storage_map_normalize precis_casefold
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=Maddy
|
||||
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=docker.io/foxcpp/maddy:{{ version['containers']['maddy'] }}
|
||||
|
||||
ContainerName=maddy
|
||||
HostName=maddy
|
||||
|
||||
PublishPort={{ services['maddy']['ports']['smtp'] }}:587/tcp
|
||||
PublishPort={{ services['maddy']['ports']['imaps'] }}:993/tcp
|
||||
|
||||
AddHost={{ services['postgresql']['domain']['internal'] }}.{{ domain['internal'] }}:host-gateway
|
||||
AddHost={{ services['ldap']['domain']['internal'] }}.{{ domain['internal'] }}:host-gateway
|
||||
|
||||
Volume=%h/containers/maddy/maddy.conf:/data/maddy.conf:ro
|
||||
Volume=%h/containers/maddy/ssl:/etc/ssl/maddy:ro
|
||||
Volume=%h/data/containers/maddy/data:/data:rw
|
||||
|
||||
Environment="TZ={{ timezone }}"
|
||||
Secret=MADDY_LDAP_BIND_PASSWORD,type=env
|
||||
Secret=MADDY_POSTGRES_URL,type=env
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -1,6 +1,6 @@
|
||||
$TTL 86400
|
||||
|
||||
@ IN SOA bind.ilnmors.internal. mail.ilnmors.internal. (
|
||||
@ IN SOA bind.ilnmors.internal. bind.ilnmors.internal. (
|
||||
2026021201 ; serial
|
||||
3600 ; refresh (1 hour)
|
||||
1800 ; retry (30 minutes)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$TTL 86400
|
||||
|
||||
@ IN SOA bind.ilnmors.internal. mail.ilnmors.internal. (
|
||||
@ IN SOA bind.ilnmors.internal. bind.ilnmors.internal. (
|
||||
2026021201 ; serial
|
||||
3600 ; refresh (1 hour)
|
||||
1800 ; retry (30 minutes)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$TTL 86400
|
||||
|
||||
@ IN SOA bind.ilnmors.internal. mail.ilnmors.internal. (
|
||||
@ IN SOA bind.ilnmors.internal. bind.ilnmors.internal. (
|
||||
2026021201 ; serial
|
||||
3600 ; refresh (1 hour)
|
||||
1800 ; retry (30 minutes)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$TTL 86400
|
||||
|
||||
@ IN SOA bind.ilnmors.internal. mail.ilnmors.internal. (
|
||||
@ IN SOA bind.ilnmors.internal. bind.ilnmors.internal. (
|
||||
2026021201 ; serial
|
||||
3600 ; refresh (1 hour)
|
||||
1800 ; retry (30 minutes)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$TTL 86400
|
||||
|
||||
@ IN SOA bind.ilnmors.internal. mail.ilnmors.internal. (
|
||||
@ IN SOA bind.ilnmors.internal. bind.ilnmors.internal. (
|
||||
2026021201 ; serial
|
||||
3600 ; refresh (1 hour)
|
||||
1800 ; retry (30 minutes)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$TTL 86400
|
||||
|
||||
@ IN SOA bind.ilnmors.internal. mail.ilnmors.internal. (
|
||||
@ IN SOA bind.ilnmors.internal. bind.ilnmors.internal. (
|
||||
2026021201 ; serial
|
||||
3600 ; refresh (1 hour)
|
||||
1800 ; retry (30 minutes)
|
||||
@@ -35,6 +35,7 @@ kopia IN CNAME bk.ilnmors.internal.
|
||||
ca IN CNAME infra.ilnmors.internal.
|
||||
postgresql IN CNAME infra.ilnmors.internal.
|
||||
ldap IN CNAME infra.ilnmors.internal.
|
||||
maddy IN CNAME infra.ilnmors.internal.
|
||||
prometheus IN CNAME infra.ilnmors.internal.
|
||||
loki IN CNAME infra.ilnmors.internal.
|
||||
grafana IN CNAME infra.ilnmors.internal.
|
||||
|
||||
Reference in New Issue
Block a user