Commit d2c5c24d authored by Tom Niget's avatar Tom Niget

wip: internet mail-server with webmail

Initial prototype for full mail-server SR with PostgreSQL user backend, and Snappymail webmail
parent ccdc76bb
......@@ -12,6 +12,7 @@ recipe = slapos.recipe.cmmi
url = https://dovecot.org/releases/2.3/dovecot-2.3.20.tar.gz
md5sum = b8add62d0311dcc95ac25b379e8ba043
location = @@LOCATION@@
extra-configure-options =
configure-options =
--enable-maintainer-mode
--prefix=${:location}
......@@ -19,11 +20,18 @@ configure-options =
--with-systemd=no
--with-lua=yes
--with-libcrypto=${openssl:location}
${:extra-configure-options}
extra-ld-flags =
extra-environment =
extra-pkg-config =
extra-c-flags =
environment =
PATH=${pkgconfig:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${lua:location}/lib/pkgconfig
PKG_CONFIG_PATH=${lua:location}/lib/pkgconfig:${:extra-pkg-config}
LUA_LIBS=-L${lua:location}/lib -Wl,-rpath=${lua:location}/lib -llua -lm
LUA_CFLAGS=-I${lua:location}/include
LDFLAGS=-L${openssl:location}/lib -Wl,-rpath=${openssl:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib
LDFLAGS=-L${openssl:location}/lib -Wl,-rpath=${openssl:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib ${:extra-ld-flags}
CFLAGS=${:extra-c-flags}
${:extra-environment}
make-targets = install
post-install = cp -r ${:location}/share/doc/dovecot/example-config/* ${:location}/etc/dovecot/
......@@ -23,8 +23,10 @@ patches =
${:_profile_base_location_}/linux-6.patch#08967a35249243eb06e46b1868e2dae2
configure-command = make
configure-options = makefiles CCARGS=${:configure-options-CCARGS} AUXLIBS=${:configure-options-AUXLIBS}
configure-options-CCARGS = '-DUSE_SASL_AUTH -DUSE_CYRUS_SASL -DUSE_TLS -DHAS_PCRE -DHAS_DB -I${libdb:location}/include -I${pcre:location}/include -I${openssl:location}/include -I${cyrus-sasl:location}/include/sasl -I${libnsl:location}/include'
configure-options-AUXLIBS = '-L${openssl:location}/lib -L${pcre:location}/lib -L${libdb:location}/lib -L${cyrus-sasl:location}/lib -L${libtirpc:location}/lib -L${libnsl:location}/lib -lnsl -lssl -lpcre -ldb -lcrypto -lsasl2 -Wl,-rpath=${openssl:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${libdb:location}/lib -Wl,-rpath=${cyrus-sasl:location}/lib -Wl,-rpath=${libnsl:location}/lib'
configure-options-CCARGS = ${:default-configure-options-CCARGS}
default-configure-options-CCARGS = -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -DUSE_TLS -DHAS_PCRE -DHAS_DB -I${libdb:location}/include -I${pcre:location}/include -I${openssl:location}/include -I${cyrus-sasl:location}/include/sasl -I${libnsl:location}/include
configure-options-AUXLIBS = ${:default-configure-options-AUXLIBS}
default-configure-options-AUXLIBS = -L${openssl:location}/lib -L${pcre:location}/lib -L${libdb:location}/lib -L${cyrus-sasl:location}/lib -L${libtirpc:location}/lib -L${libnsl:location}/lib -lnsl -lssl -lpcre -ldb -lcrypto -lsasl2 -Wl,-rpath=${openssl:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${libdb:location}/lib -Wl,-rpath=${cyrus-sasl:location}/lib -Wl,-rpath=${libnsl:location}/lib
make-targets = non-interactive-package install_root=${:location}
environment =
PATH=${patch:location}/bin:${m4:location}/bin:%(PATH)s
<VirtualHost *:{{ parameter_dict['port'] }}>
ServerAdmin admin@example.com
DocumentRoot {{ parameter_dict['document-root'] }}
SetEnvIf Origin "^http(s)?://(.+\.)?(app\.officejs\.com)$" ORIGIN_DOMAIN=$0
Header always set Access-Control-Allow-Origin "%{ORIGIN_DOMAIN}e" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Credentials "true" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Methods "PROPFIND, PROPPATCH, COPY, MOVE, DELETE, MKCOL, LOCK, UNLOCK, PUT, GETLIB, VERSION-CONTROL, CHECKIN, CHECKOUT, UNCHECKOUT, REPORT, UPDATE, CANCELUPLOAD, HEAD, OPTIONS, GET, POST" env=ORIGIN_DOMAIN
Header always set Access-Control-Allow-Headers "Overwrite, Destination, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Authorization" env=ORIGIN_DOMAIN
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
<Directory {{ parameter_dict['document-root'] }}>
Options +FollowSymlinks
AllowOverride All
Require all granted
SetEnv HOME {{ parameter_dict['document-root'] }}
SetEnv HTTP_HOME {{ parameter_dict['document-root'] }}
Dav off
</Directory>
ErrorLog "{{ parameter_dict['log-dir'] }}/lamp-error.log"
CustomLog "{{ parameter_dict['log-dir'] }}/lamp-access.log" combined
</VirtualHost>
# Apache static configuration
# Automatically generated
# Basic server configuration
PidFile "{{ parameter_dict['pid-file'] }}"
Listen {{ parameter_dict['ip'] }}:{{ parameter_dict['port'] }}
PHPINIDir {{ parameter_dict['php-ini-dir'] }}
ServerAdmin someone@email
DefaultType text/plain
TypesConfig conf/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType application/x-httpd-php .php .phtml .php5 .php4
AddType application/x-httpd-php-source .phps
# Log configuration
ErrorLog "{{ parameter_dict['error-log'] }}"
LogLevel warn
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
CustomLog "{{ parameter_dict['access-log'] }}" common
# SSL Configuration
SSLCertificateFile {{ parameter_dict.get('cert-file') }}
SSLCertificateKeyFile {{ parameter_dict.get('key-file') }}
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLRandomSeed startup /dev/urandom 256
SSLRandomSeed connect builtin
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
SSLEngine On
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch ".+\.phps$">
SetHandler application/x-httpd-php-source
# Deny access to raw php sources by default
# To re-enable it's recommended to enable access to the files
# only in specific virtual host or directory
Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(ar|p|ps|tml)$">
Require all denied
</FilesMatch>
# Directory protection
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
DirectoryIndex index.html index.php
Include {{ parameter_dict['apache-config-dir'] }}/*.conf
# List of modules
LoadModule unixd_module modules/mod_unixd.so
LoadModule dir_module modules/mod_dir.so
LoadModule env_module modules/mod_env.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule filter_module modules/mod_filter.so
LoadModule php_module modules/libphp.so
......@@ -15,28 +15,48 @@
[template]
filename = instance.cfg.in
md5sum = 403a4a362b2ffec05f8d0b591bab92fa
md5sum = bccd8d99888c3d4997443cae911eca79
[template-default]
_update_hash_filename_ = instance-default.cfg.in
md5sum = 73c1fe98a12465369450cb8f3340881b
md5sum = 3934440228f4ce4495f3f2736db0e71d
[dovecot.jinja2.conf]
_update_hash_filename_ = dovecot.jinja2.conf
md5sum = a1f695cb881e9be680b7b8a597a4b0c9
[dovecot-passdb.jinja2.lua]
_update_hash_filename_ = dovecot-passdb.jinja2.lua
md5sum = 060107ee6ad0eb9092529bc2bd1ee52f
md5sum = 8ac35891bcb9d5d8d7cbb78034d45eb8
[dovecot-sql.jinja2.conf.ext]
md5sum = ab15900d44b38fdad528c6a73936fd26
[postfix_main.jinja2.cf]
_update_hash_filename_ = postfix_main.jinja2.cf
md5sum = e3b2b86282816ac4020154de70cd5074
md5sum = 29e7e65dd2926a5187dcd837fede1897
[postfix_master.jinja2.cf]
_update_hash_filename_ = postfix_master.jinja2.cf
md5sum = 7752a8b4af5c18dc404e0a862af89272
[postfix_vmailbox.jinja2]
_update_hash_filename_ = postfix_vmailbox.jinja2
md5sum = b01eb42fd9cecc1fcc9bad85f463eea6
[postfix_virtual.jinja2]
_update_hash_filename_ = postfix_virtual.jinja2
md5sum = 701c95b5542890034444cf82ecf2a5e3
[postfix_mysql_mailbox.jinja2.cf]
_update_hash_filename_ = postfix_mysql_mailbox.jinja2.cf
md5sum = 4130e8e13cc98a75db098d38d8f369d6
[postfix_mysql_aliases.jinja2.cf]
_update_hash_filename_ = postfix_mysql_aliases.jinja2.cf
md5sum = 85e1d6c8ed15d3e6d58d9479d5ea7d55
[template-apache.conf]
filename = apache.conf.in
md5sum = e49410f0a4bf28993a56bb28aff0a6f0
[template-php.ini]
filename = php.ini.in
md5sum = eccdfb6d780d9aa4cf66401191ab16a6
[template-apache-httpd]
filename = apache-httpd.conf.in
md5sum = 4ad906791f0d6fd3a4aef8f5a8018b45
[template-snappymail.jinja2.ini]
filename = snappymail.jinja2.ini
md5sum = 87aae866c798b4b411953aa1ff091703
[template-snappymail-domain.jinja2.json]
filename = snappymail-domain.jinja2.json
md5sum = 2dfd15fb4fa3a839a43df9516af3829e
function auth_passdb_lookup(req)
return dovecot.auth.PASSDB_RESULT_OK, string.format("password=%s", req.password)
end
function script_init()
return 0
end
function script_deinit()
end
function auth_userdb_iterate()
return {"alpha"}
end
driver = pgsql
connect = host={{ postgresql_host }} port={{ postgresql_port }} dbname={{ postgresql_dbname }} user={{ postgresql_user }} password={{ postgresql_pass }}
default_pass_scheme = PLAIN
password_query = \
SELECT email as username, passwd AS password FROM addresses WHERE email = '%u'
user_query = \
SELECT '{{ slap_configuration['user-name'] }}' AS uid, '{{ slap_configuration['user-name'] }}' as gid, email, '{{ directory['home-dovecot'] }}/%d/%n' AS home \
FROM addresses WHERE email = '%u'
iterate_query = SELECT email AS user FROM addresses
\ No newline at end of file
protocols = " imap lmtp pop3"
auth_debug = yes
auth_mechanisms = plain login
auth_username_format = %n
auth_username_format = %Lu
auth_verbose = yes
auth_debug_passwords = yes
auth_verbose_passwords = yes
base_dir = {{ directory['run-dovecot'] }}
state_dir = {{directory['var-dovecot'] }}
mail_temp_dir = {{directory['tmp-dovecot'] }}
......@@ -79,10 +81,11 @@ namespace inbox {
ssl = no
passdb {
driver = lua
args = file={{ dovecot_passdb_lua }} blocking=yes
driver = sql
args = {{ dovecot_sql }}
}
userdb {
driver = static
args = uid={{ slap_configuration['user-name'] }} gid={{ slap_configuration['user-name'] }} home={{ directory['home-dovecot'] }}/%u
}
driver = sql
args = {{ dovecot_sql }}
}
\ No newline at end of file
......@@ -2,43 +2,79 @@
parts =
switch-softwaretype
eggs-directory = ${buildout:eggs-directory}
develop-eggs-directory = ${buildout:develop-eggs-directory}
eggs-directory = {{ buildout_egg_directory }}
develop-eggs-directory = {{ buildout_develop_directory }}
offline = true
[default-dynamic-template-parameters]
bin-directory = ${buildout:bin-directory}
buildout-bin-directory = ${buildout:bin-directory}
[dynamic-template-default]
[jinja2-template-base]
recipe = slapos.recipe.template:jinja2
url = ${template-default:target}
filename = instance-default.cfg
output = $${buildout:directory}/$${:filename}
output = ${buildout:directory}/${:filename}
extensions = jinja2.ext.do
extra-context =
context =
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key slapparameter_dict slap-configuration:configuration
raw template_monitor ${monitor2-template:output}
raw dovecot_conf_template ${dovecot.jinja2.conf:target}
raw dovecot_passdb_lua_template ${dovecot-passdb.jinja2.lua:target}
raw dovecot_binary ${dovecot:location}/sbin/dovecot
raw postfix_main_template ${postfix_main.jinja2.cf:target}
raw postfix_master_template ${postfix_master.jinja2.cf:target}
raw postfix_virtual_template ${postfix_virtual.jinja2:target}
raw postfix_vmailbox_template ${postfix_vmailbox.jinja2:target}
raw postfix_location ${postfix:location}
raw xz_utils_location ${xz-utils:location}
key develop_eggs_directory buildout:develop-eggs-directory
key eggs_directory buildout:eggs-directory
key ipv4 slap-configuration:ipv4
key ipv6 slap-configuration:ipv6
key slapparameter_dict slap-configuration:configuration
key computer_id slap-configuration:computer
raw template_monitor {{ template_monitor }}
raw openssl_location {{ openssl_location }}
raw logrotate_cfg {{ logrotate_cfg }}
${:extra-context}
[dynamic-template-default]
<= jinja2-template-base
url = {{ template_default }}
filename = instance-default.cfg
extra-context =
raw dovecot_conf_template {{ dovecot_conf_template }}
raw dovecot_sql_template {{ dovecot_sql_template }}
raw dovecot_binary {{ dovecot_binary }}
raw postfix_main_template {{ postfix_main_template }}
raw postfix_master_template {{ postfix_master_template }}
raw postfix_virtual_template {{ postfix_virtual_template }}
raw postfix_vmailbox_template {{ postfix_vmailbox_template }}
raw postfix_location {{ postfix_location }}
raw xz_utils_location {{ xz_utils_location }}
section apache_parameter_dict dynamic-template-apache-php-parameters
section slap_connection slap-connection
key ipv4_set slap-configuration:ipv4
key ipv6_set slap-configuration:ipv6
raw bin_directory {{ bin_directory }}
raw postgresql_location {{ postgresql_location }}
raw lamp_apache_httpd {{ lamp_apache_httpd }}
raw snappymail_conf {{ snappymail_conf }}
raw snappymail_domain {{ snappymail_domain }}
[dynamic-template-apache-php-parameters]
{% if application_archive_root %}
application-location = {{ application_location }}/{{ application_archive_root }}
{% else %}
application-location = {{ application_location }}
{% endif %}
template-apache-conf = {{ template_apache_conf }}
apache-location = {{ apache_location }}
apache-php-location = {{ apache_php_location }}
template-php-ini = {{ template_php_ini }}
publish-frontend = !py!{{ default_frontend }}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration.serialised
computer = $${slap-connection:computer-id}
partition = $${slap-connection:partition-id}
url = $${slap-connection:server-url}
key = $${slap-connection:key-file}
cert = $${slap-connection:cert-file}
computer = ${slap-connection:computer-id}
partition = ${slap-connection:partition-id}
url = ${slap-connection:server-url}
key = ${slap-connection:key-file}
cert = ${slap-connection:cert-file}
[publish-connection-parameters]
imap-port = 10143
smtp-port = 10025
[switch-softwaretype]
recipe = slapos.cookbook:switch-softwaretype
......
[PHP]
engine = On
safe_mode = Off
expose_php = Off
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = On
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
session.save_path = "{{ apache_parameter_dict['tmp-dir'] }}"
session.auto_start = 0
date.timezone = {{ instance_dict.get('php.date.timezone', 'Europe/Paris') }}
file_uploads = On
upload_max_filesize = {{ instance_dict.get('php.upload_max_filesize', '10240M') }}
post_max_size = {{ instance_dict.get('php.post_max_size', '10240M') }}
magic_quotes_gpc=Off
memory_limit = {{ instance_dict.get('php.memory_limit', '512M') }}
session.cookie_secure = True
max_execution_time = {{ instance_dict.get('php.max_execution_time', 1800) }}
max_input_time = {{ instance_dict.get('php.max_input_time', 3600) }}
output_buffering = {{ instance_dict.get('php.output_buffering', 4096) }}
max_file_uploads = {{ instance_dict.get('php.max_file_uploads', 100) }}
#extension_dir="./"#
sys_temp_dir="{{ apache_parameter_dict['tmp-dir'] }}"
upload_tmp_dir="{{ apache_parameter_dict['php-upload-dir'] }}"
zend_extension=opcache
extension=apcu
extension=redis
extension=imagick
apc.enabled=1
apc.file_update_protection=2
apc.optimization=0
apc.shm_size=256M
apc.include_once_override=0
apc.shm_segments=1
apc.ttl=7200
apc.user_ttl=7200
apc.gc_ttl=3600
apc.num_files_hint=1024
apc.enable_cli=1
apc.max_file_size=5M
apc.cache_by_default=1
apc.use_request_time=1
apc.slam_defense=0
apc.mmap_file_mask="{{ apache_parameter_dict['tmp-dir'] }}/apc.XXXXXX"
apc.stat_ctime=0
apc.canonicalize=1
apc.write_lock=1
apc.report_autofilter=0
apc.rfc1867=0
apc.rfc1867_prefix =upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0
apc.rfc1867_ttl=3600
apc.lazy_classes=0
apc.lazy_functions=0
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer={{ instance_dict.get('php.opcache.interned-strings-buffer', 8) }}
opcache.max_accelerated_files=10000
opcache.revalidate_freq={{ instance_dict.get('php.opcache.revalidate-freq', 1) }}
opcache.save_comments=1
......@@ -20,14 +20,14 @@ setgid_group = {{ setgid_group }}
virtual_mailbox_domains = {{ mail_domain }}
virtual_mailbox_base = {{ vhosts_directory }}
virtual_mailbox_maps = hash:{{ vmailbox_file }}
virtual_minimum_uid = 100
virtual_uid_maps = static:1001
virtual_gid_maps = static:1022
virtual_alias_maps = hash:{{ virtual_file }}
virtual_mailbox_maps = pgsql:{{ vmailbox_file }}
virtual_alias_maps = pgsql:{{ virtual_file }}
virtual_transport = lmtp:unix:private/dovecot-lmtp
inet_interfaces = {{ ip_address }}
inet_interfaces = all
inet_protocols = all
smtp_bind_address = 0.0.0.0
smtp_bind_address6 = ::
......@@ -45,6 +45,7 @@ smtpd_recipient_restrictions =
smtpd_relay_restrictions =
permit_sasl_authenticated
defer_unauth_destination
permit_mynetworks
allow_min_user = yes
......
user = {{ postgresql_user }}
password = {{ postgresql_pass }}
hosts = {{ postgresql_host }}
dbname = {{ postgresql_dbname }}
query = SELECT 1 FROM aliases WHERE source = '%s'
\ No newline at end of file
user = {{ postgresql_user }}
password = {{ postgresql_pass }}
hosts = {{ postgresql_host }}
dbname = {{ postgresql_dbname }}
query = SELECT 1 FROM addresses WHERE email = '%s'
\ No newline at end of file
postmaster@{{ mail_domain }} postmaster
@{{ mail_domain }} {{ mail_domain }}/catchall
{
"IMAP": {
"host": "{{ mail_host }}",
"port": 10143,
"type": 0,
"timeout": 300,
"shortLogin": false,
"lowerLogin": true,
"stripLogin": "",
"sasl": [
"SCRAM-SHA3-512",
"SCRAM-SHA-512",
"SCRAM-SHA-256",
"SCRAM-SHA-1",
"PLAIN",
"LOGIN"
],
"ssl": {
"verify_peer": false,
"verify_peer_name": false,
"allow_self_signed": false,
"SNI_enabled": true,
"disable_compression": true,
"security_level": 1
},
"use_expunge_all_on_delete": false,
"fast_simple_search": true,
"force_select": false,
"message_all_headers": false,
"message_list_limit": 10000,
"search_filter": "",
"spam_headers": "",
"virus_headers": "",
"disabled_capabilities": [
"METADATA",
"OBJECTID",
"PREVIEW",
"STATUS=SIZE"
]
},
"SMTP": {
"host": "{{ mail_host }}",
"port": 10025,
"type": 0,
"timeout": 60,
"shortLogin": false,
"lowerLogin": true,
"stripLogin": "",
"sasl": [
"SCRAM-SHA3-512",
"SCRAM-SHA-512",
"SCRAM-SHA-256",
"SCRAM-SHA-1",
"PLAIN",
"LOGIN"
],
"ssl": {
"verify_peer": false,
"verify_peer_name": false,
"allow_self_signed": false,
"SNI_enabled": true,
"disable_compression": true,
"security_level": 1
},
"useAuth": true,
"setSender": false,
"usePhpMail": false,
"authPlainLine": false
},
"Sieve": {
"host": "",
"port": 4190,
"type": 0,
"timeout": 10,
"shortLogin": false,
"lowerLogin": true,
"stripLogin": "",
"sasl": [
"SCRAM-SHA3-512",
"SCRAM-SHA-512",
"SCRAM-SHA-256",
"SCRAM-SHA-1",
"PLAIN",
"LOGIN"
],
"ssl": {
"verify_peer": false,
"verify_peer_name": false,
"allow_self_signed": false,
"SNI_enabled": true,
"disable_compression": true,
"security_level": 1
},
"enabled": false,
"authLiteral": true
},
"whiteList": ""
}
; SnappyMail configuration file
; Please don't add custom parameters here, those will be overwritten
[webmail]
; Text displayed as page title
title = "SnappyMail Webmail"
; Text displayed on startup
loading_description = "SnappyMail"
favicon_url = ""
app_path = ""
; Theme used by default
theme = "Default"
; Allow theme selection on settings screen
allow_themes = On
allow_user_background = Off
; Language used by default
language = "en"
; Allow language selection on settings screen
allow_languages_on_settings = On
allow_additional_accounts = On
allow_additional_identities = On
; When identity is not set yet, open identity popup after login
popup_identity = On
; Number of messages displayed on page by default
messages_per_page = 20
; Mark message read after N seconds
message_read_delay = 5
; Minimal check for new messages interval in minutes
min_refresh_interval = 5
; File size limit (MB) for file upload on compose screen
; 0 for unlimited.
attachment_size_limit = 25
; brotli or gzip compress the output.
; Warning: only enable when server does not do this, else double compression errors occur
compress_output = Off
[interface]
show_attachment_thumbnail = On
[contacts]
; Enable contacts
enable = Off
allow_sync = Off
sync_interval = 20
type = "pgsql"
pdo_dsn = "host={{ postgresql_host }};port={{ postgresql_port }};dbname=snappymail"
pdo_user = "{{ postgresql_user }}"
pdo_password = "{{ postgresql_pass }}"
; PEM format certificate
mysql_ssl_ca = ""
mysql_ssl_verify = On
; HIGH
mysql_ssl_ciphers = ""
sqlite_global = Off
suggestions_limit = 20
[security]
custom_server_signature = "SnappyMail"
x_xss_protection_header = "1; mode=block"
gnupg = On
openpgp = On
auto_verify_signatures = Off
; Access settings
allow_admin_panel = On
; Login and password for web admin panel
admin_login = "admin"
admin_password = "admin"
admin_totp = ""
; Use email address instead of login password for encrypting sensitive data (like account passwords)
insecure_cryptkey = Off
force_https = Off
hide_x_mailer_header = On
; https://en.m.wikipedia.org/wiki/Load_(computing)
max_sys_getloadavg = 0
; For example to allow all images use "img-src https:". More info at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#directives
content_security_policy = ""
; Report CSP errors to PHP and/or SnappyMail Log
csp_report = Off
; A valid cipher method from https://php.net/openssl_get_cipher_methods
encrypt_cipher = "aes-256-cbc-hmac-sha1"
; Strict, Lax or None
cookie_samesite = "Strict"
; Additional allowed Sec-Fetch combinations separated by ";".
; For example:
; * Allow iframe on same domain in any mode: dest=iframe,site=same-origin
; * Allow navigate to iframe on same domain: mode=navigate,dest=iframe,site=same-origin
; * Allow navigate to iframe on (sub)domain: mode=navigate,dest=iframe,site=same-site
; * Allow navigate to iframe from any domain: mode=navigate,dest=iframe,site=cross-site
;
; Default is "site=same-origin;site=none"
secfetch_allow = ""
[admin_panel]
host = ""
key = "admin"
allow_update = Off
; Admin Panel interface language
language = "en"
[ssl]
; Require verification of SSL certificate used.
verify_certificate = On
; Allow self-signed certificates. Requires verify_certificate.
allow_self_signed = Off
; https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html
security_level = 1
; Location of Certificate Authority file on local filesystem (/etc/ssl/certs/ca-certificates.crt)
cafile = ""
; capath must be a correctly hashed certificate directory. (/etc/ssl/certs/)
capath = ""
; Location of client certificate file (pem format with private key) on local filesystem
local_cert = ""
; This can help mitigate the CRIME attack vector.
disable_compression = On
[capa]
; Allow clear folder and delete messages without moving to trash
dangerous_actions = On
; Allow download attachments as Zip (and optionally others)
attachments_actions = On
[login]
; If someone logs in without "@domain.tld", this value will be used
; When this value is HTTP_HOST, the $_SERVER["HTTP_HOST"] value is used.
; When this value is SERVER_NAME, the $_SERVER["SERVER_NAME"] value is used.
; When this value is gethostname, the gethostname() value is used.
;
default_domain = "{{ mail_domain }}"
; Allow language selection on webmail login screen
allow_languages_on_login = On
; Detect language from browser header `Accept-Language`
determine_user_language = On
; Like default_domain but then HTTP_HOST/SERVER_NAME without www.
determine_user_domain = Off
; This option allows webmail to remember the logged in user
; once they closed the browser window.
;
; Values:
; "DefaultOff" - can be used, disabled by default;
; "DefaultOn" - can be used, enabled by default;
; "Unused" - cannot be used
sign_me_auto = "DefaultOff"
; When login fails, wait N seconds before responding
fault_delay = 5
[plugins]
; Enable plugin support
enable = Off
; Comma-separated list of enabled plugins
enabled_list = ""
[defaults]
; Editor mode used by default (Plain, Html)
view_editor_type = "Html"
; layout: 0 - no preview, 1 - side preview, 2 - bottom preview
view_layout = 1
view_use_checkboxes = On
; Show next message when (re)move current message
view_show_next_message = On
autologout = 30
view_html = On
show_images = Off
; View external images:
; "ask" - always ask
; "match" - whitelist or ask
; "always" - show always
view_images = "ask"
contacts_autosave = On
mail_list_grouped = Off
mail_use_threads = Off
allow_draft_autosave = On
mail_reply_same_folder = Off
; 1 - reply, 2 - reply all
msg_default_action = 1
collapse_blockquotes = On
allow_spellcheck = Off
[logs]
; Enable logging
enable = Off
; Path where log files will be stored
path = ""
; Log messages of set RFC 5424 section 6.2.1 Severity level and higher (0 = highest, 7 = lowest).
; 0 = Emergency
; 1 = Alert
; 2 = Critical
; 3 = Error
; 4 = Warning
; 5 = Notice
; 6 = Informational
; 7 = Debug
level = 4
; Required for development purposes only.
; Disabling this option is not recommended.
hide_passwords = On
time_zone = "UTC"
; Log filename.
; For security reasons, some characters are removed from filename.
; Allows for pattern-based folder creation (see examples below).
;
; Patterns:
; {date:Y-m-d} - Replaced by pattern-based date
; Detailed info: http://www.php.net/manual/en/function.date.php
; {user:email} - Replaced by user's email address
; If user is not logged in, value is set to "unknown"
; {user:login} - Replaced by user's login (the user part of an email)
; If user is not logged in, value is set to "unknown"
; {user:domain} - Replaced by user's domain name (the domain part of an email)
; If user is not logged in, value is set to "unknown"
; {user:uid} - Replaced by user's UID regardless of account currently used
;
; {user:ip}
; {request:ip} - Replaced by user's IP address
;
; Others:
; {imap:login} {imap:host} {imap:port}
; {smtp:login} {smtp:host} {smtp:port}
;
; Examples:
; filename = "log-{date:Y-m-d}.txt"
; filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
; filename = "{user:email}-{date:Y-m-d}.txt"
; filename = "syslog"
; filename = "stderr"
filename = "log-{date:Y-m-d}.txt"
; Enable auth logging in a separate file (for fail2ban)
auth_logging = Off
auth_logging_filename = "fail2ban/auth-{date:Y-m-d}.txt"
auth_logging_format = "[{date:Y-m-d H:i:s}] Auth failed: ip={request:ip} user={imap:login} host={imap:host} port={imap:port}"
; Enable auth logging to syslog for fail2ban
auth_syslog = Off
json_response_write_limit = 300
[debug]
; Special option required for development purposes
enable = Off
javascript = Off
css = Off
[cache]
; The section controls caching of the entire application.
;
; Enables caching in the system
enable = On
; Path where cache files will be stored
path = ""
; Additional caching key. If changed, cache is purged
index = "v1"
; Additional caching key. If changed, fast cache is purged
fast_cache_index = "v1"
; Browser-level cache. If enabled, caching is maintainted without using files
http = On
; Browser-level cache time (seconds, Expires header)
http_expires = 3600
; Caching message UIDs when searching and sorting (threading)
server_uids = On
system_data = On
[imap]
use_force_selection = Off
use_expunge_all_on_delete = Off
message_list_fast_simple_search = On
message_list_permanent_filter = ""
message_all_headers = Off
show_login_alert = On
fetch_new_messages = On
[labs]
; Allow drag & drop .eml files from system into messages list
allow_message_append = Off
smtp_show_server_errors = Off
; PHP mail() remove To and Subject headers
mail_func_clear_headers = On
; PHP mail() set -f emailaddress
mail_func_additional_parameters = Off
folders_spec_limit = 50
curl_proxy = ""
curl_proxy_auth = ""
custom_login_link = ""
custom_logout_link = ""
http_client_ip_check_proxy = Off
use_local_proxy_for_external_images = On
image_exif_auto_rotate = Off
cookie_default_path = ""
cookie_default_secure = Off
replace_env_in_configuration = ""
boundary_prefix = ""
dev_email = ""
dev_password = ""
[version]
current = "2.38.2"
saved = "Wed, 22 Jan 2025 16:50:11 +0000"
\ No newline at end of file
......@@ -3,27 +3,136 @@ extends =
../../component/xz-utils/buildout.cfg
../../component/postfix/buildout.cfg
../../component/dovecot/buildout.cfg
../../stack/monitor/buildout.cfg
# ../../component/mariadb/buildout.cfg
../../component/postgresql/buildout.cfg
../../stack/slapos.cfg
../../stack/monitor/buildout.cfg
../../stack/erp5/buildout.cfg
../../component/apache-php/buildout.cfg
# ../../component/nginx/buildout.cfg
buildout.hash.cfg
parts =
slapos-cookbook
template
dovecot
postgresql
postfix
apache-php
# nginx
[postfix]
configure-options-CCARGS = '-DHAS_PGSQL -I${postgresql:location}/include ${postfix:default-configure-options-CCARGS}'
#configure-options-CCARGS = '-DHAS_PGSQL -I${postgresql:location}/include -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -DUSE_TLS -DHAS_PCRE -DHAS_DB -I${libdb:location}/include -I${pcre:location}/include -I${openssl:location}/include -I${cyrus-sasl:location}/include/sasl -I${libnsl:location}/include'
configure-options-AUXLIBS = '-L${postgresql:location}/lib -Wl,-rpath=${postgresql:location}/lib -lpq ${postfix:default-configure-options-AUXLIBS}'
[dovecot]
extra-pkg-config=${postgresql:location}/lib/pkgconfig
extra-configure-options =
--with-pgsql=yes
extra-environment =
PGSQL_LIBS=-L${postgresql:location}/lib -Wl,-rpath=${postgresql:location}/lib
PGSQL_CFLAGS=-I${postgresql:location}/include
extra-ld-flags=-L${postgresql:location}/lib -Wl,-rpath=${postgresql:location}/lib
extra-c-flags=-I${postgresql:location}/include
[template]
recipe = slapos.recipe.template
recipe = slapos.recipe.template:jinja2
url = ${:_profile_base_location_}/${:filename}
output = ${buildout:directory}/template.cfg
context =
key application_location application:location
key application_archive_root application:archive-root
key apache_location apache:location
key apache_php_location apache-php:location
key bash_location bash:location
key bin_directory buildout:bin-directory
key coreutils_location coreutils:location
key buildout_egg_directory buildout:eggs-directory
key buildout_develop_directory buildout:develop-eggs-directory
key buildout_directory buildout:directory
key dash_location dash:location
# key findutils_location findutils:location
key logrotate_location logrotate:location
key logrotate_cfg template-logrotate-base:output
# key gzip_location gzip:location
# key xz_utils_location xz-utils:location
key template_monitor monitor2-template:output
key mariadb_link_binary template-mariadb:link-binary
key postgresql_location postgresql:location
key mariadb_location mariadb:location
key mariadb_resiliency_after_import_script mariadb-resiliency-after-import-script:target
key mariadb_slow_query_report_script mariadb-slow-query-report-script:target
key mariadb_start_clone_from_backup mariadb-start-clone-from-backup:target
key mroonga_mariadb_install_sql mroonga-mariadb:install-sql
key mroonga_mariadb_plugin_dir mroonga-mariadb:plugin-dir
key groonga_plugin_dir groonga:groonga-plugin-dir
key groonga_mysql_normalizer_plugin_dir groonga-normalizer-mysql:groonga-plugin-dir
key percona_toolkit_location percona-toolkit:location
key template_php_ini template-php.ini:target
key template_apache_conf template-apache.conf:target
# key template_apache_php instance-apache-php:target
# key template_lamp instance-lamp:target
key template_default template-default:target
key template_mariadb template-mariadb:target
key template_mariadb_initial_setup template-mariadb-initial-setup:target
key template_mysqld_wrapper template-mysqld-wrapper:output
key template_my_cnf template-my-cnf:target
key unixodbc_location unixodbc:location
key openssl_location openssl:location
key db_name custom-application-deployment:db-name
key db_user custom-application-deployment:db-user
key default_frontend custom-application-deployment:default-frontend
key lamp_apache_httpd template-apache-httpd:target
raw dovecot_conf_template ${dovecot.jinja2.conf:target}
raw dovecot_sql_template ${dovecot-sql.jinja2.conf.ext:target}
raw dovecot_binary ${dovecot:location}/sbin/dovecot
raw postfix_main_template ${postfix_main.jinja2.cf:target}
raw postfix_master_template ${postfix_master.jinja2.cf:target}
raw postfix_virtual_template ${postfix_mysql_aliases.jinja2.cf:target}
raw postfix_vmailbox_template ${postfix_mysql_mailbox.jinja2.cf:target}
raw postfix_location ${postfix:location}
raw xz_utils_location ${xz-utils:location}
raw snappymail_conf ${template-snappymail.jinja2.ini:target}
raw snappymail_domain ${template-snappymail-domain.jinja2.json:target}
[download-base]
[template-download-base]
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_update_hash_filename_}
url = ${:_profile_base_location_}/${:filename}
[template-apache.conf]
<= template-download-base
[template-php.ini]
<= template-download-base
# download apache-httpd.conf.in
[template-apache-httpd]
<= template-download-base
[template-snappymail.jinja2.ini]
<= template-download-base
[template-snappymail-domain.jinja2.json]
<= template-download-base
[custom-application-deployment]
# path = /path/to/instance-custom.cfg
# part-list = part1 part2
# See software/maarch/software.cfg for an example.
path =
part-list =
# database information
db-name = lamp
db-user = lamp
# Publish default lamp slave frontend url
default-frontend = True
[template-default]
<= download-base
recipe = slapos.recipe.build:download
url = ${:_profile_base_location_}/${:_update_hash_filename_}
[copy-to-instance]
recipe = slapos.recipe.build:download
......@@ -32,14 +141,20 @@ filename = ${:_buildout_section_name_}
[dovecot.jinja2.conf]
< = copy-to-instance
[dovecot-passdb.jinja2.lua]
[dovecot-sql.jinja2.conf.ext]
< = copy-to-instance
[postfix_main.jinja2.cf]
< = copy-to-instance
[postfix_master.jinja2.cf]
< = copy-to-instance
[postfix_vmailbox.jinja2]
[postfix_mysql_mailbox.jinja2.cf]
< = copy-to-instance
[postfix_virtual.jinja2]
[postfix_mysql_aliases.jinja2.cf]
< = copy-to-instance
[application]
url = https://github.com/the-djmaze/snappymail/releases/download/v2.38.2/snappymail-2.38.2.tar.gz
md5sum = 551af7a01691f8d988c16aa73c75e686
recipe = slapos.recipe.build:download-unpacked
archive-root =
#!${dash-output:dash}
# BEWARE: This file is operated by slapos node
# BEWARE: It will be overwritten automatically
if [ ! -e $${nginx-configuration:ssl_crt} ]
then
${openssl-output:openssl} genrsa -out $${nginx-configuration:ssl_key} 2048
${openssl-output:openssl} req -new \
-subj "/C=AA/ST=Denial/L=Nowhere/O=Dis/CN=$${nginx-configuration:ip}" \
-key $${nginx-configuration:ssl_key} -out $${nginx-configuration:ssl_csr}
${openssl-output:openssl} x509 -req -days 365 \
-in $${nginx-configuration:ssl_csr} \
-signkey $${nginx-configuration:ssl_key} \
-out $${nginx-configuration:ssl_crt}
fi
exec ${nginx-output:nginx} \
-c $${nginx-configuration:output}
daemon off; # run in the foreground so supervisord can look after it
worker_processes 4;
pid $${directory:run}/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
error_log $${nginx-configuration:error_log};
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
default_type application/octet-stream;
include ${nginx-output:mime};
##
# Logging Settings
##
access_log $${nginx-configuration:access_log};
error_log $${nginx-configuration:error_log};
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
server {
listen [$${nginx-configuration:ip}]:$${nginx-configuration:port} ssl;
ssl_certificate $${nginx-configuration:ssl_crt};
ssl_certificate_key $${nginx-configuration:ssl_key};
fastcgi_temp_path $${directory:varnginx} 1 2;
uwsgi_temp_path $${directory:varnginx} 1 2;
scgi_temp_path $${directory:varnginx} 1 2;
client_body_temp_path $${directory:varnginx} 1 2;
proxy_temp_path $${directory:varnginx} 1 2;
## Only allow GET and HEAD request methods
if ($request_method !~ ^(GET|HEAD)$ ) {
return 444;
}
## Serve an error 204 (No Content) for favicon.ico
location = /favicon.ico {
return 204;
}
location /
{
root $${directory:www};
# index index.html;
}
}
}
......@@ -66,6 +66,13 @@ db-user = lamp
# Publish default lamp slave frontend url
default-frontend = True
[custom-application-deployment-lamp]
# path = /path/to/instance-custom.cfg
# part-list = part1 part2
# See software/maarch/software.cfg for an example.
path =
part-list =
#----------------
#-- Instance-level buildout profiles.
......@@ -77,6 +84,7 @@ context =
key application_location application:location
key application_archive_root application:archive-root
key application_deployment_part_list custom-application-deployment:part-list
key application_deployment_lamp_part_list custom-application-deployment-lamp:part-list
key apache_location apache:location
key apache_php_location apache-php:location
key bash_location bash:location
......@@ -112,6 +120,7 @@ context =
key template_my_cnf template-my-cnf:target
key unixodbc_location unixodbc:location
key openssl_location openssl:location
key custom_application_lamp_template custom-application-deployment-lamp:path
key custom_application_template custom-application-deployment:path
key db_name custom-application-deployment:db-name
key db_user custom-application-deployment:db-user
......
......@@ -14,7 +14,7 @@
# not need these here).
[lamp-instance]
filename = instance.cfg.in
md5sum = f34548ba607becf3acd5c5e3d8e70551
md5sum = ed9589ab08ffefeb1eefeacd8ee97bb7
[instance-apache-php]
filename = instance-apache-php.cfg.in
......@@ -22,7 +22,7 @@ md5sum = 41602a61d5f9609281dbfa3f27da0626
[instance-lamp]
filename = instance-lamp.cfg.jinja2.in
md5sum = de1f450a80547d12334b712016138078
md5sum = 18e024ed67ea1f4ada10c01780d1975b
[template-apache.conf]
filename = apache.conf.in
......
......@@ -91,12 +91,16 @@ recipe = slapos.cookbook:publish
extends =
{{ template_monitor }}
{{ parameter_dict['application-lamp-path'] }}
parts =
publish-connection-information
# Complete parts with sections
{{ part_list | join('\n ') }}
{{ parameter_dict['application-lamp-part-list'] }}
eggs-directory = {{ eggs_directory }}
develop-eggs-directory = {{ develop_eggs_directory }}
offline = true
......@@ -43,6 +43,11 @@ context =
[mariadb-password]
recipe = slapos.cookbook:generate.password
# XXX no failure if `custom_application_template` is empty
[application-parameters]
custom-application-template = {{ custom_application_template }}
custom-application-lamp-template = {{ custom_application_lamp_template }}
[dynamic-template-lamp-parameters]
[dynamic-template-lamp]
......@@ -50,6 +55,7 @@ recipe = slapos.cookbook:generate.password
url = {{ template_lamp }}
filename = template-lamp.cfg
extra-context =
key custom_application_lamp_template application-parameters:custom-application-lamp-template
section parameter_dict dynamic-template-lamp-parameters
raw db_name {{ db_name }}
raw db_user {{ db_user }}
......@@ -68,10 +74,6 @@ apache-php-location = {{ apache_php_location }}
template-php-ini = {{ template_php_ini }}
publish-frontend = !py!{{ default_frontend }}
# XXX no failure if `custom_application_template` is empty
[application-parameters]
custom-application-template = {{ custom_application_template }}
[dynamic-template-apache-php]
<= jinja2-template-base
url = {{ template_apache_php }}
......
......@@ -82,6 +82,8 @@ def main():
if line is None or not line.startswith('#'):
if line is None or line.startswith('['):
if hash_file_path is not None:
if hash_name not in HASH_MAP:
print("Warning: unknown hash:", hash_name)
current_section.insert(
len([x for x in current_section if x.strip()]),
'%s = %s%s' % (
......
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