Initial
This commit is contained in:
2
install/common/api/billing
Normal file
2
install/common/api/billing
Normal file
@@ -0,0 +1,2 @@
|
||||
ROLE='admin'
|
||||
COMMANDS='v-add-user,v-delete-user,v-suspend-user,v-unsuspend-user,v-change-user-shell,v-list-user,v-list-users,v-make-tmp-file,v-add-domain,v-change-user-package,v-make-tmp-file,v-change-user-password'
|
||||
2
install/common/api/mail-accounts
Normal file
2
install/common/api/mail-accounts
Normal file
@@ -0,0 +1,2 @@
|
||||
ROLE='user'
|
||||
COMMANDS='v-list-mail-domains,v-list-mail-domain,v-list-mail-account,v-list-mail-accounts,v-list-mail-account-autoreply,v-delete-mail-account,v-delete-mail-account-alias,v-delete-mail-account-autoreply,v-delete-mail-account-forward,v-delete-mail-account-fwd-only,v-add-mail-account,v-add-mail-account-alias,v-add-mail-account-autoreply,v-add-mail-account-forward,v-add-mail-account-fwd-only,v-change-mail-account-password,v-change-mail-account-quota,v-suspend-mail-account,v-suspend-mail-accounts,v-unsuspend-mail-account,v-unsuspend-mail-accounts'
|
||||
2
install/common/api/phpmyadmin-sso
Normal file
2
install/common/api/phpmyadmin-sso
Normal file
@@ -0,0 +1,2 @@
|
||||
ROLE='admin'
|
||||
COMMANDS='v-add-database-temp-user,v-delete-database-temp-user'
|
||||
2
install/common/api/purge-nginx-cache
Normal file
2
install/common/api/purge-nginx-cache
Normal file
@@ -0,0 +1,2 @@
|
||||
ROLE='user'
|
||||
COMMANDS='v-purge-nginx-cache,v-list-web-domains,v-list-web-domain'
|
||||
2
install/common/api/sync-dns-cluster
Normal file
2
install/common/api/sync-dns-cluster
Normal file
@@ -0,0 +1,2 @@
|
||||
ROLE='admin'
|
||||
COMMANDS='v-list-users,v-list-sys-config,v-list-user,v-add-cron-restart-job,v-delete-dns-domains-src,v-insert-dns-domain,v-insert-dns-record,v-insert-dns-records,v-rebuild-dns-domains,v-rebuild-dns-domain,v-delete-dns-record,v-make-tmp-file,v-insert-dns-domain,v-delete-dns-domain'
|
||||
2
install/common/api/update-dns-records
Normal file
2
install/common/api/update-dns-records
Normal file
@@ -0,0 +1,2 @@
|
||||
ROLE='user'
|
||||
COMMANDS='v-list-dns-records,v-change-dns-record'
|
||||
5
install/common/dovecot/conf.d/10-auth.conf
Normal file
5
install/common/dovecot/conf.d/10-auth.conf
Normal file
@@ -0,0 +1,5 @@
|
||||
disable_plaintext_auth = no
|
||||
auth_username_format = %Lu
|
||||
auth_verbose = yes
|
||||
auth_mechanisms = plain login
|
||||
!include auth-passwdfile.conf.ext
|
||||
1
install/common/dovecot/conf.d/10-logging.conf
Normal file
1
install/common/dovecot/conf.d/10-logging.conf
Normal file
@@ -0,0 +1 @@
|
||||
log_path = /var/log/dovecot.log
|
||||
8
install/common/dovecot/conf.d/10-mail.conf
Normal file
8
install/common/dovecot/conf.d/10-mail.conf
Normal file
@@ -0,0 +1,8 @@
|
||||
mail_privileged_group = mail
|
||||
mail_access_groups = mail
|
||||
mail_location = maildir:%h/mail/%d/%n
|
||||
pop3_uidl_format = %08Xu%08Xv
|
||||
|
||||
mailbox_list_index = yes
|
||||
mailbox_idle_check_interval = 30 secs
|
||||
maildir_copy_with_hardlinks = yes
|
||||
31
install/common/dovecot/conf.d/10-master.conf
Normal file
31
install/common/dovecot/conf.d/10-master.conf
Normal file
@@ -0,0 +1,31 @@
|
||||
service imap-login {
|
||||
inet_listener imap {
|
||||
}
|
||||
inet_listener imaps {
|
||||
}
|
||||
}
|
||||
|
||||
service pop3-login {
|
||||
inet_listener pop3 {
|
||||
}
|
||||
inet_listener pop3s {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
service imap {
|
||||
}
|
||||
|
||||
service pop3 {
|
||||
}
|
||||
|
||||
service auth {
|
||||
extra_groups = mail
|
||||
|
||||
unix_listener auth-client {
|
||||
group = mail
|
||||
mode = 0660
|
||||
user = dovecot
|
||||
}
|
||||
user = dovecot
|
||||
}
|
||||
13
install/common/dovecot/conf.d/10-ssl.conf
Normal file
13
install/common/dovecot/conf.d/10-ssl.conf
Normal file
@@ -0,0 +1,13 @@
|
||||
ssl = yes
|
||||
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256
|
||||
ssl_min_protocol = TLSv1.2
|
||||
ssl_prefer_server_ciphers = yes
|
||||
|
||||
ssl_cert = </usr/local/hestia/ssl/certificate.crt
|
||||
ssl_key = </usr/local/hestia/ssl/certificate.key
|
||||
|
||||
# From and up to version 2.2
|
||||
#ssl_dh_parameters_length = 4096
|
||||
|
||||
# From version 2.3
|
||||
ssl_dh = </etc/ssl/dhparam.pem
|
||||
59
install/common/dovecot/conf.d/20-imap.conf
Normal file
59
install/common/dovecot/conf.d/20-imap.conf
Normal file
@@ -0,0 +1,59 @@
|
||||
##
|
||||
## IMAP specific settings
|
||||
##
|
||||
|
||||
protocol imap {
|
||||
# Maximum IMAP command line length. Some clients generate very long command
|
||||
# lines with huge mailboxes, so you may need to raise this if you get
|
||||
# "Too long argument" or "IMAP command line too large" errors often.
|
||||
#imap_max_line_length = 64k
|
||||
|
||||
# Maximum number of IMAP connections allowed for a user from each IP address.
|
||||
# NOTE: The username is compared case-sensitively.
|
||||
#mail_max_userip_connections = 10
|
||||
|
||||
# Space separated list of plugins to load (default is global mail_plugins).
|
||||
#mail_plugins = $mail_plugins
|
||||
mail_plugins = quota imap_quota
|
||||
|
||||
# IMAP logout format string:
|
||||
# %i - total number of bytes read from client
|
||||
# %o - total number of bytes sent to client
|
||||
#imap_logout_format = bytes=%i/%o
|
||||
|
||||
# Override the IMAP CAPABILITY response. If the value begins with '+',
|
||||
# add the given capabilities on top of the defaults (e.g. +XFOO XBAR).
|
||||
#imap_capability =
|
||||
|
||||
# How long to wait between "OK Still here" notifications when client is
|
||||
# IDLEing.
|
||||
#imap_idle_notify_interval = 2 mins
|
||||
|
||||
# ID field names and values to send to clients. Using * as the value makes
|
||||
# Dovecot use the default value. The following fields have default values
|
||||
# currently: name, version, os, os-version, support-url, support-email.
|
||||
#imap_id_send =
|
||||
|
||||
# ID fields sent by client to log. * means everything.
|
||||
#imap_id_log =
|
||||
|
||||
# Workarounds for various client bugs:
|
||||
# delay-newmail:
|
||||
# Send EXISTS/RECENT new mail notifications only when replying to NOOP
|
||||
# and CHECK commands. Some clients ignore them otherwise, for example OSX
|
||||
# Mail (<v2.1). Outlook Express breaks more badly though, without this it
|
||||
# may show user "Message no longer in server" errors. Note that OE6 still
|
||||
# breaks even with this workaround if synchronization is set to
|
||||
# "Headers Only".
|
||||
# tb-extra-mailbox-sep:
|
||||
# Thunderbird gets somehow confused with LAYOUT=fs (mbox and dbox) and
|
||||
# adds extra '/' suffixes to mailbox names. This option causes Dovecot to
|
||||
# ignore the extra '/' instead of treating it as invalid mailbox name.
|
||||
# tb-lsub-flags:
|
||||
# Show \Noselect flags for LSUB replies with LAYOUT=fs (e.g. mbox).
|
||||
# This makes Thunderbird realize they aren't selectable and show them
|
||||
# greyed out, instead of only later giving "not selectable" popup error.
|
||||
#
|
||||
# The list is space-separated.
|
||||
#imap_client_workarounds =
|
||||
}
|
||||
92
install/common/dovecot/conf.d/20-pop3.conf
Normal file
92
install/common/dovecot/conf.d/20-pop3.conf
Normal file
@@ -0,0 +1,92 @@
|
||||
##
|
||||
## POP3 specific settings
|
||||
##
|
||||
|
||||
protocol pop3 {
|
||||
# Don't try to set mails non-recent or seen with POP3 sessions. This is
|
||||
# mostly intended to reduce disk I/O. With maildir it doesn't move files
|
||||
# from new/ to cur/, with mbox it doesn't write Status-header.
|
||||
#pop3_no_flag_updates = no
|
||||
|
||||
# Support LAST command which exists in old POP3 specs, but has been removed
|
||||
# from new ones. Some clients still wish to use this though. Enabling this
|
||||
# makes RSET command clear all \Seen flags from messages.
|
||||
#pop3_enable_last = no
|
||||
|
||||
# If mail has X-UIDL header, use it as the mail's UIDL.
|
||||
#pop3_reuse_xuidl = no
|
||||
|
||||
# Keep the mailbox locked for the entire POP3 session.
|
||||
#pop3_lock_session = no
|
||||
|
||||
# POP3 requires message sizes to be listed as if they had CR+LF linefeeds.
|
||||
# Many POP3 servers violate this by returning the sizes with LF linefeeds,
|
||||
# because it's faster to get. When this setting is enabled, Dovecot still
|
||||
# tries to do the right thing first, but if that requires opening the
|
||||
# message, it fallbacks to the easier (but incorrect) size.
|
||||
#pop3_fast_size_lookups = no
|
||||
|
||||
# POP3 UIDL (unique mail identifier) format to use. You can use following
|
||||
# variables, along with the variable modifiers described in
|
||||
# doc/wiki/Variables.txt (e.g. %Uf for the filename in uppercase)
|
||||
#
|
||||
# %v - Mailbox's IMAP UIDVALIDITY
|
||||
# %u - Mail's IMAP UID
|
||||
# %m - MD5 sum of the mailbox headers in hex (mbox only)
|
||||
# %f - filename (maildir only)
|
||||
# %g - Mail's GUID
|
||||
#
|
||||
# If you want UIDL compatibility with other POP3 servers, use:
|
||||
# UW's ipop3d : %08Xv%08Xu
|
||||
# Courier : %f or %v-%u (both might be used simultaneosly)
|
||||
# Cyrus (<= 2.1.3) : %u
|
||||
# Cyrus (>= 2.1.4) : %v.%u
|
||||
# Dovecot v0.99.x : %v.%u
|
||||
# tpop3d : %Mf
|
||||
#
|
||||
# Note that Outlook 2003 seems to have problems with %v.%u format which was
|
||||
# Dovecot's default, so if you're building a new server it would be a good
|
||||
# idea to change this. %08Xu%08Xv should be pretty fail-safe.
|
||||
#
|
||||
#pop3_uidl_format = %08Xu%08Xv
|
||||
|
||||
# Permanently save UIDLs sent to POP3 clients, so pop3_uidl_format changes
|
||||
# won't change those UIDLs. Currently this works only with Maildir.
|
||||
#pop3_save_uidl = no
|
||||
|
||||
# What to do about duplicate UIDLs if they exist?
|
||||
# allow: Show duplicates to clients.
|
||||
# rename: Append a temporary -2, -3, etc. counter after the UIDL.
|
||||
#pop3_uidl_duplicates = allow
|
||||
|
||||
# POP3 logout format string:
|
||||
# %i - total number of bytes read from client
|
||||
# %o - total number of bytes sent to client
|
||||
# %t - number of TOP commands
|
||||
# %p - number of bytes sent to client as a result of TOP command
|
||||
# %r - number of RETR commands
|
||||
# %b - number of bytes sent to client as a result of RETR command
|
||||
# %d - number of deleted messages
|
||||
# %m - number of messages (before deletion)
|
||||
# %s - mailbox size in bytes (before deletion)
|
||||
# %u - old/new UIDL hash. may help finding out if UIDLs changed unexpectedly
|
||||
#pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s
|
||||
|
||||
# Maximum number of POP3 connections allowed for a user from each IP address.
|
||||
# NOTE: The username is compared case-sensitively.
|
||||
#mail_max_userip_connections = 10
|
||||
|
||||
# Space separated list of plugins to load (default is global mail_plugins).
|
||||
#mail_plugins = $mail_plugins
|
||||
mail_plugins = quota
|
||||
|
||||
# Workarounds for various client bugs:
|
||||
# outlook-no-nuls:
|
||||
# Outlook and Outlook Express hang if mails contain NUL characters.
|
||||
# This setting replaces them with 0x80 character.
|
||||
# oe-ns-eoh:
|
||||
# Outlook Express and Netscape Mail breaks if end of headers-line is
|
||||
# missing. This option simply sends it if it's missing.
|
||||
# The list is space-separated.
|
||||
#pop3_client_workarounds =
|
||||
}
|
||||
84
install/common/dovecot/conf.d/90-quota.conf
Normal file
84
install/common/dovecot/conf.d/90-quota.conf
Normal file
@@ -0,0 +1,84 @@
|
||||
##
|
||||
## Quota configuration.
|
||||
##
|
||||
|
||||
# Note that you also have to enable quota plugin in mail_plugins setting.
|
||||
# <doc/wiki/Quota.txt>
|
||||
|
||||
##
|
||||
## Quota limits
|
||||
##
|
||||
|
||||
# Quota limits are set using "quota_rule" parameters. To get per-user quota
|
||||
# limits, you can set/override them by returning "quota_rule" extra field
|
||||
# from userdb. It's also possible to give mailbox-specific limits, for example
|
||||
# to give additional 100 MB when saving to Trash:
|
||||
|
||||
plugin {
|
||||
#quota_rule = *:storage=1G
|
||||
#quota_rule2 = Trash:storage=+100M
|
||||
|
||||
# LDA/LMTP allows saving the last mail to bring user from under quota to
|
||||
# over quota, if the quota doesn't grow too high. Default is to allow as
|
||||
# long as quota will stay under 10% above the limit. Also allowed e.g. 10M.
|
||||
#quota_grace = 10%%
|
||||
|
||||
# Quota plugin can also limit the maximum accepted mail size.
|
||||
#quota_max_mail_size = 100M
|
||||
}
|
||||
|
||||
##
|
||||
## Quota warnings
|
||||
##
|
||||
|
||||
# You can execute a given command when user exceeds a specified quota limit.
|
||||
# Each quota root has separate limits. Only the command for the first
|
||||
# exceeded limit is excecuted, so put the highest limit first.
|
||||
# The commands are executed via script service by connecting to the named
|
||||
# UNIX socket (quota-warning below).
|
||||
# Note that % needs to be escaped as %%, otherwise "% " expands to empty.
|
||||
|
||||
plugin {
|
||||
#quota_warning = storage=95%% quota-warning 95 %u
|
||||
#quota_warning2 = storage=80%% quota-warning 80 %u
|
||||
}
|
||||
|
||||
# Example quota-warning service. The unix listener's permissions should be
|
||||
# set in a way that mail processes can connect to it. Below example assumes
|
||||
# that mail processes run as vmail user. If you use mode=0666, all system users
|
||||
# can generate quota warnings to anyone.
|
||||
#service quota-warning {
|
||||
# executable = script /usr/local/bin/quota-warning.sh
|
||||
# user = dovecot
|
||||
# unix_listener quota-warning {
|
||||
# user = vmail
|
||||
# }
|
||||
#}
|
||||
|
||||
##
|
||||
## Quota backends
|
||||
##
|
||||
|
||||
# Multiple backends are supported:
|
||||
# dirsize: Find and sum all the files found from mail directory.
|
||||
# Extremely SLOW with Maildir. It'll eat your CPU and disk I/O.
|
||||
# dict: Keep quota stored in dictionary (eg. SQL)
|
||||
# maildir: Maildir++ quota
|
||||
# fs: Read-only support for filesystem quota
|
||||
|
||||
plugin {
|
||||
#quota = dirsize:User quota
|
||||
quota = maildir:User quota
|
||||
#quota = dict:User quota::proxy::quota
|
||||
#quota = fs:User quota
|
||||
}
|
||||
|
||||
# Multiple quota roots are also possible, for example this gives each user
|
||||
# their own 100MB quota and one shared 1GB quota within the domain:
|
||||
plugin {
|
||||
#quota = dict:user::proxy::quota
|
||||
#quota2 = dict:domain:%d:proxy::quota_domain
|
||||
#quota_rule = *:storage=102400
|
||||
#quota2_rule = *:storage=1048576
|
||||
}
|
||||
|
||||
9
install/common/dovecot/conf.d/auth-passwdfile.conf.ext
Normal file
9
install/common/dovecot/conf.d/auth-passwdfile.conf.ext
Normal file
@@ -0,0 +1,9 @@
|
||||
passdb {
|
||||
driver = passwd-file
|
||||
args = scheme=MD5-CRYPT username_format=%n /etc/exim4/domains/%d/passwd
|
||||
}
|
||||
|
||||
userdb {
|
||||
driver = passwd-file
|
||||
args = username_format=%n /etc/exim4/domains/%d/passwd
|
||||
}
|
||||
66
install/common/dovecot/dovecot.conf
Normal file
66
install/common/dovecot/dovecot.conf
Normal file
@@ -0,0 +1,66 @@
|
||||
protocols = imap pop3
|
||||
listen = *, ::
|
||||
base_dir = /run/dovecot/
|
||||
login_greeting = Mail Delivery Agent
|
||||
!include conf.d/*.conf
|
||||
!include_try conf.d/domains/*.conf
|
||||
|
||||
service stats {
|
||||
unix_listener stats-writer {
|
||||
group = mail
|
||||
mode = 0660
|
||||
user = dovecot
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
type = private
|
||||
separator = /
|
||||
inbox = yes
|
||||
list = yes
|
||||
|
||||
mailbox Archive {
|
||||
auto = subscribe
|
||||
special_use = \Archive
|
||||
}
|
||||
|
||||
mailbox Drafts {
|
||||
auto = subscribe
|
||||
special_use = \Drafts
|
||||
}
|
||||
|
||||
mailbox Trash {
|
||||
auto = subscribe
|
||||
special_use = \Trash
|
||||
}
|
||||
|
||||
mailbox "Deleted Messages" {
|
||||
auto = no
|
||||
special_use = \Trash
|
||||
}
|
||||
|
||||
mailbox Spam {
|
||||
auto = subscribe
|
||||
special_use = \Junk
|
||||
}
|
||||
|
||||
mailbox Junk {
|
||||
auto = no
|
||||
special_use = \Junk
|
||||
}
|
||||
|
||||
mailbox Sent {
|
||||
auto = subscribe
|
||||
special_use = \Sent
|
||||
}
|
||||
|
||||
mailbox "Sent Mail" {
|
||||
auto = no
|
||||
special_use = \Sent
|
||||
}
|
||||
|
||||
mailbox "Sent Messages" {
|
||||
auto = no
|
||||
special_use = \Sent
|
||||
}
|
||||
}
|
||||
88
install/common/dovecot/sieve/20-managesieve.conf
Normal file
88
install/common/dovecot/sieve/20-managesieve.conf
Normal file
@@ -0,0 +1,88 @@
|
||||
##
|
||||
## ManageSieve specific settings
|
||||
##
|
||||
|
||||
# Uncomment to enable managesieve protocol:
|
||||
protocols = $protocols sieve
|
||||
|
||||
# Service definitions
|
||||
|
||||
service managesieve-login {
|
||||
inet_listener sieve {
|
||||
port = 4190
|
||||
}
|
||||
|
||||
#inet_listener sieve_deprecated {
|
||||
# port = 2000
|
||||
#}
|
||||
|
||||
# Number of connections to handle before starting a new process. Typically
|
||||
# the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
|
||||
# is faster. <doc/wiki/LoginProcess.txt>
|
||||
#service_count = 1
|
||||
|
||||
# Number of processes to always keep waiting for more connections.
|
||||
#process_min_avail = 0
|
||||
|
||||
# If you set service_count=0, you probably need to grow this.
|
||||
#vsz_limit = 64M
|
||||
}
|
||||
|
||||
#service managesieve {
|
||||
# Max. number of ManageSieve processes (connections)
|
||||
#process_limit = 1024
|
||||
#}
|
||||
|
||||
# Service configuration
|
||||
|
||||
protocol sieve {
|
||||
# Maximum ManageSieve command line length in bytes. ManageSieve usually does
|
||||
# not involve overly long command lines, so this setting will not normally
|
||||
# need adjustment
|
||||
managesieve_max_line_length = 65536
|
||||
|
||||
# Maximum number of ManageSieve connections allowed for a user from each IP
|
||||
# address.
|
||||
# NOTE: The username is compared case-sensitively.
|
||||
#mail_max_userip_connections = 10
|
||||
|
||||
# Space separated list of plugins to load (none known to be useful so far).
|
||||
# Do NOT try to load IMAP plugins here.
|
||||
#mail_plugins =
|
||||
|
||||
# MANAGESIEVE logout format string:
|
||||
# %i - total number of bytes read from client
|
||||
# %o - total number of bytes sent to client
|
||||
# %{put_bytes} - Number of bytes saved using PUTSCRIPT command
|
||||
# %{put_count} - Number of scripts saved using PUTSCRIPT command
|
||||
# %{get_bytes} - Number of bytes read using GETCRIPT command
|
||||
# %{get_count} - Number of scripts read using GETSCRIPT command
|
||||
# %{get_bytes} - Number of bytes processed using CHECKSCRIPT command
|
||||
# %{get_count} - Number of scripts checked using CHECKSCRIPT command
|
||||
# %{deleted_count} - Number of scripts deleted using DELETESCRIPT command
|
||||
# %{renamed_count} - Number of scripts renamed using RENAMESCRIPT command
|
||||
#managesieve_logout_format = bytes=%i/%o
|
||||
|
||||
# To fool ManageSieve clients that are focused on CMU's timesieved you can
|
||||
# specify the IMPLEMENTATION capability that Dovecot reports to clients.
|
||||
# For example: 'Cyrus timsieved v2.2.13'
|
||||
managesieve_implementation_string = Dovecot Pigeonhole
|
||||
|
||||
# Explicitly specify the SIEVE and NOTIFY capability reported by the server
|
||||
# before login. If left unassigned these will be reported dynamically
|
||||
# according to what the Sieve interpreter supports by default (after login
|
||||
# this may differ depending on the user).
|
||||
#managesieve_sieve_capability =
|
||||
#managesieve_notify_capability =
|
||||
|
||||
# The maximum number of compile errors that are returned to the client upon
|
||||
# script upload or script verification.
|
||||
#managesieve_max_compile_errors = 5
|
||||
|
||||
# Refer to 90-sieve.conf for script quota configuration and configuration of
|
||||
# Sieve execution limits.
|
||||
|
||||
#log_path = /var/log/dovecot-sieve-errors.log
|
||||
#info_log_path = /var/log/dovecot-sieve.log
|
||||
|
||||
}
|
||||
44
install/common/dovecot/sieve/90-sieve-extprograms.conf
Normal file
44
install/common/dovecot/sieve/90-sieve-extprograms.conf
Normal file
@@ -0,0 +1,44 @@
|
||||
# Sieve Extprograms plugin configuration
|
||||
|
||||
# Don't forget to add the sieve_extprograms plugin to the sieve_plugins setting.
|
||||
# Also enable the extensions you need (one or more of vnd.dovecot.pipe,
|
||||
# vnd.dovecot.filter and vnd.dovecot.execute) by adding these to the
|
||||
# sieve_extensions or sieve_global_extensions settings. Restricting these
|
||||
# extensions to a global context using sieve_global_extensions is recommended.
|
||||
|
||||
plugin {
|
||||
|
||||
# The directory where the program sockets are located for the
|
||||
# vnd.dovecot.pipe, vnd.dovecot.filter and vnd.dovecot.execute extension
|
||||
# respectively. The name of each unix socket contained in that directory
|
||||
# directly maps to a program-name referenced from the Sieve script.
|
||||
#sieve_pipe_socket_dir = sieve-pipe
|
||||
#sieve_filter_socket_dir = sieve-filter
|
||||
#sieve_execute_socket_dir = sieve-execute
|
||||
|
||||
# The directory where the scripts are located for direct execution by the
|
||||
# vnd.dovecot.pipe, vnd.dovecot.filter and vnd.dovecot.execute extension
|
||||
# respectively. The name of each script contained in that directory
|
||||
# directly maps to a program-name referenced from the Sieve script.
|
||||
#sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe
|
||||
#sieve_filter_bin_dir = /usr/lib/dovecot/sieve-filter
|
||||
#sieve_execute_bin_dir = /usr/lib/dovecot/sieve-execute
|
||||
|
||||
}
|
||||
|
||||
# An example program service called 'do-something' to pipe messages to
|
||||
#service do-something {
|
||||
# Define the executed script as parameter to the sieve service
|
||||
#executable = script /usr/lib/dovecot/sieve-pipe/do-something.sh
|
||||
|
||||
# Use some unprivileged user for executing the program
|
||||
#user = dovenull
|
||||
|
||||
# The unix socket located in the sieve_pipe_socket_dir (as defined in the
|
||||
# plugin {} section above)
|
||||
#unix_listener sieve-pipe/do-something {
|
||||
# LDA/LMTP must have access
|
||||
# user = vmail
|
||||
# mode = 0600
|
||||
#}
|
||||
#}
|
||||
211
install/common/dovecot/sieve/90-sieve.conf
Normal file
211
install/common/dovecot/sieve/90-sieve.conf
Normal file
@@ -0,0 +1,211 @@
|
||||
##
|
||||
## Settings for the Sieve interpreter
|
||||
##
|
||||
|
||||
# Do not forget to enable the Sieve plugin in 15-lda.conf and 20-lmtp.conf
|
||||
# by adding it to the respective mail_plugins= settings.
|
||||
|
||||
# The Sieve interpreter can retrieve Sieve scripts from several types of
|
||||
# locations. The default `file' location type is a local filesystem path
|
||||
# pointing to a Sieve script file or a directory containing multiple Sieve
|
||||
# script files. More complex setups can use other location types such as
|
||||
# `ldap' or `dict' to fetch Sieve scripts from remote databases.
|
||||
#
|
||||
# All settings that specify the location of one ore more Sieve scripts accept
|
||||
# the following syntax:
|
||||
#
|
||||
# location = [<type>:]path[;<option>[=<value>][;...]]
|
||||
#
|
||||
# If the type prefix is omitted, the script location type is 'file' and the
|
||||
# location is interpreted as a local filesystem path pointing to a Sieve script
|
||||
# file or directory. Refer to Pigeonhole wiki or INSTALL file for more
|
||||
# information.
|
||||
|
||||
plugin {
|
||||
# The location of the user's main Sieve script or script storage. The LDA
|
||||
# Sieve plugin uses this to find the active script for Sieve filtering at
|
||||
# delivery. The "include" extension uses this location for retrieving
|
||||
# :personal" scripts. This is also where the ManageSieve service will store
|
||||
# the user's scripts, if supported.
|
||||
#
|
||||
# Currently only the 'file:' location type supports ManageSieve operation.
|
||||
# Other location types like 'dict:' and 'ldap:' can currently only
|
||||
# be used as a read-only script source ().
|
||||
#
|
||||
# For the 'file:' type: use the ';active=' parameter to specify where the
|
||||
# active script symlink is located.
|
||||
# For other types: use the ';name=' parameter to specify the name of the
|
||||
# default/active script.
|
||||
#sieve = file:~/sieve;active=~/.dovecot.sieve
|
||||
sieve = file:~/mail/%d/%n/sieve;active=~/mail/%d/%n/dovecot.sieve
|
||||
|
||||
# The default Sieve script when the user has none. This is the location of a
|
||||
# global sieve script file, which gets executed ONLY if user's personal Sieve
|
||||
# script doesn't exist. Be sure to pre-compile this script manually using the
|
||||
# sievec command line tool if the binary is not stored in a global location.
|
||||
# --> See sieve_before for executing scripts before the user's personal
|
||||
# script.
|
||||
#sieve_default = /var/lib/dovecot/sieve/default.sieve
|
||||
|
||||
# The name by which the default Sieve script (as configured by the
|
||||
# sieve_default setting) is visible to the user through ManageSieve.
|
||||
#sieve_default_name =
|
||||
|
||||
# Location for ":global" include scripts as used by the "include" extension.
|
||||
#sieve_global =
|
||||
|
||||
# The location of a Sieve script that is run for any message that is about to
|
||||
# be discarded; i.e., it is not delivered anywhere by the normal Sieve
|
||||
# execution. This only happens when the "implicit keep" is canceled, by e.g.
|
||||
# the "discard" action, and no actions that deliver the message are executed.
|
||||
# This "discard script" can prevent discarding the message, by executing
|
||||
# alternative actions. If the discard script does nothing, the message is
|
||||
# still discarded as it would be when no discard script is configured.
|
||||
#sieve_discard =
|
||||
|
||||
# Location Sieve of scripts that need to be executed before the user's
|
||||
# personal script. If a 'file' location path points to a directory, all the
|
||||
# Sieve scripts contained therein (with the proper `.sieve' extension) are
|
||||
# executed. The order of execution within that directory is determined by the
|
||||
# file names, using a normal 8bit per-character comparison.
|
||||
#
|
||||
# Multiple script locations can be specified by appending an increasing number
|
||||
# to the setting name. The Sieve scripts found from these locations are added
|
||||
# to the script execution sequence in the specified order. Reading the
|
||||
# numbered sieve_before settings stops at the first missing setting, so no
|
||||
# numbers may be skipped.
|
||||
#sieve_before = /var/lib/dovecot/sieve.d/
|
||||
#sieve_before2 = ldap:/etc/sieve-ldap.conf;name=ldap-domain
|
||||
#sieve_before3 = (etc...)
|
||||
|
||||
# Identical to sieve_before, only the specified scripts are executed after the
|
||||
# user's script (only when keep is still in effect!). Multiple script
|
||||
# locations can be specified by appending an increasing number.
|
||||
#sieve_after =
|
||||
#sieve_after2 =
|
||||
#sieve_after2 = (etc...)
|
||||
|
||||
# Which Sieve language extensions are available to users. By default, all
|
||||
# supported extensions are available, except for deprecated extensions or
|
||||
# those that are still under development. Some system administrators may want
|
||||
# to disable certain Sieve extensions or enable those that are not available
|
||||
# by default. This setting can use '+' and '-' to specify differences relative
|
||||
# to the default. For example `sieve_extensions = +imapflags' will enable the
|
||||
# deprecated imapflags extension in addition to all extensions were already
|
||||
# enabled by default.
|
||||
sieve_extensions = +notify +imapflags
|
||||
|
||||
# Which Sieve language extensions are ONLY available in global scripts. This
|
||||
# can be used to restrict the use of certain Sieve extensions to administrator
|
||||
# control, for instance when these extensions can cause security concerns.
|
||||
# This setting has higher precedence than the `sieve_extensions' setting
|
||||
# (above), meaning that the extensions enabled with this setting are never
|
||||
# available to the user's personal script no matter what is specified for the
|
||||
# `sieve_extensions' setting. The syntax of this setting is similar to the
|
||||
# `sieve_extensions' setting, with the difference that extensions are
|
||||
# enabled or disabled for exclusive use in global scripts. Currently, no
|
||||
# extensions are marked as such by default.
|
||||
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
|
||||
|
||||
# The Pigeonhole Sieve interpreter can have plugins of its own. Using this
|
||||
# setting, the used plugins can be specified. Check the Dovecot wiki
|
||||
# (wiki2.dovecot.org) or the pigeonhole website
|
||||
# (http://pigeonhole.dovecot.org) for available plugins.
|
||||
# The sieve_extprograms plugin is included in this release.
|
||||
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||
|
||||
sieve_pipe_bin_dir = /etc/dovecot/sieve
|
||||
|
||||
# The maximum size of a Sieve script. The compiler will refuse to compile any
|
||||
# script larger than this limit. If set to 0, no limit on the script size is
|
||||
# enforced.
|
||||
#sieve_max_script_size = 1M
|
||||
|
||||
# The maximum number of actions that can be performed during a single script
|
||||
# execution. If set to 0, no limit on the total number of actions is enforced.
|
||||
#sieve_max_actions = 32
|
||||
|
||||
# The maximum number of redirect actions that can be performed during a single
|
||||
# script execution. If set to 0, no redirect actions are allowed.
|
||||
#sieve_max_redirects = 4
|
||||
|
||||
# The maximum number of personal Sieve scripts a single user can have. If set
|
||||
# to 0, no limit on the number of scripts is enforced.
|
||||
# (Currently only relevant for ManageSieve)
|
||||
#sieve_quota_max_scripts = 0
|
||||
|
||||
# The maximum amount of disk storage a single user's scripts may occupy. If
|
||||
# set to 0, no limit on the used amount of disk storage is enforced.
|
||||
# (Currently only relevant for ManageSieve)
|
||||
#sieve_quota_max_storage = 0
|
||||
|
||||
# The primary e-mail address for the user. This is used as a default when no
|
||||
# other appropriate address is available for sending messages. If this setting
|
||||
# is not configured, either the postmaster or null "<>" address is used as a
|
||||
# sender, depending on the action involved. This setting is important when
|
||||
# there is no message envelope to extract addresses from, such as when the
|
||||
# script is executed in IMAP.
|
||||
#sieve_user_email =
|
||||
|
||||
# The path to the file where the user log is written. If not configured, a
|
||||
# default location is used. If the main user's personal Sieve (as configured
|
||||
# with sieve=) is a file, the logfile is set to <filename>.log by default. If
|
||||
# it is not a file, the default user log file is ~/.dovecot.sieve.log.
|
||||
#sieve_user_log =
|
||||
|
||||
# Specifies what envelope sender address is used for redirected messages.
|
||||
# The following values are supported for this setting:
|
||||
#
|
||||
# "sender" - The sender address is used (default).
|
||||
# "recipient" - The final recipient address is used.
|
||||
# "orig_recipient" - The original recipient is used.
|
||||
# "user_email" - The user's primary address is used. This is
|
||||
# configured with the "sieve_user_email" setting. If
|
||||
# that setting is unconfigured, "user_mail" is equal to
|
||||
# "recipient".
|
||||
# "postmaster" - The postmaster_address configured for the LDA.
|
||||
# "<user@domain>" - Redirected messages are always sent from user@domain.
|
||||
# The angle brackets are mandatory. The null "<>" address
|
||||
# is also supported.
|
||||
#
|
||||
# This setting is ignored when the envelope sender is "<>". In that case the
|
||||
# sender of the redirected message is also always "<>".
|
||||
#sieve_redirect_envelope_from = sender
|
||||
|
||||
## TRACE DEBUGGING
|
||||
# Trace debugging provides detailed insight in the operations performed by
|
||||
# the Sieve script. These settings apply to both the LDA Sieve plugin and the
|
||||
# IMAPSIEVE plugin.
|
||||
#
|
||||
# WARNING: On a busy server, this functionality can quickly fill up the trace
|
||||
# directory with a lot of trace files. Enable this only temporarily and as
|
||||
# selective as possible.
|
||||
|
||||
# The directory where trace files are written. Trace debugging is disabled if
|
||||
# this setting is not configured or if the directory does not exist. If the
|
||||
# path is relative or it starts with "~/" it is interpreted relative to the
|
||||
# current user's home directory.
|
||||
#sieve_trace_dir =
|
||||
|
||||
# The verbosity level of the trace messages. Trace debugging is disabled if
|
||||
# this setting is not configured. Possible values are:
|
||||
#
|
||||
# "actions" - Only print executed action commands, like keep,
|
||||
# fileinto, reject and redirect.
|
||||
# "commands" - Print any executed command, excluding test commands.
|
||||
# "tests" - Print all executed commands and performed tests.
|
||||
# "matching" - Print all executed commands, performed tests and the
|
||||
# values matched in those tests.
|
||||
#sieve_trace_level =
|
||||
|
||||
# Enables highly verbose debugging messages that are usually only useful for
|
||||
# developers.
|
||||
#sieve_trace_debug = no
|
||||
|
||||
# Enables showing byte code addresses in the trace output, rather than only
|
||||
# the source line numbers.
|
||||
#sieve_trace_addresses = no
|
||||
|
||||
# This setting determines whether vacation messages are sent with the SMTP MAIL FROM envelope address set to the recipient address of the Sieve script owner.
|
||||
sieve_vacation_send_from_recipient = yes
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Filegator\Services\Archiver\Adapters;
|
||||
|
||||
use Filegator\Container\Container;
|
||||
use Filegator\Services\Archiver\ArchiverInterface;
|
||||
use Filegator\Services\Service;
|
||||
use Filegator\Services\Storage\Filesystem as Storage;
|
||||
use Filegator\Services\Tmpfs\TmpfsInterface;
|
||||
use function Hestiacp\quoteshellarg\quoteshellarg;
|
||||
|
||||
class HestiaZipArchiver extends ZipArchiver implements Service, ArchiverInterface {
|
||||
protected $container;
|
||||
|
||||
public function __construct(TmpfsInterface $tmpfs, Container $container) {
|
||||
$this->tmpfs = $tmpfs;
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function uncompress(string $source, string $destination, Storage $storage) {
|
||||
$auth = $this->container->get("Filegator\Services\Auth\AuthInterface");
|
||||
|
||||
$v_user = basename($auth->user()->getUsername());
|
||||
|
||||
if (!strlen($v_user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strpos($source, "/home") === false) {
|
||||
$source = "/home/$v_user/" . $source;
|
||||
}
|
||||
|
||||
if (strpos($destination, "/home") === false) {
|
||||
$destination = "/home/$v_user/" . $destination;
|
||||
}
|
||||
|
||||
exec(
|
||||
"sudo /usr/local/hestia/bin/v-extract-fs-archive " .
|
||||
quoteshellarg($v_user) .
|
||||
" " .
|
||||
quoteshellarg($source) .
|
||||
" " .
|
||||
quoteshellarg($destination),
|
||||
$output,
|
||||
$return_var,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the FileGator package.
|
||||
*
|
||||
* (c) Milos Stojanovic <alcalbg@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
*/
|
||||
|
||||
namespace Filegator\Services\Auth\Adapters;
|
||||
|
||||
use Filegator\Services\Auth\AuthInterface;
|
||||
use Filegator\Services\Auth\User;
|
||||
use Filegator\Services\Auth\UsersCollection;
|
||||
use Filegator\Services\Service;
|
||||
use function Hestiacp\quoteshellarg\quoteshellarg;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class HestiaAuth implements Service, AuthInterface {
|
||||
protected $permissions = [];
|
||||
|
||||
protected $private_repos = false;
|
||||
|
||||
protected $hestia_user = "";
|
||||
|
||||
public function init(array $config = []) {
|
||||
if (isset($_SESSION["user"])) {
|
||||
$v_user = $_SESSION["user"];
|
||||
}
|
||||
if (!empty($_SESSION["look"])) {
|
||||
if (isset($_SESSION["look"]) && $_SESSION["userContext"] === "admin") {
|
||||
$v_user = $_SESSION["look"];
|
||||
}
|
||||
if (
|
||||
$_SESSION["look"] == "admin" &&
|
||||
$_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes"
|
||||
) {
|
||||
// Go away do not login
|
||||
header("Location: /");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
$this->hestia_user = $v_user;
|
||||
$this->permissions = isset($config["permissions"]) ? (array) $config["permissions"] : [];
|
||||
$this->private_repos = isset($config["private_repos"])
|
||||
? (bool) $config["private_repos"]
|
||||
: false;
|
||||
}
|
||||
|
||||
public function user(): ?User {
|
||||
$cmd = "/usr/bin/sudo /usr/local/hestia/bin/v-list-user";
|
||||
exec($cmd . " " . quoteshellarg($this->hestia_user) . " json", $output, $return_var);
|
||||
|
||||
if ($return_var == 0) {
|
||||
$data = json_decode(implode("", $output), true);
|
||||
$hestia_user_info = $data[$this->hestia_user];
|
||||
return $this->transformUser($hestia_user_info);
|
||||
}
|
||||
|
||||
return $this->getGuest();
|
||||
}
|
||||
|
||||
public function transformUser($hstuser): User {
|
||||
$user = new User();
|
||||
$user->setUsername($this->hestia_user);
|
||||
$user->setName($this->hestia_user . " (" . $hstuser["NAME"] . ")");
|
||||
$user->setRole("user");
|
||||
$user->setPermissions($this->permissions);
|
||||
$user->setHomedir("/");
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function authenticate($username, $password): bool {
|
||||
# Auth is handled by Hestia
|
||||
return false;
|
||||
}
|
||||
|
||||
public function forget() {
|
||||
// Logout return to Hestia
|
||||
return $this->getGuest();
|
||||
}
|
||||
|
||||
public function store(User $user) {
|
||||
return null; // not used
|
||||
}
|
||||
|
||||
public function update($username, User $user, $password = ""): User {
|
||||
// Password change is handled by Hestia
|
||||
return $this->user();
|
||||
}
|
||||
|
||||
public function add(User $user, $password): User {
|
||||
return new User(); // not used
|
||||
}
|
||||
|
||||
public function delete(User $user) {
|
||||
return true; // not used
|
||||
}
|
||||
|
||||
public function find($username): ?User {
|
||||
return null; // not used
|
||||
}
|
||||
|
||||
public function allUsers(): UsersCollection {
|
||||
return new UsersCollection(); // not used
|
||||
}
|
||||
|
||||
public function getGuest(): User {
|
||||
$guest = new User();
|
||||
|
||||
$guest->setUsername("guest");
|
||||
$guest->setName("Guest");
|
||||
$guest->setRole("guest");
|
||||
$guest->setHomedir("/");
|
||||
$guest->setPermissions([]);
|
||||
|
||||
return $guest;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the FileGator package.
|
||||
*
|
||||
* (c) Milos Stojanovic <alcalbg@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
*/
|
||||
|
||||
namespace Filegator\Services\Session\Adapters;
|
||||
|
||||
use Filegator\Kernel\Request;
|
||||
use Filegator\Services\Service;
|
||||
use Filegator\Services\Session\Session;
|
||||
use Filegator\Services\Session\SessionStorageInterface;
|
||||
|
||||
class SessionStorage implements Service, SessionStorageInterface {
|
||||
protected $request;
|
||||
|
||||
protected $config;
|
||||
|
||||
public function __construct(Request $request) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function init(array $config = []) {
|
||||
// we don't have a previous session attached
|
||||
if (!$this->getSession()) {
|
||||
$handler = $config["handler"];
|
||||
$session = new Session($handler());
|
||||
//$session->setName('filegator');
|
||||
$this->setSession($session);
|
||||
}
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$this->getSession()->save();
|
||||
}
|
||||
|
||||
public function set(string $key, $data) {
|
||||
return $this->getSession()->set($key, $data);
|
||||
}
|
||||
|
||||
public function get(string $key, $default = null) {
|
||||
return $this->getSession() ? $this->getSession()->get($key, $default) : $default;
|
||||
}
|
||||
|
||||
public function invalidate() {
|
||||
if (!$this->getSession()->isStarted()) {
|
||||
$this->getSession()->start();
|
||||
}
|
||||
|
||||
$this->getSession()->invalidate();
|
||||
}
|
||||
|
||||
private function setSession(Session $session) {
|
||||
return $this->request->setSession($session);
|
||||
}
|
||||
|
||||
private function getSession(): ?Session {
|
||||
return $this->request->getSession();
|
||||
}
|
||||
}
|
||||
47
install/common/filegator/composer.json
Normal file
47
install/common/filegator/composer.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "filegator/filegator",
|
||||
"description": "Filegator",
|
||||
"license": "MIT",
|
||||
"type": "project",
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.2.5"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2",
|
||||
"monolog/monolog": "^1.24",
|
||||
"nikic/fast-route": "^1.3",
|
||||
"symfony/security-csrf": "^4.4",
|
||||
"symfony/http-foundation": "^4.4",
|
||||
"dibi/dibi": "^4.1",
|
||||
"php-di/php-di": "^6.0",
|
||||
"rakit/validation": "^1.1",
|
||||
"league/flysystem": "^1.1",
|
||||
"league/flysystem-ziparchive": "^1.0",
|
||||
"league/flysystem-sftp": "^1.0",
|
||||
"hestiacp/phpquoteshellarg": "^1.0"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Milos Stojanovic",
|
||||
"email": "alcalbg@gmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Filegator\\": "backend"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/backend/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"symfony/var-dumper": "^4.4",
|
||||
"league/flysystem-memory": "^1.0",
|
||||
"phpstan/phpstan": "^0.11.8"
|
||||
}
|
||||
}
|
||||
4771
install/common/filegator/composer.lock
generated
Normal file
4771
install/common/filegator/composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
177
install/common/filegator/configuration.php
Normal file
177
install/common/filegator/configuration.php
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
use function Hestiacp\quoteshellarg\quoteshellarg;
|
||||
|
||||
$dist_config = require __DIR__ . "/configuration_sample.php";
|
||||
|
||||
$dist_config["public_path"] = "/fm/";
|
||||
$dist_config["frontend_config"]["app_name"] = "File Manager - Hestia Control Panel";
|
||||
$dist_config["frontend_config"]["logo"] = "../images/logo.svg";
|
||||
$dist_config["frontend_config"]["editable"] = [
|
||||
".txt",
|
||||
".css",
|
||||
".js",
|
||||
".json",
|
||||
".ts",
|
||||
".html",
|
||||
".php",
|
||||
".py",
|
||||
".yml",
|
||||
".xml",
|
||||
".md",
|
||||
".log",
|
||||
".csv",
|
||||
".conf",
|
||||
".config",
|
||||
".ini",
|
||||
".scss",
|
||||
".service",
|
||||
".sh",
|
||||
".env",
|
||||
".example",
|
||||
".htaccess",
|
||||
".twig",
|
||||
".tpl",
|
||||
".yaml",
|
||||
];
|
||||
$dist_config["frontend_config"]["guest_redirection"] = "/login/";
|
||||
$dist_config["frontend_config"]["upload_max_size"] = 1024 * 1024 * 1024;
|
||||
|
||||
$dist_config["services"]["Filegator\Services\Storage\Filesystem"]["config"][
|
||||
"adapter"
|
||||
] = function () {
|
||||
if (!empty($_SESSION["INACTIVE_SESSION_TIMEOUT"])) {
|
||||
if ($_SESSION["INACTIVE_SESSION_TIMEOUT"] * 60 + $_SESSION["LAST_ACTIVITY"] < time()) {
|
||||
$v_user = quoteshellarg($_SESSION["user"]);
|
||||
$v_session_id = quoteshellarg($_SESSION["token"]);
|
||||
exec(
|
||||
"/usr/local/hestia/bin/v-log-user-logout " . $v_user . " " . $v_session_id,
|
||||
$output,
|
||||
$return_var,
|
||||
);
|
||||
unset($_SESSION);
|
||||
session_unset();
|
||||
session_destroy();
|
||||
session_start();
|
||||
echo '<meta http-equiv="refresh" content="0; url=/">';
|
||||
exit();
|
||||
} else {
|
||||
$_SESSION["LAST_ACTIVITY"] = time();
|
||||
}
|
||||
} else {
|
||||
echo '<meta http-equiv="refresh" content="0; url=/">';
|
||||
}
|
||||
if (isset($_SESSION["user"])) {
|
||||
$v_user = $_SESSION["user"];
|
||||
}
|
||||
if (!empty($_SESSION["look"])) {
|
||||
if (isset($_SESSION["look"]) && $_SESSION["userContext"] === "admin") {
|
||||
$v_user = $_SESSION["look"];
|
||||
}
|
||||
if (
|
||||
isset($_SESSION["look"]) &&
|
||||
$_SESSION["look"] == "admin" &&
|
||||
$_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes"
|
||||
) {
|
||||
header("Location: /");
|
||||
}
|
||||
}
|
||||
# Create filemanager sftp key if missing and trash it after 30 min
|
||||
if (!file_exists("/home/" . basename($v_user) . "/.ssh/hst-filemanager-key")) {
|
||||
exec(
|
||||
"sudo /usr/local/hestia/bin/v-add-user-sftp-key " .
|
||||
quoteshellarg(basename($v_user)) .
|
||||
" 30",
|
||||
$output,
|
||||
$return_var,
|
||||
);
|
||||
// filemanager also requires .ssh chmod o+x ... hopefully we can improve it to g+x or u+x someday
|
||||
// current minimum for filemanager: chmod 0701 .ssh
|
||||
shell_exec("sudo chmod o+x " . quoteshellarg("/home/" . basename($v_user) . "/.ssh"));
|
||||
}
|
||||
|
||||
if (!isset($_SESSION["SFTP_PORT"])) {
|
||||
exec("sudo /usr/local/hestia/bin/v-list-sys-sshd-port json", $output, $result);
|
||||
$port = json_decode(implode("", $output));
|
||||
if (is_numeric($port[0]) && $port[0] > 0) {
|
||||
$_SESSION["SFTP_PORT"] = $port[0];
|
||||
} elseif (
|
||||
preg_match('/^\s*Port\s+(\d+)$/im', file_get_contents("/etc/ssh/sshd_config"), $matches)
|
||||
) {
|
||||
$_SESSION["SFTP_PORT"] = $matches[1] ?? 22;
|
||||
} else {
|
||||
$_SESSION["SFTP_PORT"] = 22;
|
||||
}
|
||||
}
|
||||
|
||||
preg_match(
|
||||
'/(Hestia SFTP Chroot\nMatch User)(.*)/i',
|
||||
file_get_contents("/etc/ssh/sshd_config"),
|
||||
$matches,
|
||||
);
|
||||
$user_list = explode(",", $matches[2]);
|
||||
if (in_array($v_user, $user_list)) {
|
||||
$root = "/";
|
||||
} else {
|
||||
$root = "/home/" . $v_user;
|
||||
}
|
||||
|
||||
return new \League\Flysystem\Sftp\SftpAdapter([
|
||||
"host" => "127.0.0.1",
|
||||
"port" => intval($_SESSION["SFTP_PORT"]),
|
||||
"username" => basename($v_user),
|
||||
"privateKey" => "/home/" . basename($v_user) . "/.ssh/hst-filemanager-key",
|
||||
"root" => $root,
|
||||
"timeout" => 10,
|
||||
"directoryPerm" => 0755,
|
||||
]);
|
||||
};
|
||||
|
||||
$dist_config["services"]["Filegator\Services\Archiver\ArchiverInterface"] = [
|
||||
"handler" => "\Filegator\Services\Archiver\Adapters\HestiaZipArchiver",
|
||||
"config" => [],
|
||||
];
|
||||
|
||||
$dist_config["services"]["Filegator\Services\Auth\AuthInterface"] = [
|
||||
"handler" => "\Filegator\Services\Auth\Adapters\HestiaAuth",
|
||||
"config" => [
|
||||
"permissions" => ["read", "write", "upload", "download", "batchdownload", "zip"],
|
||||
"private_repos" => false,
|
||||
],
|
||||
];
|
||||
|
||||
$dist_config["services"]["Filegator\Services\View\ViewInterface"]["config"] = [
|
||||
"add_to_head" => '
|
||||
<style>
|
||||
.logo {
|
||||
width: 46px;
|
||||
}
|
||||
</style>
|
||||
',
|
||||
"add_to_body" => '
|
||||
<script>
|
||||
var checkVueLoaded = setInterval(function() {
|
||||
if (document.getElementsByClassName("container").length) {
|
||||
clearInterval(checkVueLoaded);
|
||||
var navProfile = document.getElementsByClassName("navbar-item profile")[0]; navProfile.replaceWith(navProfile.cloneNode(true))
|
||||
document.getElementsByClassName("navbar-item logout")[0].text="Exit to Control Panel \u00BB";
|
||||
div = document.getElementsByClassName("container")[0];
|
||||
callback = function(){
|
||||
if (document.getElementsByClassName("navbar-item logout")[0]){
|
||||
if ( document.getElementsByClassName("navbar-item logout")[0].text != "Exit to Control Panel \u00BB" ){
|
||||
var navProfile = document.getElementsByClassName("navbar-item profile")[0]; navProfile.replaceWith(navProfile.cloneNode(true))
|
||||
document.getElementsByClassName("navbar-item logout")[0].text="Exit to Control Panel \u00BB";
|
||||
}
|
||||
}
|
||||
}
|
||||
config = {
|
||||
childList:true,
|
||||
subtree:true
|
||||
}
|
||||
observer = new MutationObserver(callback);
|
||||
observer.observe(div,config);
|
||||
}
|
||||
}, 200);
|
||||
</script>',
|
||||
];
|
||||
|
||||
return $dist_config;
|
||||
35
install/common/firewall/ipset/blacklist.sh
Executable file
35
install/common/firewall/ipset/blacklist.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script and blacklist urls partially taken from:
|
||||
# https://github.com/trick77/ipset-blacklist/blob/master/ipset-blacklist.conf
|
||||
#
|
||||
|
||||
BLACKLISTS=(
|
||||
"https://www.projecthoneypot.org/list_of_ips.php?t=d&rss=1" # Project Honey Pot Directory of Dictionary Attacker IPs
|
||||
"https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.1.1.1" # TOR Exit Nodes
|
||||
"https://www.maxmind.com/en/high-risk-ip-sample-list" # MaxMind GeoIP Anonymous Proxies
|
||||
"https://danger.rulez.sk/projects/bruteforceblocker/blist.php" # BruteForceBlocker IP List
|
||||
"https://www.spamhaus.org/drop/drop.lasso" # Spamhaus Don't Route Or Peer List (DROP)
|
||||
"https://cinsscore.com/list/ci-badguys.txt" # C.I. Army Malicious IP List
|
||||
"https://lists.blocklist.de/lists/all.txt" # blocklist.de attackers
|
||||
"https://blocklist.greensnow.co/greensnow.txt" # GreenSnow
|
||||
"https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset" # Firehol Level 1
|
||||
"https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/stopforumspam_7d.ipset" # Stopforumspam via Firehol
|
||||
)
|
||||
|
||||
IP_BLACKLIST_TMP=$(mktemp)
|
||||
for i in "${BLACKLISTS[@]}"; do
|
||||
IP_TMP=$(mktemp)
|
||||
((HTTP_RC = $(curl -L --connect-timeout 10 --max-time 10 -o "$IP_TMP" -s -w "%{http_code}" "$i")))
|
||||
if ((HTTP_RC == 200 || HTTP_RC == 302 || HTTP_RC == 0)); then # "0" because file:/// returns 000
|
||||
command grep -Po '^(?:\d{1,3}\.){3}\d{1,3}(?:/\d{1,2})?' "$IP_TMP" | sed -r 's/^0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+)\.0*([0-9]+)$/\1.\2.\3.\4/' >> "$IP_BLACKLIST_TMP"
|
||||
elif ((HTTP_RC == 503)); then
|
||||
echo >&2 -e "\\nUnavailable (${HTTP_RC}): $i"
|
||||
else
|
||||
echo >&2 -e "\\nWarning: curl returned HTTP response code $HTTP_RC for URL $i"
|
||||
fi
|
||||
rm -f "$IP_TMP"
|
||||
done
|
||||
|
||||
sed -r -e '/^(0\.0\.0\.0|10\.|127\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.|192\.168\.|22[4-9]\.|23[0-9]\.)/d' "$IP_BLACKLIST_TMP" | sort -n | sort -mu
|
||||
rm -f "$IP_BLACKLIST_TMP"
|
||||
10
install/common/firewall/rules.conf
Normal file
10
install/common/firewall/rules.conf
Normal file
@@ -0,0 +1,10 @@
|
||||
RULE='1' ACTION='ACCEPT' PROTOCOL='ICMP' PORT='0' IP='0.0.0.0/0' COMMENT='PING' SUSPENDED='no' TIME='17:13:48' DATE='2014-09-16'
|
||||
RULE='2' ACTION='ACCEPT' PROTOCOL='TCP' PORT='8083' IP='0.0.0.0/0' COMMENT='HESTIA' SUSPENDED='no' TIME='07:40:16' DATE='2014-05-25'
|
||||
RULE='3' ACTION='ACCEPT' PROTOCOL='TCP' PORT='143,993' IP='0.0.0.0/0' COMMENT='IMAP' SUSPENDED='no' TIME='07:40:16' DATE='2014-05-25'
|
||||
RULE='4' ACTION='ACCEPT' PROTOCOL='TCP' PORT='110,995' IP='0.0.0.0/0' COMMENT='POP3' SUSPENDED='no' TIME='07:40:16' DATE='2014-05-25'
|
||||
RULE='5' ACTION='ACCEPT' PROTOCOL='TCP' PORT='25,465,587' IP='0.0.0.0/0' COMMENT='SMTP' SUSPENDED='no' TIME='21:47:04' DATE='2018-11-07'
|
||||
RULE='6' ACTION='ACCEPT' PROTOCOL='TCP' PORT='53' IP='0.0.0.0/0' COMMENT='DNS' SUSPENDED='no' TIME='07:40:16' DATE='2014-05-25'
|
||||
RULE='7' ACTION='ACCEPT' PROTOCOL='UDP' PORT='53' IP='0.0.0.0/0' COMMENT='DNS' SUSPENDED='no' TIME='07:40:16' DATE='2014-05-25'
|
||||
RULE='8' ACTION='ACCEPT' PROTOCOL='TCP' PORT='21,12000-12100' IP='0.0.0.0/0' COMMENT='FTP' SUSPENDED='no' TIME='07:40:16' DATE='2014-05-25'
|
||||
RULE='9' ACTION='ACCEPT' PROTOCOL='TCP' PORT='80,443' IP='0.0.0.0/0' COMMENT='WEB' SUSPENDED='no' TIME='17:04:27' DATE='2014-09-24'
|
||||
RULE='10' ACTION='ACCEPT' PROTOCOL='TCP' PORT='22' IP='0.0.0.0/0' COMMENT='SSH' SUSPENDED='no' TIME='17:14:41' DATE='2014-09-16'
|
||||
20
install/common/packages/default.pkg
Normal file
20
install/common/packages/default.pkg
Normal file
@@ -0,0 +1,20 @@
|
||||
WEB_TEMPLATE='default'
|
||||
PROXY_TEMPLATE='default'
|
||||
BACKEND_TEMPLATE='default'
|
||||
DNS_TEMPLATE='default'
|
||||
WEB_DOMAINS='unlimited'
|
||||
WEB_ALIASES='unlimited'
|
||||
DNS_DOMAINS='unlimited'
|
||||
DNS_RECORDS='unlimited'
|
||||
MAIL_DOMAINS='unlimited'
|
||||
MAIL_ACCOUNTS='unlimited'
|
||||
RATE_LIMIT='200'
|
||||
DATABASES='unlimited'
|
||||
CRON_JOBS='unlimited'
|
||||
DISK_QUOTA='unlimited'
|
||||
BANDWIDTH='unlimited'
|
||||
NS='ns1.domain.tld,ns2.domain.tld'
|
||||
SHELL='nologin'
|
||||
BACKUPS='1'
|
||||
TIME='18:00:00'
|
||||
DATE='2019-01-15'
|
||||
20
install/common/packages/system.pkg
Normal file
20
install/common/packages/system.pkg
Normal file
@@ -0,0 +1,20 @@
|
||||
WEB_TEMPLATE='default'
|
||||
PROXY_TEMPLATE='default'
|
||||
BACKEND_TEMPLATE='default'
|
||||
DNS_TEMPLATE='default'
|
||||
WEB_DOMAINS='1'
|
||||
WEB_ALIASES='1'
|
||||
DNS_DOMAINS='1'
|
||||
DNS_RECORDS='unlimited'
|
||||
MAIL_DOMAINS='1'
|
||||
MAIL_ACCOUNTS='1'
|
||||
RATE_LIMIT='200'
|
||||
DATABASES='0'
|
||||
CRON_JOBS='unlimited'
|
||||
DISK_QUOTA='unlimited'
|
||||
BANDWIDTH='unlimited'
|
||||
NS='ns1.domain.tld,ns2.domain.tld'
|
||||
SHELL='nologin'
|
||||
BACKUPS='1'
|
||||
TIME='00:00:00'
|
||||
DATE='2022-01-20'
|
||||
36
install/common/phpmyadmin/config.inc.php
Normal file
36
install/common/phpmyadmin/config.inc.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/* PHPmyadmin config for Hestia 1.3.3 > */
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* All directives are explained in documentation in the doc/ folder
|
||||
* or at <https://docs.phpmyadmin.net/>.
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This is needed for cookie based authentication to encrypt password in
|
||||
* cookie. Needs to be 32 chars long.
|
||||
*/
|
||||
$cfg["blowfish_secret"] = "%blowfish_secret%"; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
|
||||
|
||||
/**
|
||||
* Directories for saving/loading files from server
|
||||
*/
|
||||
$cfg["UploadDir"] = "";
|
||||
$cfg["SaveDir"] = "";
|
||||
|
||||
/**
|
||||
* You can find more configuration options in the documentation
|
||||
* in the doc/ folder or at <https://docs.phpmyadmin.net/>.
|
||||
*/
|
||||
|
||||
//start with 1 other wise it doesn't work
|
||||
$i = 1;
|
||||
foreach (glob("/etc/phpmyadmin/conf.d/*.php") as $filename) {
|
||||
include $filename;
|
||||
/*Don't remove / alter code here below this will add SSO support for all servers*/
|
||||
//Add Hestia SSO code here
|
||||
$i++;
|
||||
}
|
||||
389
install/common/phpmyadmin/create_tables.sql
Normal file
389
install/common/phpmyadmin/create_tables.sql
Normal file
@@ -0,0 +1,389 @@
|
||||
-- --------------------------------------------------------
|
||||
-- SQL Commands to set up the pmadb as described in the documentation.
|
||||
--
|
||||
-- This file is meant for use with MySQL 5 and above!
|
||||
--
|
||||
-- This script expects the user pma to already be existing. If we would put a
|
||||
-- line here to create him too many users might just use this script and end
|
||||
-- up with having the same password for the controluser.
|
||||
--
|
||||
-- This user "pma" must be defined in config.inc.php (controluser/controlpass)
|
||||
--
|
||||
-- Please don't forget to set up the tablenames in config.inc.php
|
||||
--
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Database : `phpmyadmin`
|
||||
--
|
||||
CREATE DATABASE IF NOT EXISTS `phpmyadmin` DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
USE phpmyadmin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Privileges
|
||||
--
|
||||
-- (activate this statement if necessary)
|
||||
-- GRANT SELECT, INSERT, DELETE, UPDATE, ALTER ON `phpmyadmin`.* TO
|
||||
-- 'pma'@localhost;
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__usergroups`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__usergroups` (
|
||||
`usergroup` varchar(64) NOT NULL,
|
||||
`tab` varchar(64) NOT NULL,
|
||||
`allowed` enum ('Y', 'N') NOT NULL DEFAULT 'N',
|
||||
PRIMARY KEY (`usergroup`, `tab`, `allowed`)
|
||||
) COMMENT = 'User groups with configured menu items' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__designer_coords`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__designer_coords` (
|
||||
`db_name` varchar(64) COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||
`table_name` varchar(64) COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||
`x` int (11) DEFAULT NULL,
|
||||
`y` int (11) DEFAULT NULL,
|
||||
`v` tinyint (4) DEFAULT NULL,
|
||||
`h` tinyint (4) DEFAULT NULL,
|
||||
PRIMARY KEY (`db_name`, `table_name`)
|
||||
) ENGINE = MyISAM DEFAULT CHARSET = utf8 COLLATE = utf8_bin COMMENT = 'Table coordinates for Designer';
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__bookmark`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__bookmark` (
|
||||
`id` int (11) NOT NULL auto_increment,
|
||||
`dbase` varchar(255) NOT NULL default '',
|
||||
`user` varchar(255) NOT NULL default '',
|
||||
`label` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
|
||||
`query` text NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT = 'Bookmarks' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__column_info`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__column_info` (
|
||||
`id` int (5) unsigned NOT NULL auto_increment,
|
||||
`db_name` varchar(64) NOT NULL default '',
|
||||
`table_name` varchar(64) NOT NULL default '',
|
||||
`column_name` varchar(64) NOT NULL default '',
|
||||
`comment` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
|
||||
`mimetype` varchar(255) COLLATE utf8_general_ci NOT NULL default '',
|
||||
`transformation` varchar(255) NOT NULL default '',
|
||||
`transformation_options` varchar(255) NOT NULL default '',
|
||||
`input_transformation` varchar(255) NOT NULL default '',
|
||||
`input_transformation_options` varchar(255) NOT NULL default '',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `db_name` (`db_name`, `table_name`, `column_name`)
|
||||
) COMMENT = 'Column information for phpMyAdmin' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__history`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__history` (
|
||||
`id` bigint (20) unsigned NOT NULL auto_increment,
|
||||
`username` varchar(64) NOT NULL default '',
|
||||
`db` varchar(64) NOT NULL default '',
|
||||
`table` varchar(64) NOT NULL default '',
|
||||
`timevalue` timestamp NOT NULL default CURRENT_TIMESTAMP,
|
||||
`sqlquery` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `username` (`username`, `db`, `table`, `timevalue`)
|
||||
) COMMENT = 'SQL history for phpMyAdmin' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__pdf_pages`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__pdf_pages` (
|
||||
`db_name` varchar(64) NOT NULL default '',
|
||||
`page_nr` int (10) unsigned NOT NULL auto_increment,
|
||||
`page_descr` varchar(50) COLLATE utf8_general_ci NOT NULL default '',
|
||||
PRIMARY KEY (`page_nr`),
|
||||
KEY `db_name` (`db_name`)
|
||||
) COMMENT = 'PDF relation pages for phpMyAdmin' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__recent`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__recent` (
|
||||
`username` varchar(64) NOT NULL,
|
||||
`tables` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
) COMMENT = 'Recently accessed tables' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__favorite`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__favorite` (
|
||||
`username` varchar(64) NOT NULL,
|
||||
`tables` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
) COMMENT = 'Favorite tables' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__table_uiprefs`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__table_uiprefs` (
|
||||
`username` varchar(64) NOT NULL,
|
||||
`db_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(64) NOT NULL,
|
||||
`prefs` text NOT NULL,
|
||||
`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`username`, `db_name`, `table_name`)
|
||||
) COMMENT = 'Tables'' UI preferences' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__relation`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__relation` (
|
||||
`master_db` varchar(64) NOT NULL default '',
|
||||
`master_table` varchar(64) NOT NULL default '',
|
||||
`master_field` varchar(64) NOT NULL default '',
|
||||
`foreign_db` varchar(64) NOT NULL default '',
|
||||
`foreign_table` varchar(64) NOT NULL default '',
|
||||
`foreign_field` varchar(64) NOT NULL default '',
|
||||
PRIMARY KEY (`master_db`, `master_table`, `master_field`),
|
||||
KEY `foreign_field` (`foreign_db`, `foreign_table`)
|
||||
) COMMENT = 'Relation table' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__table_coords`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__table_coords` (
|
||||
`db_name` varchar(64) NOT NULL default '',
|
||||
`table_name` varchar(64) NOT NULL default '',
|
||||
`pdf_page_number` int (11) NOT NULL default '0',
|
||||
`x` float unsigned NOT NULL default '0',
|
||||
`y` float unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (`db_name`, `table_name`, `pdf_page_number`)
|
||||
) COMMENT = 'Table coordinates for phpMyAdmin PDF output' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__table_info`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__table_info` (
|
||||
`db_name` varchar(64) NOT NULL default '',
|
||||
`table_name` varchar(64) NOT NULL default '',
|
||||
`display_field` varchar(64) NOT NULL default '',
|
||||
PRIMARY KEY (`db_name`, `table_name`)
|
||||
) COMMENT = 'Table information for phpMyAdmin' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__tracking`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__tracking` (
|
||||
`db_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(64) NOT NULL,
|
||||
`version` int (10) unsigned NOT NULL,
|
||||
`date_created` datetime NOT NULL,
|
||||
`date_updated` datetime NOT NULL,
|
||||
`schema_snapshot` text NOT NULL,
|
||||
`schema_sql` text,
|
||||
`data_sql` longtext,
|
||||
`tracking`
|
||||
set
|
||||
(
|
||||
'UPDATE',
|
||||
'REPLACE',
|
||||
'INSERT',
|
||||
'DELETE',
|
||||
'TRUNCATE',
|
||||
'CREATE DATABASE',
|
||||
'ALTER DATABASE',
|
||||
'DROP DATABASE',
|
||||
'CREATE TABLE',
|
||||
'ALTER TABLE',
|
||||
'RENAME TABLE',
|
||||
'DROP TABLE',
|
||||
'CREATE INDEX',
|
||||
'DROP INDEX',
|
||||
'CREATE VIEW',
|
||||
'ALTER VIEW',
|
||||
'DROP VIEW'
|
||||
) default NULL,
|
||||
`tracking_active` int (1) unsigned NOT NULL default '1',
|
||||
PRIMARY KEY (`db_name`, `table_name`, `version`)
|
||||
) COMMENT = 'Database changes tracking for phpMyAdmin' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__userconfig`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__userconfig` (
|
||||
`username` varchar(64) NOT NULL,
|
||||
`timevalue` timestamp NOT NULL default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`config_data` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
) COMMENT = 'User preferences storage for phpMyAdmin' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__users`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__users` (
|
||||
`username` varchar(64) NOT NULL,
|
||||
`usergroup` varchar(64) NOT NULL,
|
||||
PRIMARY KEY (`username`, `usergroup`)
|
||||
) COMMENT = 'Users and their assignments to user groups' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__usergroups`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__usergroups` (
|
||||
`usergroup` varchar(64) NOT NULL,
|
||||
`tab` varchar(64) NOT NULL,
|
||||
`allowed` enum ('Y', 'N') NOT NULL DEFAULT 'N',
|
||||
PRIMARY KEY (`usergroup`, `tab`, `allowed`)
|
||||
) COMMENT = 'User groups with configured menu items' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__navigationhiding`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__navigationhiding` (
|
||||
`username` varchar(64) NOT NULL,
|
||||
`item_name` varchar(64) NOT NULL,
|
||||
`item_type` varchar(64) NOT NULL,
|
||||
`db_name` varchar(64) NOT NULL,
|
||||
`table_name` varchar(64) NOT NULL,
|
||||
PRIMARY KEY (
|
||||
`username`,
|
||||
`item_name`,
|
||||
`item_type`,
|
||||
`db_name`,
|
||||
`table_name`
|
||||
)
|
||||
) COMMENT = 'Hidden items of navigation tree' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__savedsearches`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__savedsearches` (
|
||||
`id` int (5) unsigned NOT NULL auto_increment,
|
||||
`username` varchar(64) NOT NULL default '',
|
||||
`db_name` varchar(64) NOT NULL default '',
|
||||
`search_name` varchar(64) NOT NULL default '',
|
||||
`search_data` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `u_savedsearches_username_dbname` (`username`, `db_name`, `search_name`)
|
||||
) COMMENT = 'Saved searches' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__central_columns`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__central_columns` (
|
||||
`db_name` varchar(64) NOT NULL,
|
||||
`col_name` varchar(64) NOT NULL,
|
||||
`col_type` varchar(64) NOT NULL,
|
||||
`col_length` text,
|
||||
`col_collation` varchar(64) NOT NULL,
|
||||
`col_isNull` boolean NOT NULL,
|
||||
`col_extra` varchar(255) default '',
|
||||
`col_default` text,
|
||||
PRIMARY KEY (`db_name`, `col_name`)
|
||||
) COMMENT = 'Central list of columns' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__designer_settings`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__designer_settings` (
|
||||
`username` varchar(64) NOT NULL,
|
||||
`settings_data` text NOT NULL,
|
||||
PRIMARY KEY (`username`)
|
||||
) COMMENT = 'Settings related to Designer' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
--
|
||||
-- Table structure for table `pma__export_templates`
|
||||
--
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS `pma__export_templates` (
|
||||
`id` int (5) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`username` varchar(64) NOT NULL,
|
||||
`export_type` varchar(10) NOT NULL,
|
||||
`template_name` varchar(64) NOT NULL,
|
||||
`template_data` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `u_user_type_template` (`username`, `export_type`, `template_name`)
|
||||
) COMMENT = 'Saved export templates' DEFAULT CHARACTER
|
||||
SET
|
||||
utf8 COLLATE utf8_bin;
|
||||
213
install/common/phpmyadmin/hestia-sso.php
Normal file
213
install/common/phpmyadmin/hestia-sso.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
/* Hestia way to enable support for SSO to PHPmyAdmin */
|
||||
/* To install please run v-add-sys-pma-sso */
|
||||
|
||||
/* Following keys will get replaced when calling v-add-sys-pma-sso */
|
||||
define("PHPMYADMIN_KEY", "%PHPMYADMIN_KEY%");
|
||||
define("API_HOST_NAME", "%API_HOST_NAME%");
|
||||
define("API_HESTIA_PORT", "%API_HESTIA_PORT%");
|
||||
define("API_KEY", "%API_KEY%");
|
||||
|
||||
class Hestia_API {
|
||||
/** @var string */
|
||||
public $hostname;
|
||||
/** @var string */
|
||||
public $key;
|
||||
/** @var string */
|
||||
public $pma_key;
|
||||
/** @var string */
|
||||
private $api_url;
|
||||
public function __construct() {
|
||||
$this->hostname = "https://" . API_HOST_NAME . ":" . API_HESTIA_PORT . "/api/";
|
||||
$this->key = API_KEY;
|
||||
$this->pma_key = PHPMYADMIN_KEY;
|
||||
}
|
||||
|
||||
/* Creates curl request */
|
||||
public function request($postvars) {
|
||||
$postdata = http_build_query($postvars);
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $this->hostname);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
|
||||
$answer = curl_exec($curl);
|
||||
return $answer;
|
||||
}
|
||||
|
||||
/* Creates an new temp user in mysql */
|
||||
public function create_temp_user($database, $user, $host) {
|
||||
$post_request = [
|
||||
"hash" => $this->key,
|
||||
"returncode" => "no",
|
||||
"cmd" => "v-add-database-temp-user",
|
||||
"arg1" => $user,
|
||||
"arg2" => $database,
|
||||
"arg3" => "mysql",
|
||||
"arg4" => $host,
|
||||
];
|
||||
$request = $this->request($post_request);
|
||||
$json = json_decode($request);
|
||||
if (json_last_error() == JSON_ERROR_NONE) {
|
||||
return $json;
|
||||
} else {
|
||||
trigger_error("Unable to connect over API please check api connection", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete an new temp user in mysql */
|
||||
public function delete_temp_user($database, $user, $dbuser, $host) {
|
||||
$post_request = [
|
||||
"hash" => $this->key,
|
||||
"returncode" => "yes",
|
||||
"cmd" => "v-delete-database-temp-user",
|
||||
"arg1" => $user,
|
||||
"arg2" => $database,
|
||||
"arg3" => $dbuser,
|
||||
"arg4" => "mysql",
|
||||
"arg5" => $host,
|
||||
];
|
||||
$request = $this->request($post_request);
|
||||
if (is_numeric($request) && $request == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_user_ip() {
|
||||
// Saving user IPs to the session for preventing session hijacking
|
||||
$user_combined_ip = [];
|
||||
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["SERVER_ADDR"]) {
|
||||
$user_combined_ip[] = $_SERVER["REMOTE_ADDR"];
|
||||
}
|
||||
if (isset($_SERVER["HTTP_CLIENT_IP"])) {
|
||||
$user_combined_ip .= "|" . $_SERVER["HTTP_CLIENT_IP"];
|
||||
}
|
||||
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
|
||||
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_X_FORWARDED_FOR"]) {
|
||||
$user_combined_ip[] = $_SERVER["HTTP_X_FORWARDED_FOR"];
|
||||
}
|
||||
}
|
||||
if (isset($_SERVER["HTTP_FORWARDED_FOR"])) {
|
||||
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_FORWARDED_FOR"]) {
|
||||
$user_combined_ip[] = $_SERVER["HTTP_FORWARDED_FOR"];
|
||||
}
|
||||
}
|
||||
if (isset($_SERVER["HTTP_X_FORWARDED"])) {
|
||||
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_X_FORWARDED"]) {
|
||||
$user_combined_ip[] = $_SERVER["HTTP_X_FORWARDED"];
|
||||
}
|
||||
}
|
||||
if (isset($_SERVER["HTTP_FORWARDED"])) {
|
||||
if ($_SERVER["REMOTE_ADDR"] != $_SERVER["HTTP_FORWARDED"]) {
|
||||
$user_combined_ip[] = "|" . $_SERVER["HTTP_FORWARDED"];
|
||||
}
|
||||
}
|
||||
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
|
||||
if (!empty($_SERVER["HTTP_CF_CONNECTING_IP"])) {
|
||||
$user_combined_ip[] = $_SERVER["HTTP_CF_CONNECTING_IP"];
|
||||
}
|
||||
}
|
||||
return implode("|", $user_combined_ip);
|
||||
}
|
||||
}
|
||||
|
||||
function verify_token($database, $user, $ip, $time, $token) {
|
||||
if (!password_verify($database . $user . $ip . $time . PHPMYADMIN_KEY, $token)) {
|
||||
if (
|
||||
!password_verify(
|
||||
$database . $user . $_SERVER["SERVER_ADDR"] . "|" . $ip . $time . PHPMYADMIN_KEY,
|
||||
$token,
|
||||
)
|
||||
) {
|
||||
trigger_error(
|
||||
"Access denied: There is a security token mismatch " . $time,
|
||||
E_USER_WARNING,
|
||||
);
|
||||
session_invalid();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* Need to have cookie visible from parent directory */
|
||||
session_set_cookie_params(0, "/", "", true, true);
|
||||
/* Create signon session */
|
||||
$session_name = "SignonSession";
|
||||
session_name($session_name);
|
||||
@session_start();
|
||||
|
||||
function session_invalid() {
|
||||
global $session_name;
|
||||
//delete all current sessions
|
||||
session_destroy();
|
||||
setcookie($session_name, null, -1, "/");
|
||||
header("Location: " . dirname($_SERVER["PHP_SELF"]) . "/index.php");
|
||||
die();
|
||||
}
|
||||
|
||||
$api = new Hestia_API();
|
||||
if (!empty($_GET)) {
|
||||
if (isset($_GET["logout"])) {
|
||||
$api->delete_temp_user(
|
||||
$_SESSION["HESTIA_sso_database"],
|
||||
$_SESSION["HESTIA_sso_user"],
|
||||
$_SESSION["PMA_single_signon_user"],
|
||||
$_SESSION["HESTIA_sso_host"],
|
||||
);
|
||||
//remove session
|
||||
session_invalid();
|
||||
} else {
|
||||
if (isset($_GET["user"]) && isset($_GET["hestia_token"])) {
|
||||
$database = $_GET["database"];
|
||||
$user = $_GET["user"];
|
||||
$host = "localhost";
|
||||
$token = $_GET["hestia_token"];
|
||||
if (is_numeric($_GET["exp"])) {
|
||||
$time = $_GET["exp"];
|
||||
} else {
|
||||
$time = 0;
|
||||
}
|
||||
|
||||
if ($time + 60 > time()) {
|
||||
//note: Possible issues with cloudflare due to ip obfuscation
|
||||
$ip = $api->get_user_ip();
|
||||
verify_token($database, $user, $ip, $time, $token);
|
||||
$id = session_id();
|
||||
//create a new temp user
|
||||
$data = $api->create_temp_user($database, $user, $host);
|
||||
if ($data) {
|
||||
$_SESSION["PMA_single_signon_user"] = $data->login->user;
|
||||
$_SESSION["PMA_single_signon_password"] = $data->login->password;
|
||||
$_SESSION["PMA_single_signon_host"] = $host;
|
||||
//save database / username to be used for sending logout notification.
|
||||
$_SESSION["HESTIA_sso_user"] = $user;
|
||||
$_SESSION["HESTIA_sso_database"] = $database;
|
||||
$_SESSION["HESTIA_sso_host"] = $host;
|
||||
|
||||
@session_write_close();
|
||||
setcookie($session_name, $id, 0, "/");
|
||||
header("Location: " . dirname($_SERVER["PHP_SELF"]) . "/index.php");
|
||||
die();
|
||||
} else {
|
||||
session_invalid();
|
||||
}
|
||||
} else {
|
||||
trigger_error(
|
||||
"Link has been expired: System time: " .
|
||||
time() .
|
||||
" / Time provided in link: " .
|
||||
$time,
|
||||
E_USER_WARNING,
|
||||
);
|
||||
session_invalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
session_invalid();
|
||||
}
|
||||
103
install/common/phpmyadmin/pma.sh
Normal file
103
install/common/phpmyadmin/pma.sh
Normal file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# phpmyadmin-fixer
|
||||
#
|
||||
# Fixes for phpmyadmin (configuration storage and some extended features)
|
||||
#
|
||||
# Original Version by Pavel Galkin (https://skurudo.ru)
|
||||
# https://github.com/skurudo/phpmyadmin-fixer
|
||||
#
|
||||
# Changed some lines to fit to Hestia Configuration.
|
||||
#
|
||||
|
||||
PASS=$(gen_pass)
|
||||
|
||||
#ubuntu phpmyadmin path
|
||||
pmapath="/etc/phpmyadmin/conf.d/01-localhost.php"
|
||||
echo "<?php " >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['host'] = 'localhost';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['port'] = '3306';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['favorite'] = 'pma__favorite';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['usergroups'] = 'pma__usergroups';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['central_columns'] = 'pma__central_columns';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['designer_settings'] = 'pma__designer_settings';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['export_templates'] = 'pma__export_templates';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['savedsearches'] = 'pma__savedsearches';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['navigationhiding'] = 'pma__navigationhiding';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['users'] = 'pma__users';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['usergroups'] = 'pma__usergroups';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['pmadb'] = 'phpmyadmin';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['controluser'] = 'pma';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['controlpass'] = '$PASS';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['bookmarktable'] = 'pma__bookmark';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['relation'] = 'pma__relation';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['userconfig'] = 'pma__userconfig';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['table_info'] = 'pma__table_info';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['column_info'] = 'pma__column_info';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['history'] = 'pma__history';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['recent'] = 'pma__recent';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['table_uiprefs'] = 'pma__table_uiprefs';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['tracking'] = 'pma__tracking';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['table_coords'] = 'pma__table_coords';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['pdf_pages'] = 'pma__pdf_pages';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['designer_coords'] = 'pma__designer_coords';" >> $pmapath
|
||||
echo "\$cfg['Servers'][\$i]['hide_db'] = 'information_schema';" >> $pmapath
|
||||
|
||||
#SOME WORK with DATABASE (table / user)
|
||||
PMADB=phpmyadmin
|
||||
PMAUSER=pma
|
||||
|
||||
#DROP USER and TABLE
|
||||
#mysql -uroot <<MYSQL_PMA1
|
||||
#DROP USER '$PMAUSER'@'localhost';
|
||||
#DROP DATABASE $PMADB;
|
||||
#FLUSH PRIVILEGES;
|
||||
#MYSQL_PMA1
|
||||
|
||||
#CREATE PMA USER
|
||||
if [ -f '/usr/bin/mariadb' ]; then
|
||||
mysql_server="mariadb"
|
||||
else
|
||||
mysql_server="mysql"
|
||||
fi
|
||||
mysql_out=$(mktemp)
|
||||
$mysql -e 'SELECT VERSION()' > $mysql_out
|
||||
mysql_ver=$(cat $mysql_out | tail -n1 | cut -f 1 -d -)
|
||||
mysql_ver_sub=$(echo $mysql_ver | cut -d '.' -f1)
|
||||
mysql_ver_sub_sub=$(echo $mysql_ver | cut -d '.' -f2)
|
||||
|
||||
if [ "$mysql" = "mysql" ] && [ "$mysql_ver_sub" -ge 8 ]; then
|
||||
query="CREATE USER '$PMAUSER'@'localhost' IDENTIFIED BY '$PASS';"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="CREATE DATABASE $PMADB;"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="GRANT USAGE ON $PMADB.* TO '$PMAUSER'@'localhost';"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="GRANT ALL PRIVILEGES ON $PMADB.* TO '$PMAUSER'@'localhost';"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="FLUSH PRIVILEGES;"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
else
|
||||
query="CREATE USER '$PMAUSER'@'localhost' IDENTIFIED BY '$PASS';"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="CREATE DATABASE $PMADB;"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="GRANT USAGE ON $PMADB.* TO '$PMAUSER'@'localhost' IDENTIFIED BY '$PASS';"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="GRANT ALL PRIVILEGES ON $PMADB.* TO '$PMAUSER'@'localhost';"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
|
||||
query="FLUSH PRIVILEGES;"
|
||||
$mysql_server -uroot -e "$query" > /dev/null
|
||||
fi
|
||||
|
||||
#MYSQL DB and TABLES ADDITION
|
||||
$mysql_server -uroot < "$HESTIA_INSTALL_DIR/phpmyadmin/create_tables.sql"
|
||||
40
install/common/roundcube/apache.conf
Normal file
40
install/common/roundcube/apache.conf
Normal file
@@ -0,0 +1,40 @@
|
||||
Alias /roundcube/program/js/tiny_mce/ /usr/share/tinymce/www/
|
||||
Alias /roundcube /var/lib/roundcube
|
||||
Alias /webmail /var/lib/roundcube
|
||||
|
||||
# Access to tinymce files
|
||||
<Directory "/usr/share/tinymce/www/">
|
||||
Options Indexes MultiViews FollowSymLinks
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
allow from all
|
||||
</Directory>
|
||||
|
||||
<Directory /var/lib/roundcube/>
|
||||
Options +FollowSymLinks
|
||||
# This is needed to parse /var/lib/roundcube/.htaccess. See its
|
||||
# content before setting AllowOverride to None.
|
||||
AllowOverride All
|
||||
order allow,deny
|
||||
allow from all
|
||||
</Directory>
|
||||
|
||||
# Protecting basic directories:
|
||||
<Directory /var/lib/roundcube/config>
|
||||
Options -FollowSymLinks
|
||||
AllowOverride None
|
||||
</Directory>
|
||||
|
||||
<Directory /var/lib/roundcube/temp>
|
||||
Options -FollowSymLinks
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</Directory>
|
||||
|
||||
<Directory /var/lib/roundcube/logs>
|
||||
Options -FollowSymLinks
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
</Directory>
|
||||
32
install/common/roundcube/config.inc.php
Normal file
32
install/common/roundcube/config.inc.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
// Password Plugin options
|
||||
// -----------------------
|
||||
// A driver to use for password change. Default: "sql".
|
||||
// See README file for list of supported driver names.
|
||||
$config["password_driver"] = "hestia";
|
||||
|
||||
// Require the new password to be a certain length.
|
||||
// set to blank to allow passwords of any length
|
||||
$config["password_minimum_length"] = 8;
|
||||
|
||||
// Require the new password to contain a letter and punctuation character
|
||||
// Change to false to remove this check.
|
||||
$config["password_require_nonalpha"] = false;
|
||||
|
||||
// Enables logging of password changes into logs/password
|
||||
$config["password_log"] = false;
|
||||
|
||||
// Comma-separated list of login exceptions for which password change
|
||||
// will be not available (no Password tab in Settings)
|
||||
$config["password_login_exceptions"] = null;
|
||||
|
||||
// By default domains in variables are using unicode.
|
||||
// Enable this option to use punycoded names
|
||||
$config["password_idn_ascii"] = false;
|
||||
|
||||
// Hestia Driver options
|
||||
// -----------------------
|
||||
// Control Panel host
|
||||
$config["password_hestia_host"] = "localhost";
|
||||
$config["password_hestia_port"] = "8083";
|
||||
57
install/common/roundcube/hestia.php
Normal file
57
install/common/roundcube/hestia.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Hestia Control Panel Password Driver
|
||||
*
|
||||
* @version 1.0
|
||||
* @author HestiaCP <info@hestiacp.com>
|
||||
*/
|
||||
class rcube_hestia_password {
|
||||
public function save($curpass, $passwd) {
|
||||
$rcmail = rcmail::get_instance();
|
||||
$hestia_host = $rcmail->config->get("password_hestia_host");
|
||||
|
||||
if (empty($hestia_host)) {
|
||||
$hestia_host = "localhost";
|
||||
}
|
||||
|
||||
$hestia_port = $rcmail->config->get("password_hestia_port");
|
||||
if (empty($hestia_port)) {
|
||||
$hestia_port = "8083";
|
||||
}
|
||||
|
||||
$postvars = [
|
||||
"email" => $_SESSION["username"],
|
||||
"password" => $curpass,
|
||||
"new" => $passwd,
|
||||
];
|
||||
$url = "https://{$hestia_host}:{$hestia_port}/reset/mail/";
|
||||
$ch = curl_init();
|
||||
if (
|
||||
false ===
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => http_build_query($postvars),
|
||||
CURLOPT_USERAGENT => "Hestia Control Panel Password Driver",
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
])
|
||||
) {
|
||||
// should never happen
|
||||
throw new Exception("curl_setopt_array() failed: " . curl_error($ch));
|
||||
}
|
||||
$result = curl_exec($ch);
|
||||
if (curl_errno($ch) !== CURLE_OK) {
|
||||
throw new Exception("curl_exec() failed: " . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
if (strpos($result, "ok") && !strpos($result, "error")) {
|
||||
return PASSWORD_SUCCESS;
|
||||
} else {
|
||||
return PASSWORD_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
104
install/common/roundcube/main.inc.php
Normal file
104
install/common/roundcube/main.inc.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/* Local configuration for Roundcube Webmail */
|
||||
|
||||
//rewrite below this line
|
||||
$config["db_dsnw"] = "mysql://roundcube:%password%@localhost/roundcube";
|
||||
|
||||
// Log sent messages to <log_dir>/sendmail or to syslog
|
||||
$config["smtp_log"] = false;
|
||||
|
||||
// Log IMAP conversation to <log_dir>/imap or to syslog
|
||||
$config["imap_debug"] = true;
|
||||
|
||||
// Log SMTP conversation to <log_dir>/smtp.log or to syslog
|
||||
$config["smtp_debug"] = true;
|
||||
|
||||
// ----------------------------------
|
||||
// IMAP
|
||||
// ----------------------------------
|
||||
// The IMAP host chosen to perform the log-in.
|
||||
// Leave blank to show a textbox at login, give a list of hosts
|
||||
// to display a pulldown menu or set one host as string.
|
||||
// Enter hostname with prefix ssl:// to use Implicit TLS, or use
|
||||
// prefix tls:// to use STARTTLS.
|
||||
// Supported replacement variables:
|
||||
// %n - hostname ($_SERVER['SERVER_NAME'])
|
||||
// %t - hostname without the first part
|
||||
// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
|
||||
// %s - domain name after the '@' from e-mail address provided at login screen
|
||||
// For example %n = mail.domain.tld, %t = domain.tld
|
||||
// WARNING: After hostname change update of mail_host column in users table is
|
||||
// required to match old user data records with the new host.
|
||||
$config["imap_host"] = "localhost:143";
|
||||
|
||||
// IMAP socket context options
|
||||
// See http://php.net/manual/en/context.ssl.php
|
||||
// The example below enables server certificate validation
|
||||
//$config['imap_conn_options'] = array(
|
||||
// 'ssl' => array(
|
||||
// 'verify_peer' => true,
|
||||
// 'verify_depth' => 3,
|
||||
// 'cafile' => '/etc/openssl/certs/ca.crt',
|
||||
// ),
|
||||
// );
|
||||
// Note: These can be also specified as an array of options indexed by hostname
|
||||
$config["imap_conn_options"] = [
|
||||
"ssl" => [
|
||||
"verify_peer" => false,
|
||||
"verify_peer_name" => false,
|
||||
"verify_depth" => 3,
|
||||
"cafile" => "/etc/ssl/certs/ca-certificates.crt",
|
||||
],
|
||||
];
|
||||
|
||||
// SMTP socket context options
|
||||
// See http://php.net/manual/en/context.ssl.php
|
||||
// The example below enables server certificate validation, and
|
||||
// requires 'smtp_timeout' to be non zero.
|
||||
// $config['smtp_conn_options'] = array(
|
||||
// 'ssl' => array(
|
||||
// 'verify_peer' => true,
|
||||
// 'verify_depth' => 3,
|
||||
// 'cafile' => '/etc/openssl/certs/ca.crt',
|
||||
// ),
|
||||
// );
|
||||
// Note: These can be also specified as an array of options indexed by hostname
|
||||
$config["smtp_conn_options"] = [
|
||||
"ssl" => [
|
||||
"verify_peer" => false,
|
||||
"verify_peer_name" => false,
|
||||
"verify_depth" => 3,
|
||||
"cafile" => "/etc/ssl/certs/ca-certificates.crt",
|
||||
],
|
||||
];
|
||||
|
||||
// provide an URL where a user can get support for this Roundcube installation
|
||||
// PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!
|
||||
$config["support_url"] = "";
|
||||
|
||||
// use this folder to store log files
|
||||
// must be writeable for the user who runs PHP process (Apache user if mod_php is being used)
|
||||
// This is used by the 'file' log driver.
|
||||
$config["log_dir"] = "/var/log/roundcube/";
|
||||
|
||||
// This key is used for encrypting purposes, like storing of imap password
|
||||
// in the session. For historical reasons it's called DES_key, but it's used
|
||||
// with any configured cipher_method (see below).
|
||||
// For the default cipher_method a required key length is 24 characters.
|
||||
$config["des_key"] = "%des_key%";
|
||||
|
||||
// Maximum number of recipients per message (including To, Cc, Bcc).
|
||||
// Default: 0 (no limit)
|
||||
$config["max_recipients"] = 100;
|
||||
|
||||
// List of active plugins (in plugins/ directory)
|
||||
$config["plugins"] = ["password", "newmail_notifier", "zipdownload", "archive"];
|
||||
|
||||
$config["default_user"] = "%u";
|
||||
|
||||
$config["default_pass"] = "%p";
|
||||
|
||||
$config["smtp_host"] = "localhost:587";
|
||||
|
||||
// Log session authentication errors to <log_dir>/session or to syslog
|
||||
$config["log_session"] = true;
|
||||
56
install/common/roundcube/mimetypes.php
Normal file
56
install/common/roundcube/mimetypes.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Local mapping file to specify mime-types based on common file-name extensions
|
||||
*
|
||||
* Please note that this mapping takes precedence over the content-based mime-type detection
|
||||
* and should only contain mappings which cannot be detected properly from the file contents.
|
||||
*/
|
||||
|
||||
return [
|
||||
"xls" => "application/vnd.ms-excel",
|
||||
"xlm" => "application/vnd.ms-excel",
|
||||
"xla" => "application/vnd.ms-excel",
|
||||
"xlc" => "application/vnd.ms-excel",
|
||||
"xlt" => "application/vnd.ms-excel",
|
||||
"xlw" => "application/vnd.ms-excel",
|
||||
"pdf" => "application/pdf",
|
||||
"ppt" => "application/vnd.ms-powerpoint",
|
||||
"pps" => "application/vnd.ms-powerpoint",
|
||||
"pot" => "application/vnd.ms-powerpoint",
|
||||
"doc" => "application/msword",
|
||||
"dot" => "application/msword",
|
||||
"odc" => "application/vnd.oasis.opendocument.chart",
|
||||
"otc" => "application/vnd.oasis.opendocument.chart-template",
|
||||
"odf" => "application/vnd.oasis.opendocument.formula",
|
||||
"otf" => "application/vnd.oasis.opendocument.formula-template",
|
||||
"odg" => "application/vnd.oasis.opendocument.graphics",
|
||||
"otg" => "application/vnd.oasis.opendocument.graphics-template",
|
||||
"odi" => "application/vnd.oasis.opendocument.image",
|
||||
"oti" => "application/vnd.oasis.opendocument.image-template",
|
||||
"odp" => "application/vnd.oasis.opendocument.presentation",
|
||||
"otp" => "application/vnd.oasis.opendocument.presentation-template",
|
||||
"ods" => "application/vnd.oasis.opendocument.spreadsheet",
|
||||
"ots" => "application/vnd.oasis.opendocument.spreadsheet-template",
|
||||
"odt" => "application/vnd.oasis.opendocument.text",
|
||||
"otm" => "application/vnd.oasis.opendocument.text-master",
|
||||
"ott" => "application/vnd.oasis.opendocument.text-template",
|
||||
"oth" => "application/vnd.oasis.opendocument.text-web",
|
||||
"docm" => "application/vnd.ms-word.document.macroEnabled.12",
|
||||
"docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
"dotm" => "application/vnd.ms-word.template.macroEnabled.12",
|
||||
"dotx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
|
||||
"ppsm" => "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
|
||||
"ppsx" => "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
|
||||
"pptm" => "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
|
||||
"pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
"xlsb" => "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
|
||||
"xlsm" => "application/vnd.ms-excel.sheet.macroEnabled.12",
|
||||
"xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"xps" => "application/vnd.ms-xpsdocument",
|
||||
"rar" => "application/x-rar-compressed",
|
||||
"7z" => "application/x-7z-compressed",
|
||||
"s7z" => "application/x-7z-compressed",
|
||||
"vcf" => "text/vcard",
|
||||
"ics" => "text/calendar",
|
||||
];
|
||||
126
install/common/roundcube/plugins/config_managesieve.inc.php
Normal file
126
install/common/roundcube/plugins/config_managesieve.inc.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
// managesieve server address, default is localhost.
|
||||
// Replacement variables supported in host name:
|
||||
// %h - user's IMAP hostname
|
||||
// %n - http hostname ($_SERVER['SERVER_NAME'])
|
||||
// %d - domain (http hostname without the first part)
|
||||
// For example %n = mail.domain.tld, %d = domain.tld
|
||||
$config["managesieve_host"] = "localhost:4190";
|
||||
|
||||
// authentication method. Can be CRAM-MD5, DIGEST-MD5, PLAIN, LOGIN, EXTERNAL
|
||||
// or none. Optional, defaults to best method supported by server.
|
||||
$config["managesieve_auth_type"] = null;
|
||||
|
||||
// Optional managesieve authentication identifier to be used as authorization proxy.
|
||||
// Authenticate as a different user but act on behalf of the logged in user.
|
||||
// Works with PLAIN and DIGEST-MD5 auth.
|
||||
$config["managesieve_auth_cid"] = null;
|
||||
|
||||
// Optional managesieve authentication password to be used for imap_auth_cid
|
||||
$config["managesieve_auth_pw"] = null;
|
||||
|
||||
// use or not TLS for managesieve server connection
|
||||
// Note: tls:// prefix in managesieve_host is also supported
|
||||
$config["managesieve_usetls"] = false;
|
||||
|
||||
// Connection scket context options
|
||||
// See http://php.net/manual/en/context.ssl.php
|
||||
// The example below enables server certificate validation
|
||||
//$config['managesieve_conn_options'] = array(
|
||||
// 'ssl' => array(
|
||||
// 'verify_peer' => true,
|
||||
// 'verify_depth' => 3,
|
||||
// 'cafile' => '/etc/openssl/certs/ca.crt',
|
||||
// ),
|
||||
// );
|
||||
// Note: These can be also specified as an array of options indexed by hostname
|
||||
$config["managesieve_conn_options"] = null;
|
||||
|
||||
// A file with default script content (eg. spam filter)
|
||||
//$config['managesieve_default'] = '/etc/dovecot/sieve/global';
|
||||
$config["managesieve_default"] = "/etc/dovecot/sieve/default";
|
||||
|
||||
// The name of the script which will be used when there's no user script
|
||||
$config["managesieve_script_name"] = "managesieve";
|
||||
|
||||
// Sieve RFC says that we should use UTF-8 endcoding for mailbox names,
|
||||
// but some implementations does not covert UTF-8 to modified UTF-7.
|
||||
// Defaults to UTF7-IMAP
|
||||
$config["managesieve_mbox_encoding"] = "UTF-8";
|
||||
|
||||
// I need this because my dovecot (with listescape plugin) uses
|
||||
// ':' delimiter, but creates folders with dot delimiter
|
||||
$config["managesieve_replace_delimiter"] = "";
|
||||
|
||||
// disabled sieve extensions (body, copy, date, editheader, encoded-character,
|
||||
// envelope, environment, ereject, fileinto, ihave, imap4flags, index,
|
||||
// mailbox, mboxmetadata, regex, reject, relational, servermetadata,
|
||||
// spamtest, spamtestplus, subaddress, vacation, variables, virustest, etc.
|
||||
// Note: not all extensions are implemented
|
||||
$config["managesieve_disabled_extensions"] = [];
|
||||
|
||||
// Enables debugging of conversation with sieve server. Logs it into <log_dir>/sieve
|
||||
$config["managesieve_debug"] = false;
|
||||
|
||||
// Enables features described in http://wiki.kolab.org/KEP:14
|
||||
$config["managesieve_kolab_master"] = false;
|
||||
|
||||
// Script name extension used for scripts including. Dovecot uses '.sieve',
|
||||
// Cyrus uses '.siv'. Doesn't matter if you have managesieve_kolab_master disabled.
|
||||
$config["managesieve_filename_extension"] = ".sieve";
|
||||
|
||||
// List of reserved script names (without extension).
|
||||
// Scripts listed here will be not presented to the user.
|
||||
$config["managesieve_filename_exceptions"] = [];
|
||||
|
||||
// List of domains limiting destination emails in redirect action
|
||||
// If not empty, user will need to select domain from a list
|
||||
$config["managesieve_domains"] = [];
|
||||
|
||||
// Default list of entries in header selector
|
||||
$config["managesieve_default_headers"] = ["Subject", "From", "To"];
|
||||
|
||||
// Enables separate management interface for vacation responses (out-of-office)
|
||||
// 0 - no separate section (default),
|
||||
// 1 - add Vacation section,
|
||||
// 2 - add Vacation section, but hide Filters section
|
||||
$config["managesieve_vacation"] = 0;
|
||||
|
||||
// Enables separate management interface for setting forwards (redirect to and copy to)
|
||||
// 0 - no separate section (default),
|
||||
// 1 - add Forward section,
|
||||
// 2 - add Forward section, but hide Filters section
|
||||
$config["managesieve_forward"] = 0;
|
||||
|
||||
// Default vacation interval (in days).
|
||||
// Note: If server supports vacation-seconds extension it is possible
|
||||
// to define interval in seconds here (as a string), e.g. "3600s".
|
||||
$config["managesieve_vacation_interval"] = 0;
|
||||
|
||||
// Some servers require vacation :addresses to be filled with all
|
||||
// user addresses (aliases). This option enables automatic filling
|
||||
// of these on initial vacation form creation.
|
||||
$config["managesieve_vacation_addresses_init"] = false;
|
||||
|
||||
// Sometimes you want to always reply with mail email address
|
||||
// This option enables automatic filling of :from field on initial vacation form creation.
|
||||
$config["managesieve_vacation_from_init"] = false;
|
||||
|
||||
// Supported methods of notify extension. Default: 'mailto'
|
||||
$config["managesieve_notify_methods"] = ["mailto"];
|
||||
|
||||
// Enables scripts RAW editor feature
|
||||
$config["managesieve_raw_editor"] = true;
|
||||
|
||||
// Disabled actions
|
||||
// Prevent user from performing specific actions:
|
||||
// list_sets, enable_disable_set, delete_set, new_set, download_set, new_rule, delete_rule
|
||||
// Note: disabling list_sets removes the Filter sets widget from the UI and means
|
||||
// the set defined in managesieve_script_name will always be used (and activated)
|
||||
$config["managesieve_disabled_actions"] = [];
|
||||
|
||||
// List of hosts that support managesieve.
|
||||
// Activate managesieve for selected hosts only. If this is not set all hosts are allowed.
|
||||
// Example: $config['managesieve_allowed_hosts'] = array('host1.mydomain.com','host2.mydomain.com');
|
||||
$config["managesieve_allowed_hosts"] = null;
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
// Enables basic notification
|
||||
$config["newmail_notifier_basic"] = true;
|
||||
|
||||
// Enables sound notification
|
||||
$config["newmail_notifier_sound"] = false;
|
||||
|
||||
// Enables desktop notification
|
||||
$config["newmail_notifier_desktop"] = false;
|
||||
|
||||
// Desktop notification close timeout in seconds
|
||||
$config["newmail_notifier_desktop_timeout"] = 5;
|
||||
|
||||
?>
|
||||
21
install/common/roundcube/plugins/config_zipdownload.inc.php
Normal file
21
install/common/roundcube/plugins/config_zipdownload.inc.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ZipDownload configuration file
|
||||
*/
|
||||
|
||||
// Zip attachments
|
||||
// Only show the link when there are more than this many attachments
|
||||
// -1 to prevent downloading of attachments as zip
|
||||
$config["zipdownload_attachments"] = 1;
|
||||
|
||||
// Zip selection of mail messages
|
||||
// This option enables downloading of multiple messages as one zip archive.
|
||||
// The number or string value specifies maximum total size of all messages
|
||||
// in the archive (not the size of the archive itself).
|
||||
$config["zipdownload_selection"] = "100MB";
|
||||
|
||||
// Charset to use for filenames inside the zip
|
||||
$config["zipdownload_charset"] = "ISO-8859-1";
|
||||
|
||||
?>
|
||||
73
install/common/snappymail/install.php
Normal file
73
install/common/snappymail/install.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
$_ENV["SNAPPYMAIL_INCLUDE_AS_API"] = true;
|
||||
require_once "/var/lib/snappymail/index.php";
|
||||
|
||||
$oConfig = \RainLoop\Api::Config();
|
||||
|
||||
// Change default login data / key
|
||||
$oConfig->Set("security", "admin_login", $argv[1]);
|
||||
$oConfig->Set("security", "admin_panel_key", $argv[1]);
|
||||
$oConfig->SetPassword($argv[2]);
|
||||
|
||||
// Allow Contacts to be saved in database
|
||||
$oConfig->Set("contacts", "enable", "On");
|
||||
$oConfig->Set("contacts", "allow_sync", "On");
|
||||
$oConfig->Set("contacts", "type", "mysql");
|
||||
$oConfig->Set("contacts", "pdo_dsn", "mysql:host=127.0.0.1;port=3306;dbname=snappymail");
|
||||
$oConfig->Set("contacts", "pdo_user", "snappymail");
|
||||
$oConfig->Set("contacts", "pdo_password", $argv[3]);
|
||||
|
||||
// Plugins
|
||||
$oConfig->Set("plugins", "enable", "On");
|
||||
|
||||
\SnappyMail\Repository::installPackage("plugin", "change-password");
|
||||
\SnappyMail\Repository::installPackage("plugin", "change-password-hestia");
|
||||
|
||||
$sFile = APP_PRIVATE_DATA . "configs/plugin-change-password.json";
|
||||
if (!file_exists($sFile)) {
|
||||
file_put_contents(
|
||||
"$sFile",
|
||||
json_encode(
|
||||
[
|
||||
"plugin" => [
|
||||
"pass_min_length" => 8,
|
||||
"pass_min_strength" => 60,
|
||||
"driver_hestia_enabled" => true,
|
||||
"driver_hestia_allowed_emails" => "*",
|
||||
"hestia_host" => gethostname(),
|
||||
"hestia_port" => $argv[4], // $BACKEND_PORT
|
||||
],
|
||||
],
|
||||
JSON_PRETTY_PRINT,
|
||||
),
|
||||
);
|
||||
}
|
||||
\SnappyMail\Repository::enablePackage("change-password");
|
||||
|
||||
\SnappyMail\Repository::installPackage("plugin", "add-x-originating-ip-header");
|
||||
\SnappyMail\Repository::enablePackage("add-x-originating-ip-header");
|
||||
$sFile = APP_PRIVATE_DATA . "configs/plugin-add-x-originating-ip-header.json";
|
||||
if (!file_exists($sFile)) {
|
||||
file_put_contents(
|
||||
"$sFile",
|
||||
json_encode(
|
||||
[
|
||||
"plugin" => [
|
||||
"check_proxy" => true,
|
||||
],
|
||||
],
|
||||
JSON_PRETTY_PRINT,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$oConfig->Save();
|
||||
|
||||
$sFile = APP_PRIVATE_DATA . "domains/hestia.json";
|
||||
if (!file_exists($sFile)) {
|
||||
$config = json_decode(APP_PRIVATE_DATA . "domains/default.json", true);
|
||||
$config["IMAP"]["shortLogin"] = true;
|
||||
$config["SMTP"]["shortLogin"] = true;
|
||||
file_put_contents($sFile, json_encode($config, JSON_PRETTY_PRINT));
|
||||
}
|
||||
12
install/common/templates/dns/child-ns.tpl
Executable file
12
install/common/templates/dns/child-ns.tpl
Executable file
@@ -0,0 +1,12 @@
|
||||
ID='1' RECORD='@' TYPE='NS' PRIORITY='' VALUE='ns1.%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='2' RECORD='@' TYPE='NS' PRIORITY='' VALUE='ns2.%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='3' RECORD='@' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='4' RECORD='ns1' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='5' RECORD='ns2' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='6' RECORD='www' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='7' RECORD='ftp' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='8' RECORD='mail' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='9' RECORD='webmail' TYPE='CNAME' PRIORITY='' VALUE='mail.%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='10' RECORD='@' TYPE='MX' PRIORITY='0' VALUE='mail.%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='11' RECORD='@' TYPE='TXT' PRIORITY='' VALUE='"v=spf1 a mx ip4:%ip% -all"' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='12' RECORD='_dmarc' TYPE='TXT' PRIORITY='' VALUE='"v=DMARC1; p=quarantine; pct=100"' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
11
install/common/templates/dns/default-nomail.tpl
Normal file
11
install/common/templates/dns/default-nomail.tpl
Normal file
@@ -0,0 +1,11 @@
|
||||
ID='1' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns1%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='2' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns2%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='3' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns3%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='4' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns4%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='5' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns5%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='6' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns6%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='7' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns7%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='8' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns8%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='9' RECORD='@' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='10' RECORD='www' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='11' RECORD='ftp' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
16
install/common/templates/dns/default.tpl
Executable file
16
install/common/templates/dns/default.tpl
Executable file
@@ -0,0 +1,16 @@
|
||||
ID='1' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns1%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='2' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns2%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='3' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns3%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='4' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns4%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='5' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns5%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='6' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns6%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='7' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns7%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='8' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns8%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='9' RECORD='@' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='10' RECORD='www' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='11' RECORD='ftp' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='12' RECORD='mail' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='13' RECORD='webmail' TYPE='CNAME' PRIORITY='' VALUE='mail.%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='14' RECORD='@' TYPE='MX' PRIORITY='0' VALUE='mail.%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='15' RECORD='@' TYPE='TXT' PRIORITY='' VALUE='"v=spf1 a mx ip4:%ip% -all"' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='16' RECORD='_dmarc' TYPE='TXT' PRIORITY='' VALUE='"v=DMARC1; p=quarantine; pct=100"' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
17
install/common/templates/dns/gmail.tpl
Executable file
17
install/common/templates/dns/gmail.tpl
Executable file
@@ -0,0 +1,17 @@
|
||||
ID='1' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns1%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='2' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns2%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='3' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns3%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='4' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns4%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='5' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns5%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='6' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns6%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='7' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns7%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='8' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns8%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='9' RECORD='@' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='10' RECORD='ftp' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='11' RECORD='www' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='12' RECORD='@' TYPE='MX' PRIORITY='1' VALUE='ASPMX.L.GOOGLE.COM.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='13' RECORD='@' TYPE='MX' PRIORITY='5' VALUE='ALT1.ASPMX.L.GOOGLE.COM.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='14' RECORD='@' TYPE='MX' PRIORITY='5' VALUE='ALT2.ASPMX.L.GOOGLE.COM.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='15' RECORD='@' TYPE='MX' PRIORITY='10' VALUE='ALT3.ASPMX.L.GOOGLE.COM.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='16' RECORD='@' TYPE='MX' PRIORITY='10' VALUE='ALT4.ASPMX.L.GOOGLE.COM.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='17' RECORD='@' TYPE='TXT' PRIORITY='' VALUE='"v=spf1 a mx ip4:%ip% include:_spf.google.com -all"' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
22
install/common/templates/dns/office365.tpl
Normal file
22
install/common/templates/dns/office365.tpl
Normal file
@@ -0,0 +1,22 @@
|
||||
ID='1' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns1%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='2' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns2%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='3' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns3%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='4' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns4%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='5' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns5%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='6' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns6%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='7' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns7%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='8' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns8%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='9' RECORD='@' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='10' RECORD='ftp' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='11' RECORD='www' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='12' RECORD='@' TYPE='TXT' PRIORITY='' VALUE='"v=spf1 a mx ip4:%ip% include:spf.protection.outlook.com -all"' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='13' RECORD='_dmarc' TYPE='TXT' PRIORITY='' VALUE='v=DMARC1; p=none; pct=100; fo=1'
|
||||
ID='14' RECORD='autodiscover' TYPE='CNAME' PRIORITY='' VALUE='autodiscover.outlook.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='15' RECORD='lyncdiscover' TYPE='CNAME' PRIORITY='' VALUE='webdir.online.lync.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='16' RECORD='sip' TYPE='CNAME' PRIORITY='' VALUE='sipdir.online.lync.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='17' RECORD='enterpriseregistration' TYPE='CNAME' PRIORITY='' VALUE='enterpriseregistration.windows.net.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='18' RECORD='enterpriseenrollment' TYPE='CNAME' PRIORITY='' VALUE='enterpriseenrollment.manage.microsoft.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='19' RECORD='_sip._tls' TYPE='SRV' PRIORITY='100' VALUE='1 443 sipdir.online.lync.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='20' RECORD='_sipfederationtls._tcp' TYPE='SRV' PRIORITY='100' VALUE='1 5061 sipfed.online.lync.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='21' RECORD='login' TYPE='CNAME' PRIORITY='' VALUE='login.microsoftonline.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='22' RECORD='mail' TYPE='CNAME' PRIORITY='' VALUE='mail.office365.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
15
install/common/templates/dns/zoho.tpl
Normal file
15
install/common/templates/dns/zoho.tpl
Normal file
@@ -0,0 +1,15 @@
|
||||
ID='1' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns1%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='2' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns2%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='3' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns3%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='4' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns4%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='5' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns5%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='6' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns6%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='7' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns7%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='8' RECORD='@' TYPE='NS' PRIORITY='' VALUE='%ns8%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='9' RECORD='@' TYPE='A' PRIORITY='' VALUE='%ip%' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='10' RECORD='ftp' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='11' RECORD='www' TYPE='CNAME' PRIORITY='' VALUE='%domain%.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='12' RECORD='@' TYPE='MX' PRIORITY='10' VALUE='mx.zoho.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='13' RECORD='@' TYPE='MX' PRIORITY='20' VALUE='mx2.zoho.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='14' RECORD='@' TYPE='MX' PRIORITY='50' VALUE='mx3.zoho.com.' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
ID='15' RECORD='@' TYPE='TXT' PRIORITY='' VALUE='"v=spf1 a mx ip4:%ip% include:zoho.com -all"' SUSPENDED='no' TIME='%time%' DATE='%date%'
|
||||
12
install/common/templates/email/examples/account_ready.html
Normal file
12
install/common/templates/email/examples/account_ready.html
Normal file
@@ -0,0 +1,12 @@
|
||||
Hello {{name}},
|
||||
|
||||
Your account has been created and ready to use.
|
||||
|
||||
https://{{hostname}}/login/
|
||||
Username: {{user}}
|
||||
Password: {{password}}
|
||||
|
||||
Best regards,
|
||||
|
||||
--
|
||||
{{appname}}
|
||||
@@ -0,0 +1,11 @@
|
||||
Database has been created.
|
||||
|
||||
Database: {{database}}
|
||||
Username: {{username}}
|
||||
Password: {{password}}
|
||||
SQL Manager: {{dbadmin}}
|
||||
|
||||
Best regards,
|
||||
|
||||
--
|
||||
{{appname}}
|
||||
@@ -0,0 +1,30 @@
|
||||
Mail account has been created.
|
||||
|
||||
Common Account Settings:
|
||||
Username: {{account}}@{{domain}}
|
||||
Password: {{password}}
|
||||
Webmail: {{webmail}}
|
||||
Hostname: {{hostname}}
|
||||
|
||||
IMAP Settings
|
||||
Authentication: Normal password
|
||||
SSL/TLS: Port 993
|
||||
STARTTLS: Port 143
|
||||
No encryption: Port 143
|
||||
|
||||
POP3 Settings
|
||||
Authentication: Normal password
|
||||
SSL/TLS: Port 995
|
||||
STARTTLS: Port 110
|
||||
No encryption: Port 110
|
||||
|
||||
SMTP Settings
|
||||
Authentication: Normal password
|
||||
SSL/TLS: Port 465
|
||||
STARTTLS: Port 587
|
||||
No encryption: Port 25
|
||||
|
||||
Best regards,
|
||||
|
||||
--
|
||||
{{appname}}
|
||||
10
install/common/templates/email/examples/ftp_credentials.html
Normal file
10
install/common/templates/email/examples/ftp_credentials.html
Normal file
@@ -0,0 +1,10 @@
|
||||
FTP account has been created and ready to use.
|
||||
|
||||
Hostname: {{domain}}
|
||||
Username: {{username}}
|
||||
Password: {{password}}
|
||||
|
||||
Best regards,
|
||||
|
||||
--
|
||||
{{appname}}
|
||||
15
install/common/templates/email/examples/reset_password.html
Normal file
15
install/common/templates/email/examples/reset_password.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<subject>{{hostname}} Password reset at {{date}}</subject>
|
||||
Hello {{name}},
|
||||
|
||||
To reset your {{appname}} password, please follow this link:
|
||||
https://{{hostname}}/reset/?action=confirm&user={{user}}&code={{resetcode}}
|
||||
|
||||
Alternatively, you may go to https://{{hostname}}/reset/?action=code&user={{user}} and enter the following reset code:
|
||||
{{resetcode}}
|
||||
|
||||
If you did not request password reset, please ignore this message and accept our apologies.
|
||||
|
||||
Best regards,
|
||||
|
||||
--
|
||||
{{appname}}
|
||||
119
install/common/templates/web/skel/document_errors/403.html
Normal file
119
install/common/templates/web/skel/document_errors/403.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Access Denied</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 8%;
|
||||
color: #5d5d5d;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.45em;
|
||||
font-weight: 700;
|
||||
color: #5d5d5d;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.animate__animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #5594cf;
|
||||
fill: #5594cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #c92127;
|
||||
fill: #c92127;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #ffcc33;
|
||||
fill: #ffcc33;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #5aba47;
|
||||
fill: #5aba47;
|
||||
}
|
||||
|
||||
.icon-large {
|
||||
height: 132px;
|
||||
width: 132px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
color: #707070;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 1.25em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.animate__delay-1s {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="animate__animated animate__fadeIn">
|
||||
<svg
|
||||
class="error icon-large fa-times-circle"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="animate__animated animate__fadeIn">Access Denied</h1>
|
||||
<div class="description-text animate__animated animate__fadeIn animate__delay-1s">
|
||||
<p>You do not have permission to view this page.</p>
|
||||
<p>Please check your credentials and try again.</p>
|
||||
<section class="footer"><strong>Error Code:</strong> 403</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
119
install/common/templates/web/skel/document_errors/404.html
Normal file
119
install/common/templates/web/skel/document_errors/404.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Page Not Found</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 8%;
|
||||
color: #5d5d5d;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.45em;
|
||||
font-weight: 700;
|
||||
color: #5d5d5d;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.animate__animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #5594cf;
|
||||
fill: #5594cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #c92127;
|
||||
fill: #c92127;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #ffcc33;
|
||||
fill: #ffcc33;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #5aba47;
|
||||
fill: #5aba47;
|
||||
}
|
||||
|
||||
.icon-large {
|
||||
height: 132px;
|
||||
width: 132px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
color: #707070;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 1.25em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.animate__delay-1s {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="animate__animated animate__fadeIn">
|
||||
<svg
|
||||
class="info icon-large fa-question-circle"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zM262.655 90c-54.497 0-89.255 22.957-116.549 63.758-3.536 5.286-2.353 12.415 2.715 16.258l34.699 26.31c5.205 3.947 12.621 3.008 16.665-2.122 17.864-22.658 30.113-35.797 57.303-35.797 20.429 0 45.698 13.148 45.698 32.958 0 14.976-12.363 22.667-32.534 33.976C247.128 238.528 216 254.941 216 296v4c0 6.627 5.373 12 12 12h56c6.627 0 12-5.373 12-12v-1.333c0-28.462 83.186-29.647 83.186-106.667 0-58.002-60.165-102-116.531-102zM256 338c-25.365 0-46 20.635-46 46 0 25.364 20.635 46 46 46s46-20.636 46-46c0-25.365-20.635-46-46-46z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="animate__animated animate__fadeIn">Page Not Found</h1>
|
||||
<div class="description-text animate__animated animate__fadeIn animate__delay-1s">
|
||||
<p>Oops! We couldn't find the page that you're looking for.</p>
|
||||
<p>Please check the address and try again.</p>
|
||||
<section class="footer"><strong>Error Code:</strong> 404</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
119
install/common/templates/web/skel/document_errors/410.html
Normal file
119
install/common/templates/web/skel/document_errors/410.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Resource is Gone</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 8%;
|
||||
color: #5d5d5d;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.45em;
|
||||
font-weight: 700;
|
||||
color: #5d5d5d;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.animate__animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #5594cf;
|
||||
fill: #5594cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #c92127;
|
||||
fill: #c92127;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #ffcc33;
|
||||
fill: #ffcc33;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #5aba47;
|
||||
fill: #5aba47;
|
||||
}
|
||||
|
||||
.icon-large {
|
||||
height: 132px;
|
||||
width: 132px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
color: #707070;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 1.25em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.animate__delay-1s {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="animate__animated animate__fadeIn">
|
||||
<svg
|
||||
class="info icon-large fa-sign-out-alt"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
d="M272 112v51.6h-96c-26.5 0-48 21.5-48 48v88.6c0 26.5 21.5 48 48 48h96v51.6c0 42.6 51.7 64.2 81.9 33.9l144-143.9c18.7-18.7 18.7-49.1 0-67.9l-144-144C323.8 48 272 69.3 272 112zm192 144L320 400v-99.7H176v-88.6h144V112l144 144zM96 64h84c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H96c-26.5 0-48 21.5-48 48v192c0 26.5 21.5 48 48 48h84c6.6 0 12 5.4 12 12v24c0 6.6-5.4 12-12 12H96c-53 0-96-43-96-96V160c0-53 43-96 96-96z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="animate__animated animate__fadeIn">Resource is Gone</h1>
|
||||
<div class="description-text animate__animated animate__fadeIn animate__delay-1s">
|
||||
<p>Oops! The requested resource is no longer available.</p>
|
||||
<p>Please check the address and try again.</p>
|
||||
<section class="footer"><strong>Error Code:</strong> 410</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
122
install/common/templates/web/skel/document_errors/50x.html
Normal file
122
install/common/templates/web/skel/document_errors/50x.html
Normal file
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Internal Server Error</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 8%;
|
||||
color: #5d5d5d;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.45em;
|
||||
font-weight: 700;
|
||||
color: #5d5d5d;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.animate__animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #5594cf;
|
||||
fill: #5594cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #c92127;
|
||||
fill: #c92127;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #ffcc33;
|
||||
fill: #ffcc33;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #5aba47;
|
||||
fill: #5aba47;
|
||||
}
|
||||
|
||||
.icon-large {
|
||||
height: 132px;
|
||||
width: 132px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
color: #707070;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 1.25em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.animate__delay-1s {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="animate__animated animate__fadeIn">
|
||||
<svg
|
||||
class="warning icon-large fa-exclamation-triangle"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 576 512"
|
||||
>
|
||||
<path
|
||||
d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="animate__animated animate__fadeIn">Internal Server Error</h1>
|
||||
<div class="description-text animate__animated animate__fadeIn animate__delay-1s">
|
||||
<p>Oops! Something went wrong.</p>
|
||||
<p>
|
||||
The server encountered an internal error or misconfiguration and was unable to
|
||||
complete your request.
|
||||
</p>
|
||||
<section class="footer"><strong>Error Code:</strong> 500</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
119
install/common/templates/web/skel/public_html/index.html
Normal file
119
install/common/templates/web/skel/public_html/index.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Coming Soon</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 8%;
|
||||
color: #5d5d5d;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.45em;
|
||||
font-weight: 700;
|
||||
color: #5d5d5d;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.animate__animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #5594cf;
|
||||
fill: #5594cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #c92127;
|
||||
fill: #c92127;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #ffcc33;
|
||||
fill: #ffcc33;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #5aba47;
|
||||
fill: #5aba47;
|
||||
}
|
||||
|
||||
.icon-large {
|
||||
height: 132px;
|
||||
width: 132px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
color: #707070;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 1.25em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.animate__delay-1s {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="animate__animated animate__fadeIn">
|
||||
<svg
|
||||
class="warning icon-large fa-hard-hat"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
d="M480 288c0-80.25-49.28-148.92-119.19-177.62L320 192V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v112l-40.81-81.62C81.28 139.08 32 207.75 32 288v64h448zm16 96H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h480a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="animate__animated animate__fadeIn">We're working on it!</h1>
|
||||
<div class="description-text animate__animated animate__fadeIn animate__delay-1s">
|
||||
<p>This site is currently under construction.</p>
|
||||
<p>Please check back soon.</p>
|
||||
<section class="footer"><strong>Domain:</strong> %domain%</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
3
install/common/templates/web/skel/public_html/robots.txt
Executable file
3
install/common/templates/web/skel/public_html/robots.txt
Executable file
@@ -0,0 +1,3 @@
|
||||
# hestiacp autogenerated robots.txt
|
||||
User-agent: *
|
||||
Crawl-delay: 10
|
||||
2
install/common/templates/web/suspend/.htaccess
Executable file
2
install/common/templates/web/suspend/.htaccess
Executable file
@@ -0,0 +1,2 @@
|
||||
ErrorDocument 403 /index.html
|
||||
ErrorDocument 404 /index.html
|
||||
117
install/common/templates/web/suspend/index.html
Normal file
117
install/common/templates/web/suspend/index.html
Normal file
@@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Access Denied</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 8%;
|
||||
color: #5d5d5d;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.45em;
|
||||
font-weight: 700;
|
||||
color: #5d5d5d;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.animate__animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #5594cf;
|
||||
fill: #5594cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #c92127;
|
||||
fill: #c92127;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #ffcc33;
|
||||
fill: #ffcc33;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #5aba47;
|
||||
fill: #5aba47;
|
||||
}
|
||||
|
||||
.icon-large {
|
||||
height: 132px;
|
||||
width: 132px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
color: #707070;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 1.25em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.animate__delay-1s {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="animate__animated animate__fadeIn">
|
||||
<svg
|
||||
class="error icon-large fa-exclamation-circle"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="animate__animated animate__fadeIn">This site is currently suspended</h1>
|
||||
<div class="description-text animate__animated animate__fadeIn animate__delay-1s">
|
||||
<p>If you are the owner of this site, please contact support for more information.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
119
install/common/templates/web/unassigned/index.html
Normal file
119
install/common/templates/web/unassigned/index.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Success!</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 8%;
|
||||
color: #5d5d5d;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
||||
"Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.75);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.45em;
|
||||
font-weight: 700;
|
||||
color: #5d5d5d;
|
||||
letter-spacing: -0.02em;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.animate__animated {
|
||||
animation-duration: 1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #5594cf;
|
||||
fill: #5594cf;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #c92127;
|
||||
fill: #c92127;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: #ffcc33;
|
||||
fill: #ffcc33;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #5aba47;
|
||||
fill: #5aba47;
|
||||
}
|
||||
|
||||
.icon-large {
|
||||
height: 132px;
|
||||
width: 132px;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
color: #707070;
|
||||
letter-spacing: -0.01em;
|
||||
font-size: 1.25em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.animate__delay-1s {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="animate__animated animate__fadeIn">
|
||||
<i class="success">
|
||||
<svg
|
||||
class="success icon-large fa-check-circle"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
>
|
||||
<path
|
||||
d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"
|
||||
></path>
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
<h1 class="animate__animated animate__fadeIn">Success!</h1>
|
||||
<div class="description-text animate__animated animate__fadeIn animate__delay-1s">
|
||||
<p>Your new web server is ready to use.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
96
install/deb/apache2/apache2.conf
Normal file
96
install/deb/apache2/apache2.conf
Normal file
@@ -0,0 +1,96 @@
|
||||
# It is split into several files forming the configuration hierarchy outlined
|
||||
# below, all located in the /etc/apache2/ directory:
|
||||
#
|
||||
# /etc/apache2/
|
||||
# |-- apache2.conf
|
||||
# | `-- ports.conf
|
||||
# |-- mods-enabled
|
||||
# | |-- *.load
|
||||
# | `-- *.conf
|
||||
# |-- conf.d
|
||||
# | `-- *
|
||||
|
||||
# Global configuration
|
||||
PidFile ${APACHE_PID_FILE}
|
||||
Timeout 30
|
||||
KeepAlive Off
|
||||
MaxKeepAliveRequests 100
|
||||
KeepAliveTimeout 10
|
||||
|
||||
<IfModule mpm_prefork_module>
|
||||
StartServers 8
|
||||
MinSpareServers 5
|
||||
MaxSpareServers 20
|
||||
ServerLimit 256
|
||||
MaxClients 200
|
||||
MaxRequestsPerChild 4000
|
||||
</IfModule>
|
||||
|
||||
<IfModule mpm_worker_module>
|
||||
StartServers 2
|
||||
MinSpareThreads 25
|
||||
MaxSpareThreads 75
|
||||
ThreadLimit 64
|
||||
ThreadsPerChild 25
|
||||
MaxClients 200
|
||||
MaxRequestsPerChild 4000
|
||||
</IfModule>
|
||||
|
||||
<IfModule mpm_event_module>
|
||||
StartServers 2
|
||||
MinSpareThreads 25
|
||||
MaxSpareThreads 75
|
||||
ThreadLimit 64
|
||||
ThreadsPerChild 25
|
||||
MaxClients 200
|
||||
MaxRequestsPerChild 4000
|
||||
</IfModule>
|
||||
|
||||
# These need to be set in /etc/apache2/envvars
|
||||
User ${APACHE_RUN_USER}
|
||||
Group ${APACHE_RUN_GROUP}
|
||||
#User www-data
|
||||
#Group www-data
|
||||
|
||||
AccessFileName .htaccess
|
||||
|
||||
<Files ~ "^\.ht">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy all
|
||||
</Files>
|
||||
|
||||
DefaultType None
|
||||
HostnameLookups Off
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
LogLevel warn
|
||||
|
||||
# Include module configuration:
|
||||
Include mods-enabled/*.load
|
||||
Include mods-enabled/*.conf
|
||||
|
||||
# Include list of ports to listen on and which to use for name based vhosts
|
||||
Include ports.conf
|
||||
|
||||
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %O" common
|
||||
LogFormat "%{Referer}i -> %U" referer
|
||||
LogFormat "%{User-agent}i" agent
|
||||
LogFormat "%b" bytes
|
||||
|
||||
IncludeOptional conf.d/*.conf
|
||||
IncludeOptional conf.d/domains/webmail.*.conf
|
||||
IncludeOptional conf.d/domains/*.conf
|
||||
|
||||
# Include the virtual host configurations:
|
||||
#Include sites-enabled/
|
||||
|
||||
ErrorDocument 403 /error/403.html
|
||||
ErrorDocument 404 /error/404.html
|
||||
ErrorDocument 500 /error/50x.html
|
||||
ErrorDocument 501 /error/50x.html
|
||||
ErrorDocument 502 /error/50x.html
|
||||
ErrorDocument 503 /error/50x.html
|
||||
ErrorDocument 506 /error/50x.html
|
||||
5
install/deb/apache2/hestia-event.conf
Normal file
5
install/deb/apache2/hestia-event.conf
Normal file
@@ -0,0 +1,5 @@
|
||||
<IfModule mpm_event_module>
|
||||
<FilesMatch \.php$>
|
||||
SetHandler "proxy:fcgi://127.0.0.1:9000"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
7
install/deb/apache2/status.conf
Normal file
7
install/deb/apache2/status.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
Listen 127.0.0.1:8081
|
||||
<Location /server-status>
|
||||
SetHandler server-status
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
Allow from 127.0.0.1
|
||||
</Location>
|
||||
18
install/deb/apache2/unassigned.conf
Normal file
18
install/deb/apache2/unassigned.conf
Normal file
@@ -0,0 +1,18 @@
|
||||
<VirtualHost directIP:directPORT>
|
||||
ServerName directIP
|
||||
DocumentRoot /var/www/html/
|
||||
Alias /error/ /var/www/document_errors/
|
||||
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost directIP:directSSLPORT>
|
||||
ServerName directIP
|
||||
DocumentRoot /var/www/html/
|
||||
Alias /error/ /var/www/document_errors/
|
||||
|
||||
SSLEngine on
|
||||
SSLVerifyClient none
|
||||
SSLCertificateFile /usr/local/hestia/ssl/certificate.crt
|
||||
SSLCertificateKeyFile /usr/local/hestia/ssl/certificate.key
|
||||
|
||||
</VirtualHost>
|
||||
12
install/deb/bind/named.conf
Normal file
12
install/deb/bind/named.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
// This is the primary configuration file for the BIND DNS server named.
|
||||
//
|
||||
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
|
||||
// structure of BIND configuration files in Debian, *BEFORE* you customize
|
||||
// this configuration file.
|
||||
//
|
||||
// If you are just adding zones, please do that in /etc/bind/named.conf.local
|
||||
|
||||
include "/etc/bind/named.conf.options";
|
||||
include "/etc/bind/named.conf.local";
|
||||
include "/etc/bind/named.conf.default-zones";
|
||||
|
||||
24
install/deb/bind/named.conf.options
Normal file
24
install/deb/bind/named.conf.options
Normal file
@@ -0,0 +1,24 @@
|
||||
options {
|
||||
directory "/var/cache/bind";
|
||||
// If there is a firewall between you and nameservers you want
|
||||
// to talk to, you may need to fix the firewall to allow multiple
|
||||
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
|
||||
// If your ISP provided one or more IP addresses for stable
|
||||
// nameservers, you probably want to use them as forwarders.
|
||||
// Uncomment the following block, and insert the addresses replacing
|
||||
// the all-0's placeholder.
|
||||
// forwarders {
|
||||
// 0.0.0.0;
|
||||
// };
|
||||
//========================================================================
|
||||
// If BIND logs error messages about the root key being expired,
|
||||
// you will need to update your keys. See https://www.isc.org/bind-keys
|
||||
//========================================================================
|
||||
dnssec-validation auto;
|
||||
auth-nxdomain no;
|
||||
allow-recursion { 127.0.0.1; ::1; };
|
||||
allow-transfer {"none";};
|
||||
hostname none;
|
||||
server-id none;
|
||||
version none;
|
||||
};
|
||||
88
install/deb/clamav/clamd.conf
Normal file
88
install/deb/clamav/clamd.conf
Normal file
@@ -0,0 +1,88 @@
|
||||
#Automatically Generated by clamav-daemon postinst
|
||||
#To reconfigure clamd run #dpkg-reconfigure clamav-daemon
|
||||
#Please read /usr/share/doc/clamav-daemon/README.Debian.gz for details
|
||||
LocalSocket /run/clamav/clamd.ctl
|
||||
FixStaleSocket true
|
||||
LocalSocketGroup clamav
|
||||
LocalSocketMode 666
|
||||
# TemporaryDirectory is not set to its default /tmp here to make overriding
|
||||
# the default with environment variables TMPDIR/TMP/TEMP possible
|
||||
User clamav
|
||||
ScanMail true
|
||||
ScanArchive true
|
||||
ArchiveBlockEncrypted false
|
||||
MaxDirectoryRecursion 15
|
||||
FollowDirectorySymlinks false
|
||||
FollowFileSymlinks false
|
||||
ReadTimeout 180
|
||||
MaxThreads 12
|
||||
MaxConnectionQueueLength 15
|
||||
LogSyslog false
|
||||
LogRotate true
|
||||
LogFacility LOG_LOCAL6
|
||||
LogClean false
|
||||
LogVerbose true
|
||||
PreludeEnable no
|
||||
PreludeAnalyzerName ClamAV
|
||||
DatabaseDirectory /var/lib/clamav
|
||||
OfficialDatabaseOnly false
|
||||
SelfCheck 3600
|
||||
Foreground false
|
||||
Debug false
|
||||
ScanPE true
|
||||
MaxEmbeddedPE 10M
|
||||
ScanOLE2 true
|
||||
ScanPDF true
|
||||
ScanHTML true
|
||||
MaxHTMLNormalize 10M
|
||||
MaxHTMLNoTags 2M
|
||||
MaxScriptNormalize 5M
|
||||
MaxZipTypeRcg 1M
|
||||
ScanSWF true
|
||||
ExitOnOOM false
|
||||
LeaveTemporaryFiles false
|
||||
AlgorithmicDetection true
|
||||
ScanELF true
|
||||
IdleTimeout 30
|
||||
CrossFilesystems true
|
||||
PhishingSignatures true
|
||||
PhishingScanURLs true
|
||||
PhishingAlwaysBlockSSLMismatch false
|
||||
PhishingAlwaysBlockCloak false
|
||||
PartitionIntersection false
|
||||
DetectPUA false
|
||||
ScanPartialMessages false
|
||||
HeuristicScanPrecedence false
|
||||
StructuredDataDetection false
|
||||
CommandReadTimeout 5
|
||||
SendBufTimeout 200
|
||||
MaxQueue 100
|
||||
ExtendedDetectionInfo true
|
||||
OLE2BlockMacros false
|
||||
AllowAllMatchScan true
|
||||
ForceToDisk false
|
||||
DisableCertCheck false
|
||||
DisableCache false
|
||||
MaxScanTime 120000
|
||||
MaxScanSize 100M
|
||||
MaxFileSize 25M
|
||||
MaxRecursion 16
|
||||
MaxFiles 10000
|
||||
MaxPartitions 50
|
||||
MaxIconsPE 100
|
||||
PCREMatchLimit 10000
|
||||
PCRERecMatchLimit 5000
|
||||
PCREMaxFileSize 25M
|
||||
ScanXMLDOCS true
|
||||
ScanHWP3 true
|
||||
MaxRecHWP3 16
|
||||
StreamMaxLength 25M
|
||||
LogFile /var/log/clamav/clamav.log
|
||||
LogTime true
|
||||
LogFileUnlock false
|
||||
LogFileMaxSize 0
|
||||
Bytecode true
|
||||
BytecodeSecurity TrustSigned
|
||||
BytecodeTimeout 60000
|
||||
PidFile /run/clamav/clamd.pid
|
||||
OnAccessMaxFileSize 5M
|
||||
30
install/deb/deb_signing.key
Normal file
30
install/deb/deb_signing.key
Normal file
@@ -0,0 +1,30 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.12 (GNU/Linux)
|
||||
|
||||
mQENBFJIGbEBCAC8SHOOFo7iDTbnC2GhNZ+uBGCh226Dn1QPoFZNFM/DNakHZ6rD
|
||||
G3wzr8++eKz4fJual/VLllE2N9XDPuxbozb3LLkcyY1WzJqtIXbXhFGQ/SuIeT+x
|
||||
QY90XU6t2Ckze2c+zUniAWmJ8GSyVmXOoc9JxAQ1u47wvGXLzrjWXc8u8PNRYXuf
|
||||
fZplTL+dFu9P0d6lP8FGsV+r9wXvvazpRTz3+H8PKrGCYT55ZQIEdG9Jgamylto2
|
||||
oVPFXkwGML+TLw6oeCIBuz2y2vtivphW4MJ3ifQjDj7k3n+DTIxfDFs8lB6VRhhY
|
||||
2nMHCrcZC6U2mhmXmr6O4s1fu6irBVx05ejPABEBAAG0IFNlcmdoZXkgUm9kaW4g
|
||||
PHNraWRAdmVzdGFjcC5jb20+iQE4BBMBAgAiBQJSSBmxAhsDBgsJCAcDAgYVCAIJ
|
||||
CgsEFgIDAQIeAQIXgAAKCRBCxbITCh93FPdqB/93GjV9g+wBfeZYLHQK9MDU2wBb
|
||||
VloYOJJae6IvYKYQVAJayD3PbHdpxrF8s9e23vdnmb9jKu6jX6oV54EIyqP2HPiN
|
||||
QYc8wcea+eSHerznBixCtoQh8mtdWGFeN71zU/ig7L5qlOVF/EmxDVZTFUeivFxh
|
||||
IV6qyBnktQKktE45585yKZyyLtfGoXA54DGK69OtJFh+wdkKEMmUXocMl7wUrxW6
|
||||
Cx2CuKeEXEgvwu8mRHQi3S3T9XP456qWEn5dWyMVcP660IzEuZfSJApZusNK7zG3
|
||||
WMy0/EuX7xHNY3mcNxTOUN1LsO7iHnhHD9+iKWJo9parGkMZzc92MpjDK/g7uQEN
|
||||
BFJIGbEBCAC7k5QEA9WQM7E3ceNaeLMrA9lXfuzaNCcySq7ONdVAa5PxzbSKdHvz
|
||||
QFoL1VFqBTYQ038lbil1XqnoM0zvIfAI3LcpS8sq92El/vPxp6jZh2Ari9Uw7x95
|
||||
k2cZMgI67g+zQMGdjVRA155nFQRCgg000xU4F7JA6+WsuLlVUmccsDv7YWJExMtC
|
||||
YPxiuz5DFu8RALnw4Ckts+dbwsrcvUHhkm9b6RAsdCKjjRpUZjLgdltjH83gUVvt
|
||||
i1YmdjjsVpt95dtsaG+ad852g/Rk8EdxNMkjPF6HLA67CLADP9wYaj80yPcPtylS
|
||||
ycvPtcclVeHkFBRVM8xZpQd4iD19MWI1ABEBAAGJAR8EGAECAAkFAlJIGbECGwwA
|
||||
CgkQQsWyEwofdxQ7tQgAhB0FwTs7L8Qr63DHC2yAnXVxgtTAY1/36CccNXVculyR
|
||||
+EkLcwahms9AKhz7eQb+Mud+5vH0GRohLp2npgO38CjVUfIP5d+Y6dsthmrkF6p8
|
||||
XdV1dVK9vWX+i/YZSw/Mded30Cq4P2Yhq9EaemMT0rtli8lz2NnkZ9dFJZk1lzJC
|
||||
CZmRpbjSNWqRU4f7qyh21lYk/OC/0XE8fh8CaO23TZ+6gBionoCztwb7NyC9OArN
|
||||
qYlNnbmh9iNqdblykPS3bkjf34n2xyMgnIehNrM89tk8PY4UfNPhgT1TMD9W3Svq
|
||||
ynNZvLuF/FIDwDeC1qcfjGbfDn9fXO/lMIIRooQYKQ==
|
||||
=J2HJ
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
2
install/deb/exim/dnsbl.conf
Normal file
2
install/deb/exim/dnsbl.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
bl.spamcop.net
|
||||
zen.spamhaus.org
|
||||
476
install/deb/exim/exim4.conf.4.94.template
Normal file
476
install/deb/exim/exim4.conf.4.94.template
Normal file
@@ -0,0 +1,476 @@
|
||||
######################################################################
|
||||
# #
|
||||
# Exim configuration file for Hestia Control Panel #
|
||||
# #
|
||||
######################################################################
|
||||
|
||||
#SPAMASSASSIN = yes
|
||||
#SPAM_SCORE = 50
|
||||
#SPAM_REJECT_SCORE = 100
|
||||
#CLAMD = yes
|
||||
|
||||
smtp_banner = $smtp_active_hostname
|
||||
smtp_active_hostname = ${lookup dnsdb{>: defer_never,ptr=$interface_address}{${listextract{1}{$value}}}{$primary_hostname}}
|
||||
add_environment = <; PATH=/bin:/usr/bin
|
||||
keep_environment =
|
||||
disable_ipv6 = true
|
||||
|
||||
smtputf8_advertise_hosts =
|
||||
domainlist local_domains = dsearch;/etc/exim4/domains/
|
||||
domainlist relay_to_domains = dsearch;/etc/exim4/domains/
|
||||
hostlist relay_from_hosts = 127.0.0.1
|
||||
hostlist whitelist = net-iplsearch;/etc/exim4/white-blocks.conf
|
||||
hostlist spammers = net-iplsearch;/etc/exim4/spam-blocks.conf
|
||||
no_local_from_check
|
||||
untrusted_set_sender = *
|
||||
acl_smtp_connect = acl_check_spammers
|
||||
acl_smtp_mail = acl_check_mail
|
||||
acl_smtp_rcpt = acl_check_rcpt
|
||||
acl_smtp_data = acl_check_data
|
||||
acl_smtp_mime = acl_check_mime
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
spamd_address = 127.0.0.1 783
|
||||
.endif
|
||||
|
||||
.ifdef CLAMD
|
||||
av_scanner = clamd: /run/clamav/clamd.ctl
|
||||
.endif
|
||||
|
||||
log_selector = +tls_sni
|
||||
|
||||
tls_advertise_hosts = *
|
||||
|
||||
# We test that $tls_in_sni is a valid domain, by an arbitrary email address foo@domain.tld .
|
||||
# Then, we extract the domain with a function that would fail if the email address is invalid.
|
||||
# If the certificate exists, we will use it, otherwise the default certificate in /etc/ssl will be used.
|
||||
tls_certificate = \
|
||||
${if and {\
|
||||
{ eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
|
||||
{ exists{/usr/local/hestia/ssl/mail/$tls_in_sni.crt} }\
|
||||
}\
|
||||
{/usr/local/hestia/ssl/mail/$tls_in_sni.crt}\
|
||||
{/usr/local/hestia/ssl/certificate.crt}\
|
||||
}
|
||||
|
||||
tls_privatekey = \
|
||||
${if and {\
|
||||
{ eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
|
||||
{ exists{/usr/local/hestia/ssl/mail/$tls_in_sni.key} }\
|
||||
}\
|
||||
{/usr/local/hestia/ssl/mail/$tls_in_sni.key}\
|
||||
{/usr/local/hestia/ssl/certificate.key}\
|
||||
}
|
||||
|
||||
daemon_smtp_ports = 25 : 465 : 587
|
||||
tls_on_connect_ports = 465
|
||||
tls_require_ciphers = PERFORMANCE:-RSA:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:%SERVER_PRECEDENCE
|
||||
never_users = root
|
||||
host_lookup = *
|
||||
rfc1413_hosts = *
|
||||
rfc1413_query_timeout = 0s
|
||||
ignore_bounce_errors_after = 2d
|
||||
timeout_frozen_after = 7d
|
||||
|
||||
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
|
||||
DKIM_FILE = /etc/exim4/domains/${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains/}}/dkim.pem
|
||||
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
|
||||
|
||||
OUTGOING_IP = /etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/ip
|
||||
|
||||
SMTP_RELAY_FILE = ${if exists{/etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/smtp_relay.conf}{/etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/smtp_relay.conf}{/etc/exim4/smtp_relay.conf}}
|
||||
SMTP_RELAY_HOST = ${lookup{host}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_PORT = ${lookup{port}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_USER = ${lookup{user}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_PASS = ${lookup{pass}lsearch{SMTP_RELAY_FILE}}
|
||||
|
||||
# Custom Filter
|
||||
system_filter = /etc/exim4/system.filter
|
||||
system_filter_user = Debian-exim
|
||||
|
||||
######################################################################
|
||||
# ACL CONFIGURATION #
|
||||
# Specifies access control lists for incoming SMTP mail #
|
||||
######################################################################
|
||||
|
||||
acl_not_smtp = acl_not_smtp
|
||||
|
||||
begin acl
|
||||
|
||||
# Limit per user for PHP scripts
|
||||
acl_not_smtp:
|
||||
deny message = Website of user $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
|
||||
ratelimit = 200 / 1h / $authenticated_id
|
||||
|
||||
warn ratelimit = 100 / 1h / strict / $authenticated_id
|
||||
log_message = Sender rate [limitlog]: log / account / $authenticated_id / $sender_rate / $sender_rate_period
|
||||
|
||||
accept
|
||||
|
||||
acl_check_spammers:
|
||||
accept hosts = +whitelist
|
||||
|
||||
drop message = Your host in blacklist on this server.
|
||||
log_message = Host in blacklist
|
||||
hosts = +spammers
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_mail:
|
||||
deny condition = ${if eq{$sender_helo_name}{}}
|
||||
message = HELO required before MAIL
|
||||
|
||||
drop !authenticated = *
|
||||
message = Helo name contains an IP address (HELO was $sender_helo_name) and not is valid
|
||||
condition = ${if match{$sender_helo_name}{\N((\d{1,3}[.-]\d{1,3}[.-]\d{1,3}[.-]\d{1,3})|([0-9a-f]{8})|([0-9A-F]{8}))\N}{yes}{no}}
|
||||
condition = ${if match {${lookup dnsdb{>: defer_never,ptr=$sender_host_address}}\}{$sender_helo_name}{no}{yes}}
|
||||
delay = 45s
|
||||
|
||||
drop !authenticated = *
|
||||
condition = ${if isip{$sender_helo_name}}
|
||||
message = Access denied - Invalid HELO name (See RFC2821 4.1.3)
|
||||
|
||||
drop !authenticated = *
|
||||
condition = ${if eq{[$interface_address]}{$sender_helo_name}}
|
||||
message = $interface_address is _my_ address
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_rcpt:
|
||||
accept hosts = :
|
||||
|
||||
# Limit per email account for SMTP auhenticated users
|
||||
deny message = Email account $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
|
||||
set acl_c_msg_limit = ${if exists{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{${lookup {$authenticated_id} lsearch{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{$value}{${readfile{/etc/exim4/limit.conf}}}}}{${readfile{/etc/exim4/limit.conf}}} }
|
||||
ratelimit = $acl_c_msg_limit / 1h / strict/ $authenticated_id
|
||||
|
||||
warn ratelimit = ${eval:$acl_c_msg_limit / 2} / 1h / strict / $authenticated_id
|
||||
log_message = Sender rate [limitlog]: log / email / $authenticated_id / $sender_rate / $sender_rate_period
|
||||
|
||||
deny message = Restricted characters in address
|
||||
domains = +local_domains
|
||||
local_parts = ^[.] : ^.*[@%!/|]
|
||||
|
||||
deny message = Restricted characters in address
|
||||
domains = !+local_domains
|
||||
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
|
||||
|
||||
require verify = sender
|
||||
|
||||
accept hosts = +relay_from_hosts
|
||||
control = submission
|
||||
|
||||
accept authenticated = *
|
||||
control = submission/domain=
|
||||
|
||||
deny message = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
|
||||
hosts = !+whitelist
|
||||
dnslists = ${readfile {/etc/exim4/dnsbl.conf}{:}}
|
||||
|
||||
require message = relay not permitted
|
||||
domains = +local_domains : +relay_to_domains
|
||||
|
||||
deny message = smtp auth required
|
||||
sender_domains = +local_domains
|
||||
!authenticated = *
|
||||
|
||||
require verify = recipient
|
||||
|
||||
.ifdef CLAMD
|
||||
warn set acl_m0 = no
|
||||
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/antivirus}{yes}{no}}
|
||||
set acl_m0 = yes
|
||||
.endif
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
warn set acl_m1 = no
|
||||
set acl_m3 = no
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/antispam}{yes}{no}}
|
||||
set acl_m1 = yes
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/reject_spam}{yes}{no}}
|
||||
set acl_m3 = yes
|
||||
.endif
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_data:
|
||||
.ifdef CLAMD
|
||||
deny message = Message contains a virus ($malware_name) and has been rejected
|
||||
malware = */defer_ok
|
||||
condition = ${if eq{$acl_m0}{yes}{yes}{no}}
|
||||
.endif
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
warn !authenticated = *
|
||||
hosts = !+relay_from_hosts
|
||||
condition = ${if < {$message_size}{1024K}}
|
||||
condition = ${if eq{$acl_m1}{yes}{yes}{no}}
|
||||
spam = debian-spamd:true/defer_ok
|
||||
add_header = X-Spam-Score: $spam_score_int
|
||||
add_header = X-Spam-Bar: $spam_bar
|
||||
add_header = X-Spam-Report: $spam_report
|
||||
set acl_m2 = $spam_score_int
|
||||
|
||||
warn condition = ${if !eq{$acl_m2}{} {yes}{no}}
|
||||
condition = ${if >{$acl_m2}{SPAM_SCORE} {yes}{no}}
|
||||
add_header = X-Spam-Status: Yes
|
||||
message = SpamAssassin detected spam (from $sender_address to $recipients).
|
||||
|
||||
# Deny spam at high score if spam score > SPAM_REJECT_SCORE and delete_spam is enabled
|
||||
deny message = This message scored $spam_score spam points
|
||||
spam = debian-spamd:true
|
||||
condition = ${if eq{$acl_m3}{yes}{yes}{no}}
|
||||
condition = ${if >{$spam_score_int}{SPAM_REJECT_SCORE}{1}{0}}
|
||||
.endif
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_mime:
|
||||
deny message = Blacklisted file extension detected
|
||||
condition = ${if match {${lc:$mime_filename}}{\N(\.ace|\.ade|\.adp|\.app|\.arj|\.asp|\.aspx|\.asx|\.bas|\.bat|\.cab|\.cer|\.chm|\.cmd|\.cnt|\.com|\.cpl|\.crt|\.csh|\.der|\.diagcab|\.dll|\.efi|\.exe|\.fla|\.fon|\.fxp|\.gadget|\.grp|\.hlp|\.hpj|\.hta|\.htc|\.img|\.inf|\.ins|\.iso|\.isp|\.its|\.jar|\.jnlp|\.js|\.jse|\.ksh|\.lib|\.lnk|\.mad|\.maf|\.mag|\.mam|\.maq|\.mar|\.mas|\.mat|\.mau|\.mav|\.maw|\.mcf|\.mda|\.mdb|\.mde|\.mdt|\.mdw|\.mdz|\.msc|\.msh|\.msh1|\.msh1xml|\.msh2|\.msh2xml|\.mshxml|\.msi|\.msp|\.mst|\.msu|\.ops|\.osd|\.pcd|\.pif|\.pl|\.plg|\.prf|\.prg|\.printerexport|\.ps1|\.ps1xml|\.ps2|\.ps2xml|\.psc1|\.psc2|\.psd1|\.psdm1|\.pst|\.py|\.pyc|\.pyo|\.pyw|\.pyz|\.pyzw|\.reg|\.scf|\.scr|\.sct|\.sfx|\.shb|\.shs|\.swf|\.sys|\.theme|\.tmp|\.ttf|\.url|\.vb|\.vba|\.vbe|\.vbp|\.vbs|\.vhd|\.vhdx|\.vsmacros|\.vsw|\.vxd|\.webpnp|\.website|\.wim|\.ws|\.wsc|\.wsf|\.wsh|\.xbap|\.xll|\.xnk)$\N}{1}{0}}
|
||||
|
||||
accept
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# AUTHENTICATION CONFIGURATION #
|
||||
######################################################################
|
||||
begin authenticators
|
||||
|
||||
smtp_relay_login:
|
||||
driver = plaintext
|
||||
public_name = LOGIN
|
||||
hide client_send = : SMTP_RELAY_USER : SMTP_RELAY_PASS
|
||||
|
||||
dovecot_plain:
|
||||
driver = dovecot
|
||||
public_name = PLAIN
|
||||
server_socket = /run/dovecot/auth-client
|
||||
server_set_id = $auth1
|
||||
|
||||
dovecot_login:
|
||||
driver = dovecot
|
||||
public_name = LOGIN
|
||||
server_socket = /run/dovecot/auth-client
|
||||
server_set_id = $auth1
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# ROUTERS CONFIGURATION #
|
||||
# Specifies how addresses are handled #
|
||||
######################################################################
|
||||
begin routers
|
||||
|
||||
send_via_unauthenticated_smtp_relay:
|
||||
driver = manualroute
|
||||
address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
|
||||
domains = !+local_domains
|
||||
require_files = SMTP_RELAY_FILE
|
||||
condition = ${if eq{SMTP_RELAY_USER}{}}
|
||||
transport = remote_smtp
|
||||
route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
|
||||
no_more
|
||||
no_verify
|
||||
|
||||
send_via_smtp_relay:
|
||||
driver = manualroute
|
||||
address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
|
||||
domains = !+local_domains
|
||||
require_files = SMTP_RELAY_FILE
|
||||
transport = smtp_relay_smtp
|
||||
route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
|
||||
no_more
|
||||
no_verify
|
||||
|
||||
dnslookup:
|
||||
driver = dnslookup
|
||||
domains = !+local_domains
|
||||
transport = remote_smtp
|
||||
no_more
|
||||
|
||||
userforward:
|
||||
driver = redirect
|
||||
check_local_user
|
||||
file = $home/.forward
|
||||
require_files = ${local_part}:+${home}/.forward
|
||||
domains = +local_domains
|
||||
allow_filter
|
||||
no_verify
|
||||
no_expn
|
||||
check_ancestor
|
||||
file_transport = address_file
|
||||
pipe_transport = address_pipe
|
||||
reply_transport = address_reply
|
||||
|
||||
procmail:
|
||||
driver = accept
|
||||
check_local_user
|
||||
require_files = ${local_part}:+${home}/.procmailrc:/usr/bin/procmail
|
||||
transport = procmail
|
||||
no_verify
|
||||
|
||||
autoreplay:
|
||||
driver = accept
|
||||
require_files = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${local_part}.msg
|
||||
condition = ${if exists{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${local_part}.msg}{yes}{no}}
|
||||
retry_use_local_part
|
||||
transport = userautoreply
|
||||
unseen
|
||||
|
||||
aliases:
|
||||
driver = redirect
|
||||
headers_add = X-redirected: yes
|
||||
data = ${extract{1}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}}}}
|
||||
require_files = /etc/exim4/domains/$domain/aliases
|
||||
redirect_router = dnslookup
|
||||
pipe_transport = address_pipe
|
||||
unseen
|
||||
|
||||
localuser_fwd_only:
|
||||
driver = accept
|
||||
transport = devnull
|
||||
condition = ${if exists{/etc/exim4/domains/$domain/fwd_only}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/fwd_only}{true}{false}}}}
|
||||
|
||||
localuser_spam:
|
||||
driver = accept
|
||||
transport = local_spam_delivery
|
||||
condition = ${if eq {${if match{$h_X-Spam-Status:}{\N^Yes\N}{yes}{no}}} {${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{yes}{no_such_user}}}}
|
||||
|
||||
localuser:
|
||||
driver = accept
|
||||
transport = local_delivery
|
||||
condition = ${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{true}{false}}
|
||||
|
||||
catchall:
|
||||
driver = redirect
|
||||
headers_add = X-redirected: yes
|
||||
require_files = /etc/exim4/domains/$domain/aliases
|
||||
data = ${extract{1}{:}{${lookup{*@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}}}}
|
||||
file_transport = local_delivery
|
||||
redirect_router = dnslookup
|
||||
condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{false}{true}}
|
||||
|
||||
terminate_alias:
|
||||
driver = accept
|
||||
transport = devnull
|
||||
condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{true}{false}}
|
||||
|
||||
######################################################################
|
||||
# TRANSPORTS CONFIGURATION #
|
||||
######################################################################
|
||||
begin transports
|
||||
|
||||
smtp_relay_smtp:
|
||||
driver = smtp
|
||||
hosts_require_auth = $host_address
|
||||
hosts_require_tls = $host_address
|
||||
|
||||
remote_smtp:
|
||||
driver = smtp
|
||||
helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
|
||||
dkim_domain = DKIM_DOMAIN
|
||||
dkim_selector = mail
|
||||
dkim_private_key = DKIM_PRIVATE_KEY
|
||||
dkim_canon = relaxed
|
||||
dkim_strict = 0
|
||||
hosts_try_fastopen = !*.l.google.com
|
||||
interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
|
||||
|
||||
procmail:
|
||||
driver = pipe
|
||||
command = "/usr/bin/procmail -d $local_part"
|
||||
return_path_add
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
user = $local_part
|
||||
initgroups
|
||||
return_output
|
||||
|
||||
local_delivery:
|
||||
driver = appendfile
|
||||
maildir_format
|
||||
maildir_use_size_file
|
||||
user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}
|
||||
group = mail
|
||||
create_directory
|
||||
directory_mode = 770
|
||||
mode = 660
|
||||
use_lockfile = no
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}"
|
||||
quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}M
|
||||
quota_warn_threshold = 75%
|
||||
|
||||
local_spam_delivery:
|
||||
driver = appendfile
|
||||
maildir_format
|
||||
maildir_use_size_file
|
||||
user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}
|
||||
group = mail
|
||||
create_directory
|
||||
directory_mode = 770
|
||||
mode = 660
|
||||
use_lockfile = no
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}/.Spam"
|
||||
quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}M
|
||||
quota_directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}"
|
||||
quota_warn_threshold = 75%
|
||||
|
||||
address_pipe:
|
||||
driver = pipe
|
||||
return_output
|
||||
|
||||
address_file:
|
||||
driver = appendfile
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
|
||||
address_reply:
|
||||
driver = autoreply
|
||||
|
||||
userautoreply:
|
||||
driver = autoreply
|
||||
file = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${extract{1}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/accounts}}}}.msg
|
||||
from = "${extract{1}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/accounts}}}}@${lookup{$domain}dsearch{/etc/exim4/domains/}}"
|
||||
headers = Content-Type: text/plain; charset=utf-8;\nContent-Transfer-Encoding: 8bit
|
||||
subject = "${if def:h_Subject: {Autoreply: \"${rfc2047:$h_Subject:}\"} {Autoreply Message}}"
|
||||
to = "${sender_address}"
|
||||
|
||||
devnull:
|
||||
driver = appendfile
|
||||
file = /dev/null
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# RETRY CONFIGURATION #
|
||||
######################################################################
|
||||
begin retry
|
||||
|
||||
# Address or Domain Error Retries
|
||||
# ----------------- ----- -------
|
||||
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# REWRITE CONFIGURATION #
|
||||
######################################################################
|
||||
begin rewrite
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
512
install/deb/exim/exim4.conf.4.95.template
Normal file
512
install/deb/exim/exim4.conf.4.95.template
Normal file
@@ -0,0 +1,512 @@
|
||||
######################################################################
|
||||
# #
|
||||
# Exim configuration file for Hestia Control Panel #
|
||||
# #
|
||||
######################################################################
|
||||
|
||||
#SPAMASSASSIN = yes
|
||||
#SPAM_SCORE = 50
|
||||
#SPAM_REJECT_SCORE = 100
|
||||
#CLAMD = yes
|
||||
|
||||
smtp_banner = $smtp_active_hostname
|
||||
smtp_active_hostname = ${lookup dnsdb{>: defer_never,ptr=$interface_address}{${listextract{1}{$value}}}{$primary_hostname}}
|
||||
add_environment = <; PATH=/bin:/usr/bin
|
||||
keep_environment =
|
||||
disable_ipv6 = true
|
||||
|
||||
SRS_SECRET = ${readfile{/etc/exim4/srs.conf}}
|
||||
|
||||
smtputf8_advertise_hosts =
|
||||
domainlist local_domains = dsearch;/etc/exim4/domains/
|
||||
domainlist relay_to_domains = dsearch;/etc/exim4/domains/
|
||||
hostlist relay_from_hosts = 127.0.0.1
|
||||
hostlist whitelist = net-iplsearch;/etc/exim4/white-blocks.conf
|
||||
hostlist spammers = net-iplsearch;/etc/exim4/spam-blocks.conf
|
||||
no_local_from_check
|
||||
untrusted_set_sender = *
|
||||
acl_smtp_connect = acl_check_spammers
|
||||
acl_smtp_mail = acl_check_mail
|
||||
acl_smtp_rcpt = acl_check_rcpt
|
||||
acl_smtp_data = acl_check_data
|
||||
acl_smtp_mime = acl_check_mime
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
spamd_address = 127.0.0.1 783
|
||||
.endif
|
||||
|
||||
.ifdef CLAMD
|
||||
av_scanner = clamd: /run/clamav/clamd.ctl
|
||||
.endif
|
||||
|
||||
log_selector = +tls_sni
|
||||
|
||||
tls_advertise_hosts = *
|
||||
|
||||
# We test that $tls_in_sni is a valid domain, by an arbitrary email address foo@domain.tld .
|
||||
# Then, we extract the domain with a function that would fail if the email address is invalid.
|
||||
# If the certificate exists, we will use it, otherwise the default certificate in /etc/ssl will be used.
|
||||
tls_certificate = \
|
||||
${if and {\
|
||||
{ eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
|
||||
{ exists{/usr/local/hestia/ssl/mail/$tls_in_sni.crt} }\
|
||||
}\
|
||||
{/usr/local/hestia/ssl/mail/$tls_in_sni.crt}\
|
||||
{/usr/local/hestia/ssl/certificate.crt}\
|
||||
}
|
||||
|
||||
tls_privatekey = \
|
||||
${if and {\
|
||||
{ eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
|
||||
{ exists{/usr/local/hestia/ssl/mail/$tls_in_sni.key} }\
|
||||
}\
|
||||
{/usr/local/hestia/ssl/mail/$tls_in_sni.key}\
|
||||
{/usr/local/hestia/ssl/certificate.key}\
|
||||
}
|
||||
|
||||
daemon_smtp_ports = 25 : 465 : 587
|
||||
tls_on_connect_ports = 465
|
||||
tls_require_ciphers = PERFORMANCE:-RSA:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:%SERVER_PRECEDENCE
|
||||
never_users = root
|
||||
host_lookup = *
|
||||
rfc1413_hosts = *
|
||||
rfc1413_query_timeout = 0s
|
||||
ignore_bounce_errors_after = 2d
|
||||
timeout_frozen_after = 7d
|
||||
|
||||
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
|
||||
DKIM_FILE = /etc/exim4/domains/${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains/}}/dkim.pem
|
||||
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
|
||||
|
||||
OUTGOING_IP = /etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/ip
|
||||
|
||||
SMTP_RELAY_FILE = ${if exists{/etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/smtp_relay.conf}{/etc/exim4/domains/${lookup{$sender_address_domain}dsearch{/etc/exim4/domains}}/smtp_relay.conf}{/etc/exim4/smtp_relay.conf}}
|
||||
SMTP_RELAY_HOST = ${lookup{host}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_PORT = ${lookup{port}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_USER = ${lookup{user}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_PASS = ${lookup{pass}lsearch{SMTP_RELAY_FILE}}
|
||||
|
||||
# Custom Filter
|
||||
system_filter = /etc/exim4/system.filter
|
||||
system_filter_user = Debian-exim
|
||||
|
||||
######################################################################
|
||||
# ACL CONFIGURATION #
|
||||
# Specifies access control lists for incoming SMTP mail #
|
||||
######################################################################
|
||||
|
||||
acl_not_smtp = acl_not_smtp
|
||||
|
||||
begin acl
|
||||
|
||||
# Limit per user for PHP scripts
|
||||
acl_not_smtp:
|
||||
deny message = Website of user $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
|
||||
ratelimit = 200 / 1h / $authenticated_id
|
||||
|
||||
warn ratelimit = 100 / 1h / strict / $authenticated_id
|
||||
log_message = Sender rate [limitlog]: log / account / $authenticated_id / $sender_rate / $sender_rate_period
|
||||
|
||||
accept
|
||||
|
||||
acl_check_spammers:
|
||||
accept hosts = +whitelist
|
||||
|
||||
drop message = Your host in blacklist on this server.
|
||||
log_message = Host in blacklist
|
||||
hosts = +spammers
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_mail:
|
||||
deny condition = ${if eq{$sender_helo_name}{}}
|
||||
message = HELO required before MAIL
|
||||
|
||||
drop !authenticated = *
|
||||
message = Helo name contains an IP address (HELO was $sender_helo_name) and not is valid
|
||||
condition = ${if match{$sender_helo_name}{\N((\d{1,3}[.-]\d{1,3}[.-]\d{1,3}[.-]\d{1,3})|([0-9a-f]{8})|([0-9A-F]{8}))\N}{yes}{no}}
|
||||
condition = ${if match {${lookup dnsdb{>: defer_never,ptr=$sender_host_address}}\}{$sender_helo_name}{no}{yes}}
|
||||
delay = 45s
|
||||
|
||||
drop !authenticated = *
|
||||
condition = ${if isip{$sender_helo_name}}
|
||||
message = Access denied - Invalid HELO name (See RFC2821 4.1.3)
|
||||
|
||||
drop !authenticated = *
|
||||
condition = ${if eq{[$interface_address]}{$sender_helo_name}}
|
||||
message = $interface_address is _my_ address
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_rcpt:
|
||||
accept hosts = :
|
||||
|
||||
# Limit per email account for SMTP auhenticated users
|
||||
deny message = Email account $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
|
||||
set acl_c_msg_limit = ${if exists{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{${lookup {$authenticated_id} lsearch{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{$value}{${readfile{/etc/exim4/limit.conf}}}}}{${readfile{/etc/exim4/limit.conf}}} }
|
||||
ratelimit = $acl_c_msg_limit / 1h / strict/ $authenticated_id
|
||||
|
||||
warn ratelimit = ${eval:$acl_c_msg_limit / 2} / 1h / strict / $authenticated_id
|
||||
log_message = Sender rate [limitlog]: log / email / $authenticated_id / $sender_rate / $sender_rate_period
|
||||
|
||||
deny message = Restricted characters in address
|
||||
domains = +local_domains
|
||||
local_parts = ^[.] : ^.*[@%!/|]
|
||||
|
||||
deny message = Restricted characters in address
|
||||
domains = !+local_domains
|
||||
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
|
||||
|
||||
require verify = sender
|
||||
|
||||
accept hosts = +relay_from_hosts
|
||||
control = submission
|
||||
|
||||
accept authenticated = *
|
||||
control = submission/domain=
|
||||
|
||||
deny message = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
|
||||
hosts = !+whitelist
|
||||
dnslists = ${readfile {/etc/exim4/dnsbl.conf}{:}}
|
||||
|
||||
require message = relay not permitted
|
||||
domains = +local_domains : +relay_to_domains
|
||||
|
||||
deny message = smtp auth required
|
||||
sender_domains = +local_domains
|
||||
!authenticated = *
|
||||
|
||||
require verify = recipient
|
||||
|
||||
.ifdef CLAMD
|
||||
warn set acl_m0 = no
|
||||
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/antivirus}{yes}{no}}
|
||||
set acl_m0 = yes
|
||||
.endif
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
warn set acl_m1 = no
|
||||
set acl_m3 = no
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/antispam}{yes}{no}}
|
||||
set acl_m1 = yes
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/reject_spam}{yes}{no}}
|
||||
set acl_m3 = yes
|
||||
.endif
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_data:
|
||||
.ifdef CLAMD
|
||||
deny message = Message contains a virus ($malware_name) and has been rejected
|
||||
malware = */defer_ok
|
||||
condition = ${if eq{$acl_m0}{yes}{yes}{no}}
|
||||
.endif
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
warn !authenticated = *
|
||||
hosts = !+relay_from_hosts
|
||||
condition = ${if < {$message_size}{1024K}}
|
||||
condition = ${if eq{$acl_m1}{yes}{yes}{no}}
|
||||
spam = debian-spamd:true/defer_ok
|
||||
add_header = X-Spam-Score: $spam_score_int
|
||||
add_header = X-Spam-Bar: $spam_bar
|
||||
add_header = X-Spam-Report: $spam_report
|
||||
set acl_m2 = $spam_score_int
|
||||
|
||||
warn condition = ${if !eq{$acl_m2}{} {yes}{no}}
|
||||
condition = ${if >{$acl_m2}{SPAM_SCORE} {yes}{no}}
|
||||
add_header = X-Spam-Status: Yes
|
||||
message = SpamAssassin detected spam (from $sender_address to $recipients).
|
||||
|
||||
# Deny spam at high score if spam score > SPAM_REJECT_SCORE and delete_spam is enabled
|
||||
deny message = This message scored $spam_score spam points
|
||||
spam = debian-spamd:true
|
||||
condition = ${if eq{$acl_m3}{yes}{yes}{no}}
|
||||
condition = ${if >{$spam_score_int}{SPAM_REJECT_SCORE}{1}{0}}
|
||||
.endif
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_mime:
|
||||
deny message = Blacklisted file extension detected
|
||||
condition = ${if match {${lc:$mime_filename}}{\N(\.ace|\.ade|\.adp|\.app|\.arj|\.asp|\.aspx|\.asx|\.bas|\.bat|\.cab|\.cer|\.chm|\.cmd|\.cnt|\.com|\.cpl|\.crt|\.csh|\.der|\.diagcab|\.dll|\.efi|\.exe|\.fla|\.fon|\.fxp|\.gadget|\.grp|\.hlp|\.hpj|\.hta|\.htc|\.img|\.inf|\.ins|\.iso|\.isp|\.its|\.jar|\.jnlp|\.js|\.jse|\.ksh|\.lib|\.lnk|\.mad|\.maf|\.mag|\.mam|\.maq|\.mar|\.mas|\.mat|\.mau|\.mav|\.maw|\.mcf|\.mda|\.mdb|\.mde|\.mdt|\.mdw|\.mdz|\.msc|\.msh|\.msh1|\.msh1xml|\.msh2|\.msh2xml|\.mshxml|\.msi|\.msp|\.mst|\.msu|\.ops|\.osd|\.pcd|\.pif|\.pl|\.plg|\.prf|\.prg|\.printerexport|\.ps1|\.ps1xml|\.ps2|\.ps2xml|\.psc1|\.psc2|\.psd1|\.psdm1|\.pst|\.py|\.pyc|\.pyo|\.pyw|\.pyz|\.pyzw|\.reg|\.scf|\.scr|\.sct|\.sfx|\.shb|\.shs|\.swf|\.sys|\.theme|\.tmp|\.ttf|\.url|\.vb|\.vba|\.vbe|\.vbp|\.vbs|\.vhd|\.vhdx|\.vsmacros|\.vsw|\.vxd|\.webpnp|\.website|\.wim|\.ws|\.wsc|\.wsf|\.wsh|\.xbap|\.xll|\.xnk)$\N}{1}{0}}
|
||||
|
||||
accept
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# AUTHENTICATION CONFIGURATION #
|
||||
######################################################################
|
||||
begin authenticators
|
||||
|
||||
smtp_relay_login:
|
||||
driver = plaintext
|
||||
public_name = LOGIN
|
||||
hide client_send = : SMTP_RELAY_USER : SMTP_RELAY_PASS
|
||||
|
||||
dovecot_plain:
|
||||
driver = dovecot
|
||||
public_name = PLAIN
|
||||
server_socket = /run/dovecot/auth-client
|
||||
server_set_id = $auth1
|
||||
|
||||
dovecot_login:
|
||||
driver = dovecot
|
||||
public_name = LOGIN
|
||||
server_socket = /run/dovecot/auth-client
|
||||
server_set_id = $auth1
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# ROUTERS CONFIGURATION #
|
||||
# Specifies how addresses are handled #
|
||||
######################################################################
|
||||
begin routers
|
||||
|
||||
send_via_unauthenticated_smtp_relay:
|
||||
driver = manualroute
|
||||
address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
|
||||
domains = !+local_domains
|
||||
require_files = SMTP_RELAY_FILE
|
||||
condition = ${if eq{SMTP_RELAY_USER}{}}
|
||||
transport = remote_smtp
|
||||
route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
|
||||
no_more
|
||||
no_verify
|
||||
|
||||
send_via_smtp_relay:
|
||||
driver = manualroute
|
||||
address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
|
||||
domains = !+local_domains
|
||||
require_files = SMTP_RELAY_FILE
|
||||
transport = smtp_relay_smtp
|
||||
route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
|
||||
no_more
|
||||
no_verify
|
||||
|
||||
dnslookup:
|
||||
driver = dnslookup
|
||||
# if outbound, and forwarding has been done, use an alternate transport
|
||||
domains = ! +local_domains
|
||||
transport = ${if eq {$local_part@$domain} \
|
||||
{$original_local_part@$original_domain} \
|
||||
{remote_smtp} {remote_forwarded_smtp}}
|
||||
no_more
|
||||
|
||||
userforward:
|
||||
driver = redirect
|
||||
check_local_user
|
||||
file = $home/.forward
|
||||
require_files = ${local_part}:+${home}/.forward
|
||||
domains = +local_domains
|
||||
allow_filter
|
||||
no_verify
|
||||
no_expn
|
||||
check_ancestor
|
||||
file_transport = address_file
|
||||
pipe_transport = address_pipe
|
||||
reply_transport = address_reply
|
||||
|
||||
procmail:
|
||||
driver = accept
|
||||
check_local_user
|
||||
require_files = ${local_part}:+${home}/.procmailrc:/usr/bin/procmail
|
||||
transport = procmail
|
||||
no_verify
|
||||
|
||||
autoreplay:
|
||||
driver = accept
|
||||
require_files = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${local_part}.msg
|
||||
condition = ${if exists{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${local_part}.msg}{yes}{no}}
|
||||
retry_use_local_part
|
||||
transport = userautoreply
|
||||
unseen
|
||||
|
||||
inbound_srs:
|
||||
driver = redirect
|
||||
senders = :
|
||||
domains = +local_domains
|
||||
# detect inbound bounces which are SRS'd, and decode them
|
||||
condition = ${if inbound_srs {$local_part} {SRS_SECRET}}
|
||||
data = $srs_recipient
|
||||
|
||||
inbound_srs_failure:
|
||||
driver = redirect
|
||||
senders = :
|
||||
domains = +local_domains
|
||||
# detect inbound bounces which look SRS'd but are invalid
|
||||
condition = ${if inbound_srs {$local_part} {}}
|
||||
allow_fail
|
||||
data = :fail: Invalid SRS recipient address
|
||||
|
||||
aliases:
|
||||
driver = redirect
|
||||
headers_add = X-redirected: yes
|
||||
data = ${extract{1}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}}}}
|
||||
require_files = /etc/exim4/domains/$domain/aliases
|
||||
redirect_router = dnslookup
|
||||
pipe_transport = address_pipe
|
||||
unseen
|
||||
|
||||
localuser_fwd_only:
|
||||
driver = accept
|
||||
transport = devnull
|
||||
condition = ${if exists{/etc/exim4/domains/$domain/fwd_only}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/fwd_only}{true}{false}}}}
|
||||
|
||||
localuser_spam:
|
||||
driver = accept
|
||||
transport = local_spam_delivery
|
||||
condition = ${if eq {${if match{$h_X-Spam-Status:}{\N^Yes\N}{yes}{no}}} {${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{yes}{no_such_user}}}}
|
||||
|
||||
localuser:
|
||||
driver = accept
|
||||
transport = local_delivery
|
||||
condition = ${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}{true}{false}}
|
||||
|
||||
catchall:
|
||||
driver = redirect
|
||||
headers_add = X-redirected: yes
|
||||
require_files = /etc/exim4/domains/$domain/aliases
|
||||
data = ${extract{1}{:}{${lookup{*@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}}}}
|
||||
file_transport = local_delivery
|
||||
redirect_router = dnslookup
|
||||
condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{false}{true}}
|
||||
|
||||
terminate_alias:
|
||||
driver = accept
|
||||
transport = devnull
|
||||
condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{true}{false}}
|
||||
|
||||
######################################################################
|
||||
# TRANSPORTS CONFIGURATION #
|
||||
######################################################################
|
||||
begin transports
|
||||
|
||||
smtp_relay_smtp:
|
||||
driver = smtp
|
||||
hosts_require_auth = $host_address
|
||||
hosts_require_tls = $host_address
|
||||
|
||||
remote_smtp:
|
||||
driver = smtp
|
||||
helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
|
||||
dkim_domain = DKIM_DOMAIN
|
||||
dkim_selector = mail
|
||||
dkim_private_key = DKIM_PRIVATE_KEY
|
||||
dkim_canon = relaxed
|
||||
dkim_strict = 0
|
||||
hosts_try_fastopen = !*.l.google.com
|
||||
interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
|
||||
|
||||
remote_forwarded_smtp:
|
||||
driver = smtp
|
||||
helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
|
||||
dkim_domain = DKIM_DOMAIN
|
||||
dkim_selector = mail
|
||||
dkim_private_key = DKIM_PRIVATE_KEY
|
||||
dkim_canon = relaxed
|
||||
dkim_strict = 0
|
||||
hosts_try_fastopen = !*.l.google.com
|
||||
interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
|
||||
# modify the envelope from, for mails that we forward
|
||||
max_rcpt = 1
|
||||
return_path = ${srs_encode {SRS_SECRET} {$return_path} {$original_domain}}
|
||||
|
||||
procmail:
|
||||
driver = pipe
|
||||
command = "/usr/bin/procmail -d $local_part"
|
||||
return_path_add
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
user = $local_part
|
||||
initgroups
|
||||
return_output
|
||||
|
||||
local_delivery:
|
||||
driver = appendfile
|
||||
maildir_format
|
||||
maildir_use_size_file
|
||||
user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}
|
||||
group = mail
|
||||
create_directory
|
||||
directory_mode = 770
|
||||
mode = 660
|
||||
use_lockfile = no
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}"
|
||||
quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}M
|
||||
quota_warn_threshold = 75%
|
||||
|
||||
local_spam_delivery:
|
||||
driver = appendfile
|
||||
maildir_format
|
||||
maildir_use_size_file
|
||||
user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}
|
||||
group = mail
|
||||
create_directory
|
||||
directory_mode = 770
|
||||
mode = 660
|
||||
use_lockfile = no
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}/.Spam"
|
||||
quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}M
|
||||
quota_directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}/${lookup{$local_part}dsearch{${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/passwd}}}}/mail/${lookup{$domain}dsearch{/etc/exim4/domains/}}}}"
|
||||
quota_warn_threshold = 75%
|
||||
|
||||
address_pipe:
|
||||
driver = pipe
|
||||
return_output
|
||||
|
||||
address_file:
|
||||
driver = appendfile
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
|
||||
address_reply:
|
||||
driver = autoreply
|
||||
|
||||
userautoreply:
|
||||
driver = autoreply
|
||||
file = /etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/autoreply.${extract{1}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/accounts}}}}.msg
|
||||
from = "${extract{1}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/accounts}}}}@${lookup{$domain}dsearch{/etc/exim4/domains/}}"
|
||||
headers = Content-Type: text/plain; charset=utf-8;\nContent-Transfer-Encoding: 8bit
|
||||
subject = "${if def:h_Subject: {Autoreply: \"${rfc2047:$h_Subject:}\"} {Autoreply Message}}"
|
||||
to = "${sender_address}"
|
||||
|
||||
devnull:
|
||||
driver = appendfile
|
||||
file = /dev/null
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# RETRY CONFIGURATION #
|
||||
######################################################################
|
||||
begin retry
|
||||
|
||||
# Address or Domain Error Retries
|
||||
# ----------------- ----- -------
|
||||
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# REWRITE CONFIGURATION #
|
||||
######################################################################
|
||||
begin rewrite
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
478
install/deb/exim/exim4.conf.template
Normal file
478
install/deb/exim/exim4.conf.template
Normal file
@@ -0,0 +1,478 @@
|
||||
######################################################################
|
||||
# #
|
||||
# Exim configuration file for Hestia Control Panel #
|
||||
# #
|
||||
######################################################################
|
||||
|
||||
#SPAMASSASSIN = yes
|
||||
#SPAM_SCORE = 50
|
||||
#SPAM_REJECT_SCORE = 100
|
||||
#CLAMD = yes
|
||||
|
||||
smtp_banner = $smtp_active_hostname
|
||||
smtp_active_hostname = ${lookup dnsdb{>: defer_never,ptr=$interface_address}{${listextract{1}{$value}}}{$primary_hostname}}
|
||||
add_environment = <; PATH=/bin:/usr/bin
|
||||
keep_environment =
|
||||
disable_ipv6 = true
|
||||
|
||||
smtputf8_advertise_hosts =
|
||||
domainlist local_domains = dsearch;/etc/exim4/domains/
|
||||
domainlist relay_to_domains = dsearch;/etc/exim4/domains/
|
||||
hostlist relay_from_hosts = 127.0.0.1
|
||||
hostlist whitelist = net-iplsearch;/etc/exim4/white-blocks.conf
|
||||
hostlist spammers = net-iplsearch;/etc/exim4/spam-blocks.conf
|
||||
no_local_from_check
|
||||
untrusted_set_sender = *
|
||||
acl_smtp_connect = acl_check_spammers
|
||||
acl_smtp_mail = acl_check_mail
|
||||
acl_smtp_rcpt = acl_check_rcpt
|
||||
acl_smtp_data = acl_check_data
|
||||
acl_smtp_mime = acl_check_mime
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
spamd_address = 127.0.0.1 783
|
||||
.endif
|
||||
|
||||
.ifdef CLAMD
|
||||
av_scanner = clamd: /run/clamav/clamd.ctl
|
||||
.endif
|
||||
|
||||
log_selector = +tls_sni
|
||||
|
||||
tls_advertise_hosts = *
|
||||
|
||||
# We test that $tls_in_sni is a valid domain, by an arbitrary email address foo@domain.tld .
|
||||
# Then, we extract the domain with a function that would fail if the email address is invalid.
|
||||
# If the certificate exists, we will use it, otherwise the default certificate in /etc/ssl will be used.
|
||||
tls_certificate = \
|
||||
${if and {\
|
||||
{ eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
|
||||
{ exists{/usr/local/hestia/ssl/mail/$tls_in_sni.crt} }\
|
||||
}\
|
||||
{/usr/local/hestia/ssl/mail/$tls_in_sni.crt}\
|
||||
{/usr/local/hestia/ssl/certificate.crt}\
|
||||
}
|
||||
|
||||
tls_privatekey = \
|
||||
${if and {\
|
||||
{ eq {${domain:foo@$tls_in_sni}} {$tls_in_sni}}\
|
||||
{ exists{/usr/local/hestia/ssl/mail/$tls_in_sni.key} }\
|
||||
}\
|
||||
{/usr/local/hestia/ssl/mail/$tls_in_sni.key}\
|
||||
{/usr/local/hestia/ssl/certificate.key}\
|
||||
}
|
||||
|
||||
daemon_smtp_ports = 25 : 465 : 587
|
||||
tls_on_connect_ports = 465
|
||||
tls_require_ciphers = PERFORMANCE:-RSA:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3:%SERVER_PRECEDENCE
|
||||
never_users = root
|
||||
host_lookup = *
|
||||
rfc1413_hosts = *
|
||||
rfc1413_query_timeout = 0s
|
||||
ignore_bounce_errors_after = 2d
|
||||
timeout_frozen_after = 7d
|
||||
|
||||
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
|
||||
DKIM_FILE = /etc/exim4/domains/${lc:${domain:$h_from:}}/dkim.pem
|
||||
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
|
||||
|
||||
OUTGOING_IP = /etc/exim4/domains/$sender_address_domain/ip
|
||||
|
||||
SMTP_RELAY_FILE = ${if exists{/etc/exim4/domains/${sender_address_domain}/smtp_relay.conf}{/etc/exim4/domains/$sender_address_domain/smtp_relay.conf}{/etc/exim4/smtp_relay.conf}}
|
||||
SMTP_RELAY_HOST = ${lookup{host}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_PORT = ${lookup{port}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_USER = ${lookup{user}lsearch{SMTP_RELAY_FILE}}
|
||||
SMTP_RELAY_PASS = ${lookup{pass}lsearch{SMTP_RELAY_FILE}}
|
||||
|
||||
# Custom Filter
|
||||
system_filter = /etc/exim4/system.filter
|
||||
system_filter_user = Debian-exim
|
||||
|
||||
######################################################################
|
||||
# ACL CONFIGURATION #
|
||||
# Specifies access control lists for incoming SMTP mail #
|
||||
######################################################################
|
||||
|
||||
acl_not_smtp = acl_not_smtp
|
||||
|
||||
begin acl
|
||||
|
||||
# Limit per user for PHP scripts
|
||||
acl_not_smtp:
|
||||
deny message = Website of user $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
|
||||
ratelimit = 200 / 1h / $authenticated_id
|
||||
|
||||
warn ratelimit = 100 / 1h / strict / $authenticated_id
|
||||
log_message = Sender rate [limitlog]: log / account / $authenticated_id / $sender_rate / $sender_rate_period
|
||||
|
||||
accept
|
||||
|
||||
acl_check_spammers:
|
||||
accept hosts = +whitelist
|
||||
|
||||
drop message = Your host in blacklist on this server.
|
||||
log_message = Host in blacklist
|
||||
hosts = +spammers
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_mail:
|
||||
deny condition = ${if eq{$sender_helo_name}{}}
|
||||
message = HELO required before MAIL
|
||||
|
||||
drop !authenticated = *
|
||||
message = Helo name contains an IP address (HELO was $sender_helo_name) and not is valid
|
||||
condition = ${if match{$sender_helo_name}{\N((\d{1,3}[.-]\d{1,3}[.-]\d{1,3}[.-]\d{1,3})|([0-9a-f]{8})|([0-9A-F]{8}))\N}{yes}{no}}
|
||||
condition = ${if match {${lookup dnsdb{>: defer_never,ptr=$sender_host_address}}\}{$sender_helo_name}{no}{yes}}
|
||||
delay = 45s
|
||||
|
||||
drop !authenticated = *
|
||||
condition = ${if isip{$sender_helo_name}}
|
||||
message = Access denied - Invalid HELO name (See RFC2821 4.1.3)
|
||||
|
||||
drop !authenticated = *
|
||||
condition = ${if eq{[$interface_address]}{$sender_helo_name}}
|
||||
message = $interface_address is _my_ address
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_rcpt:
|
||||
accept hosts = :
|
||||
|
||||
# Limit per email account for SMTP auhenticated users
|
||||
deny message = Email account $authenticated_id is sending too many emails - rate overlimit = $sender_rate / $sender_rate_period
|
||||
set acl_c_msg_limit = ${if exists{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{${lookup {$authenticated_id} lsearch{/etc/exim4/domains/${lookup{${domain:$authenticated_id}}dsearch{/etc/exim4/domains/}}/limits}{$value}{${readfile{/etc/exim4/limit.conf}}}}}{${readfile{/etc/exim4/limit.conf}}} }
|
||||
ratelimit = $acl_c_msg_limit / 1h / strict/ $authenticated_id
|
||||
|
||||
warn ratelimit = ${eval:$acl_c_msg_limit / 2} / 1h / strict / $authenticated_id
|
||||
log_message = Sender rate [limitlog]: log / email / $authenticated_id / $sender_rate / $sender_rate_period
|
||||
|
||||
deny message = Restricted characters in address
|
||||
domains = +local_domains
|
||||
local_parts = ^[.] : ^.*[@%!/|]
|
||||
|
||||
deny message = Restricted characters in address
|
||||
domains = !+local_domains
|
||||
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
|
||||
|
||||
require verify = sender
|
||||
|
||||
accept hosts = +relay_from_hosts
|
||||
control = submission
|
||||
|
||||
accept authenticated = *
|
||||
control = submission/domain=
|
||||
|
||||
deny message = Rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
|
||||
hosts = !+whitelist
|
||||
dnslists = ${readfile {/etc/exim4/dnsbl.conf}{:}}
|
||||
|
||||
require message = relay not permitted
|
||||
domains = +local_domains : +relay_to_domains
|
||||
|
||||
deny message = smtp auth required
|
||||
sender_domains = +local_domains
|
||||
!authenticated = *
|
||||
|
||||
require verify = recipient
|
||||
|
||||
.ifdef CLAMD
|
||||
warn set acl_m0 = no
|
||||
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/antivirus}{yes}{no}}
|
||||
set acl_m0 = yes
|
||||
.endif
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
warn set acl_m1 = no
|
||||
set acl_m3 = no
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/antispam}{yes}{no}}
|
||||
set acl_m1 = yes
|
||||
warn condition = ${if exists {/etc/exim4/domains/$domain/reject_spam}{yes}{no}}
|
||||
set acl_m3 = yes
|
||||
.endif
|
||||
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_data:
|
||||
.ifdef CLAMD
|
||||
deny message = Message contains a virus ($malware_name) and has been rejected
|
||||
malware = */defer_ok
|
||||
condition = ${if eq{$acl_m0}{yes}{yes}{no}}
|
||||
.endif
|
||||
|
||||
.ifdef SPAMASSASSIN
|
||||
warn !authenticated = *
|
||||
hosts = !+relay_from_hosts
|
||||
condition = ${if < {$message_size}{1024K}}
|
||||
condition = ${if eq{$acl_m1}{yes}{yes}{no}}
|
||||
spam = debian-spamd:true/defer_ok
|
||||
add_header = X-Spam-Score: $spam_score_int
|
||||
add_header = X-Spam-Bar: $spam_bar
|
||||
add_header = X-Spam-Report: $spam_report
|
||||
set acl_m2 = $spam_score_int
|
||||
|
||||
warn condition = ${if !eq{$acl_m2}{} {yes}{no}}
|
||||
condition = ${if >{$acl_m2}{SPAM_SCORE} {yes}{no}}
|
||||
add_header = X-Spam-Status: Yes
|
||||
message = SpamAssassin detected spam (from $sender_address to $recipients).
|
||||
|
||||
# Deny spam at high score if spam score > SPAM_REJECT_SCORE and delete_spam is enabled
|
||||
deny message = This message scored $spam_score spam points
|
||||
spam = debian-spamd:true
|
||||
condition = ${if eq{$acl_m3}{yes}{yes}{no}}
|
||||
condition = ${if >{$spam_score_int}{SPAM_REJECT_SCORE}{1}{0}}
|
||||
.endif
|
||||
|
||||
|
||||
accept
|
||||
|
||||
|
||||
acl_check_mime:
|
||||
deny message = Blacklisted file extension detected
|
||||
condition = ${if match {${lc:$mime_filename}}{\N(\.ace|\.ade|\.adp|\.app|\.arj|\.asp|\.aspx|\.asx|\.bas|\.bat|\.cab|\.cer|\.chm|\.cmd|\.cnt|\.com|\.cpl|\.crt|\.csh|\.der|\.diagcab|\.dll|\.efi|\.exe|\.fla|\.fon|\.fxp|\.gadget|\.grp|\.hlp|\.hpj|\.hta|\.htc|\.img|\.inf|\.ins|\.iso|\.isp|\.its|\.jar|\.jnlp|\.js|\.jse|\.ksh|\.lib|\.lnk|\.mad|\.maf|\.mag|\.mam|\.maq|\.mar|\.mas|\.mat|\.mau|\.mav|\.maw|\.mcf|\.mda|\.mdb|\.mde|\.mdt|\.mdw|\.mdz|\.msc|\.msh|\.msh1|\.msh1xml|\.msh2|\.msh2xml|\.mshxml|\.msi|\.msp|\.mst|\.msu|\.ops|\.osd|\.pcd|\.pif|\.pl|\.plg|\.prf|\.prg|\.printerexport|\.ps1|\.ps1xml|\.ps2|\.ps2xml|\.psc1|\.psc2|\.psd1|\.psdm1|\.pst|\.py|\.pyc|\.pyo|\.pyw|\.pyz|\.pyzw|\.reg|\.scf|\.scr|\.sct|\.sfx|\.shb|\.shs|\.swf|\.sys|\.theme|\.tmp|\.ttf|\.url|\.vb|\.vba|\.vbe|\.vbp|\.vbs|\.vhd|\.vhdx|\.vsmacros|\.vsw|\.vxd|\.webpnp|\.website|\.wim|\.ws|\.wsc|\.wsf|\.wsh|\.xbap|\.xll|\.xnk)$\N}{1}{0}}
|
||||
|
||||
accept
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# AUTHENTICATION CONFIGURATION #
|
||||
######################################################################
|
||||
begin authenticators
|
||||
|
||||
smtp_relay_login:
|
||||
driver = plaintext
|
||||
public_name = LOGIN
|
||||
hide client_send = : SMTP_RELAY_USER : SMTP_RELAY_PASS
|
||||
|
||||
dovecot_plain:
|
||||
driver = dovecot
|
||||
public_name = PLAIN
|
||||
server_socket = /run/dovecot/auth-client
|
||||
server_set_id = $auth1
|
||||
|
||||
dovecot_login:
|
||||
driver = dovecot
|
||||
public_name = LOGIN
|
||||
server_socket = /run/dovecot/auth-client
|
||||
server_set_id = $auth1
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# ROUTERS CONFIGURATION #
|
||||
# Specifies how addresses are handled #
|
||||
######################################################################
|
||||
begin routers
|
||||
|
||||
send_via_unauthenticated_smtp_relay:
|
||||
driver = manualroute
|
||||
address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
|
||||
domains = !+local_domains
|
||||
require_files = SMTP_RELAY_FILE
|
||||
condition = ${if eq{SMTP_RELAY_USER}{}}
|
||||
transport = remote_smtp
|
||||
route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
|
||||
no_more
|
||||
no_verify
|
||||
|
||||
send_via_smtp_relay:
|
||||
driver = manualroute
|
||||
address_data = SMTP_RELAY_HOST:SMTP_RELAY_PORT
|
||||
domains = !+local_domains
|
||||
require_files = SMTP_RELAY_FILE
|
||||
transport = smtp_relay_smtp
|
||||
route_list = * ${extract{1}{:}{$address_data}}::${extract{2}{:}{$address_data}}
|
||||
no_more
|
||||
no_verify
|
||||
|
||||
dnslookup:
|
||||
driver = dnslookup
|
||||
domains = !+local_domains
|
||||
transport = remote_smtp
|
||||
no_more
|
||||
|
||||
userforward:
|
||||
driver = redirect
|
||||
check_local_user
|
||||
file = $home/.forward
|
||||
require_files = ${local_part}:+${home}/.forward
|
||||
domains = +local_domains
|
||||
allow_filter
|
||||
no_verify
|
||||
no_expn
|
||||
check_ancestor
|
||||
file_transport = address_file
|
||||
pipe_transport = address_pipe
|
||||
reply_transport = address_reply
|
||||
|
||||
procmail:
|
||||
driver = accept
|
||||
check_local_user
|
||||
require_files = ${local_part}:+${home}/.procmailrc:/usr/bin/procmail
|
||||
transport = procmail
|
||||
no_verify
|
||||
|
||||
autoreplay:
|
||||
driver = accept
|
||||
require_files = /etc/exim4/domains/$domain/autoreply.${local_part}.msg
|
||||
condition = ${if exists{/etc/exim4/domains/$domain/autoreply.${local_part}.msg}{yes}{no}}
|
||||
retry_use_local_part
|
||||
transport = userautoreply
|
||||
unseen
|
||||
|
||||
aliases:
|
||||
driver = redirect
|
||||
headers_add = X-redirected: yes
|
||||
data = ${extract{1}{:}{${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/$domain/aliases}}}}
|
||||
require_files = /etc/exim4/domains/$domain/aliases
|
||||
redirect_router = dnslookup
|
||||
pipe_transport = address_pipe
|
||||
unseen
|
||||
|
||||
localuser_fwd_only:
|
||||
driver = accept
|
||||
transport = devnull
|
||||
condition = ${if exists{/etc/exim4/domains/$domain/fwd_only}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/fwd_only}{true}{false}}}}
|
||||
|
||||
localuser_spam:
|
||||
driver = accept
|
||||
transport = local_spam_delivery
|
||||
condition = ${if eq {${if match{$h_X-Spam-Status:}{\N^Yes\N}{yes}{no}}} {${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}{yes}{no_such_user}}}}
|
||||
|
||||
localuser:
|
||||
driver = accept
|
||||
transport = local_delivery
|
||||
condition = ${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}{true}{false}}
|
||||
|
||||
catchall:
|
||||
driver = redirect
|
||||
headers_add = X-redirected: yes
|
||||
require_files = /etc/exim4/domains/$domain/aliases
|
||||
data = ${extract{1}{:}{${lookup{*@$domain}lsearch{/etc/exim4/domains/$domain/aliases}}}}
|
||||
file_transport = local_delivery
|
||||
redirect_router = dnslookup
|
||||
condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/${lookup{$domain}dsearch{/etc/exim4/domains/}}/aliases}{false}{true}}
|
||||
|
||||
terminate_alias:
|
||||
driver = accept
|
||||
transport = devnull
|
||||
condition = ${lookup{$local_part@$domain}lsearch{/etc/exim4/domains/$domain/aliases}{true}{false}}
|
||||
|
||||
######################################################################
|
||||
# TRANSPORTS CONFIGURATION #
|
||||
######################################################################
|
||||
begin transports
|
||||
|
||||
smtp_relay_smtp:
|
||||
driver = smtp
|
||||
hosts_require_auth = $host_address
|
||||
hosts_require_tls = $host_address
|
||||
|
||||
remote_smtp:
|
||||
driver = smtp
|
||||
helo_data = ${lookup dnsdb{>: defer_never,ptr=$sending_ip_address}{${listextract{1}{$value}}}{$primary_hostname}}
|
||||
dkim_domain = DKIM_DOMAIN
|
||||
dkim_selector = mail
|
||||
dkim_private_key = DKIM_PRIVATE_KEY
|
||||
dkim_canon = relaxed
|
||||
dkim_strict = 0
|
||||
hosts_try_fastopen = !*.l.google.com
|
||||
interface = ${if exists{OUTGOING_IP}{${readfile{OUTGOING_IP}}}}
|
||||
|
||||
procmail:
|
||||
driver = pipe
|
||||
command = "/usr/bin/procmail -d $local_part"
|
||||
return_path_add
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
user = $local_part
|
||||
initgroups
|
||||
return_output
|
||||
|
||||
local_delivery:
|
||||
driver = appendfile
|
||||
maildir_format
|
||||
maildir_use_size_file
|
||||
user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}}}}
|
||||
group = mail
|
||||
create_directory
|
||||
directory_mode = 770
|
||||
mode = 660
|
||||
use_lockfile = no
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}}}}/mail/$domain/$local_part"
|
||||
quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}}}}M
|
||||
quota_warn_threshold = 75%
|
||||
|
||||
local_spam_delivery:
|
||||
driver = appendfile
|
||||
maildir_format
|
||||
maildir_use_size_file
|
||||
user = ${extract{2}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}}}}
|
||||
group = mail
|
||||
create_directory
|
||||
directory_mode = 770
|
||||
mode = 660
|
||||
use_lockfile = no
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}}}}/mail/$domain/$local_part/.Spam"
|
||||
quota = ${extract{6}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}}}}M
|
||||
quota_directory = "${extract{5}{:}{${lookup{$local_part}lsearch{/etc/exim4/domains/$domain/passwd}}}}/mail/$domain/$local_part"
|
||||
quota_warn_threshold = 75%
|
||||
|
||||
address_pipe:
|
||||
driver = pipe
|
||||
return_output
|
||||
|
||||
address_file:
|
||||
driver = appendfile
|
||||
delivery_date_add
|
||||
envelope_to_add
|
||||
return_path_add
|
||||
|
||||
address_reply:
|
||||
driver = autoreply
|
||||
|
||||
userautoreply:
|
||||
driver = autoreply
|
||||
file = /etc/exim4/domains/$domain/autoreply.${local_part}.msg
|
||||
from = "${local_part}@${domain}"
|
||||
headers = Content-Type: text/plain; charset=utf-8;\nContent-Transfer-Encoding: 8bit
|
||||
subject = "${if def:h_Subject: {Autoreply: \"${rfc2047:$h_Subject:}\"} {Autoreply Message}}"
|
||||
to = "${sender_address}"
|
||||
|
||||
devnull:
|
||||
driver = appendfile
|
||||
file = /dev/null
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# RETRY CONFIGURATION #
|
||||
######################################################################
|
||||
begin retry
|
||||
|
||||
# Address or Domain Error Retries
|
||||
# ----------------- ----- -------
|
||||
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
# REWRITE CONFIGURATION #
|
||||
######################################################################
|
||||
begin rewrite
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
1
install/deb/exim/limit.conf
Normal file
1
install/deb/exim/limit.conf
Normal file
@@ -0,0 +1 @@
|
||||
200
|
||||
0
install/deb/exim/spam-blocks.conf
Normal file
0
install/deb/exim/spam-blocks.conf
Normal file
1
install/deb/exim/srs.conf
Normal file
1
install/deb/exim/srs.conf
Normal file
@@ -0,0 +1 @@
|
||||
TOBEREPLACED
|
||||
16
install/deb/exim/system.filter
Normal file
16
install/deb/exim/system.filter
Normal file
@@ -0,0 +1,16 @@
|
||||
if $h_X-Spam-Status: contains "Yes"
|
||||
then
|
||||
headers add "Old-Subject: $h_subject"
|
||||
headers remove "Subject"
|
||||
headers add "Subject: *** SPAM *** $h_old-subject"
|
||||
headers remove "Old-Subject"
|
||||
endif
|
||||
|
||||
# X-Anti-Virus: infected
|
||||
if $h_X-Anti-Virus: contains "infected"
|
||||
then
|
||||
headers add "Old-Subject: $h_subject"
|
||||
headers remove "Subject"
|
||||
headers add "Subject: *** VIRUS *** $h_old-subject"
|
||||
headers remove "Old-Subject"
|
||||
endif
|
||||
9
install/deb/fail2ban/action.d/hestia.conf
Normal file
9
install/deb/fail2ban/action.d/hestia.conf
Normal file
@@ -0,0 +1,9 @@
|
||||
# Fail2Ban configuration file for hestia
|
||||
|
||||
[Definition]
|
||||
|
||||
actionstart = /usr/local/hestia/bin/v-add-firewall-chain <name>
|
||||
actionstop = /usr/local/hestia/bin/v-delete-firewall-chain <name>
|
||||
actioncheck = iptables -n -L INPUT | grep -q 'fail2ban-<name>[ \t]'
|
||||
actionban = /usr/local/hestia/bin/v-add-firewall-ban <ip> <name>
|
||||
actionunban = /usr/local/hestia/bin/v-delete-firewall-ban <ip> <name>
|
||||
10
install/deb/fail2ban/filter.d/hestia.conf
Normal file
10
install/deb/fail2ban/filter.d/hestia.conf
Normal file
@@ -0,0 +1,10 @@
|
||||
# Fail2Ban filter for unsuccessful hestia authentication attempts
|
||||
#
|
||||
|
||||
[INCLUDES]
|
||||
before = common.conf
|
||||
|
||||
[Definition]
|
||||
failregex = .* <HOST> failed to login
|
||||
ignoreregex =
|
||||
|
||||
66
install/deb/fail2ban/jail.local
Normal file
66
install/deb/fail2ban/jail.local
Normal file
@@ -0,0 +1,66 @@
|
||||
[ssh-iptables]
|
||||
enabled = true
|
||||
filter = sshd
|
||||
action = hestia[name=SSH]
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 5
|
||||
|
||||
[vsftpd-iptables]
|
||||
enabled = false
|
||||
filter = vsftpd
|
||||
action = hestia[name=FTP]
|
||||
logpath = /var/log/vsftpd.log
|
||||
maxretry = 5
|
||||
|
||||
[exim-iptables]
|
||||
enabled = true
|
||||
filter = exim
|
||||
action = hestia[name=MAIL]
|
||||
logpath = /var/log/exim4/mainlog
|
||||
|
||||
[dovecot-iptables]
|
||||
enabled = true
|
||||
filter = dovecot
|
||||
action = hestia[name=MAIL]
|
||||
logpath = /var/log/dovecot.log
|
||||
|
||||
[mysqld-iptables]
|
||||
enabled = false
|
||||
filter = mysqld-auth
|
||||
action = hestia[name=DB]
|
||||
logpath = /var/log/mysql/error.log
|
||||
maxretry = 5
|
||||
|
||||
[hestia-iptables]
|
||||
enabled = true
|
||||
filter = hestia
|
||||
action = hestia[name=HESTIA]
|
||||
logpath = /var/log/hestia/auth.log
|
||||
maxretry = 5
|
||||
|
||||
[roundcube-auth]
|
||||
enabled = false
|
||||
filter = roundcube-auth
|
||||
action = hestia[name=WEB]
|
||||
logpath = /var/log/roundcube/errors.log
|
||||
maxretry = 5
|
||||
|
||||
[phpmyadmin-auth]
|
||||
enabled = true
|
||||
filter = phpmyadmin-syslog
|
||||
action = hestia[name=WEB]
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 5
|
||||
|
||||
[recidive]
|
||||
enabled = true
|
||||
filter = recidive
|
||||
action = hestia[name=RECIDIVE]
|
||||
logpath = /var/log/fail2ban.log
|
||||
maxretry = 5
|
||||
findtime = 86400
|
||||
bantime = 864000
|
||||
|
||||
#Uncomment and add your IPs and or domains to the Whitelist
|
||||
#[DEFAULT]
|
||||
#ignoreip = 111.111.111.111 222.222.222.222 subdomain.example.tld example.tld 333.333.333.333
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Filegator\Services\Archiver\Adapters;
|
||||
|
||||
use Filegator\Container\Container;
|
||||
use Filegator\Services\Archiver\ArchiverInterface;
|
||||
use Filegator\Services\Service;
|
||||
use Filegator\Services\Storage\Filesystem as Storage;
|
||||
use Filegator\Services\Tmpfs\TmpfsInterface;
|
||||
use function Hestiacp\quoteshellarg\quoteshellarg;
|
||||
|
||||
class HestiaZipArchiver extends ZipArchiver implements Service, ArchiverInterface {
|
||||
protected $container;
|
||||
|
||||
public function __construct(TmpfsInterface $tmpfs, Container $container) {
|
||||
$this->tmpfs = $tmpfs;
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function uncompress(string $source, string $destination, Storage $storage) {
|
||||
$auth = $this->container->get("Filegator\Services\Auth\AuthInterface");
|
||||
|
||||
$v_user = basename($auth->user()->getUsername());
|
||||
|
||||
if (!strlen($v_user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strpos($source, "/home") === false) {
|
||||
$source = "/home/$v_user/" . $source;
|
||||
}
|
||||
|
||||
if (strpos($destination, "/home") === false) {
|
||||
$destination = "/home/$v_user/" . $destination;
|
||||
}
|
||||
|
||||
exec(
|
||||
"sudo /usr/local/hestia/bin/v-extract-fs-archive " .
|
||||
quoteshellarg($v_user) .
|
||||
" " .
|
||||
quoteshellarg($source) .
|
||||
" " .
|
||||
quoteshellarg($destination),
|
||||
$output,
|
||||
$return_var,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the FileGator package.
|
||||
*
|
||||
* (c) Milos Stojanovic <alcalbg@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
*/
|
||||
|
||||
namespace Filegator\Services\Auth\Adapters;
|
||||
|
||||
use Filegator\Services\Auth\AuthInterface;
|
||||
use Filegator\Services\Auth\User;
|
||||
use Filegator\Services\Auth\UsersCollection;
|
||||
use Filegator\Services\Service;
|
||||
use function Hestiacp\quoteshellarg\quoteshellarg;
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class HestiaAuth implements Service, AuthInterface {
|
||||
protected $permissions = [];
|
||||
|
||||
protected $private_repos = false;
|
||||
|
||||
protected $hestia_user = "";
|
||||
|
||||
public function init(array $config = []) {
|
||||
if (isset($_SESSION["user"])) {
|
||||
$v_user = $_SESSION["user"];
|
||||
}
|
||||
if (!empty($_SESSION["look"])) {
|
||||
if (isset($_SESSION["look"]) && $_SESSION["userContext"] === "admin") {
|
||||
$v_user = $_SESSION["look"];
|
||||
}
|
||||
if (
|
||||
$_SESSION["look"] == "admin" &&
|
||||
$_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes"
|
||||
) {
|
||||
// Go away do not login
|
||||
header("Location: /");
|
||||
exit();
|
||||
}
|
||||
}
|
||||
$this->hestia_user = $v_user;
|
||||
$this->permissions = isset($config["permissions"]) ? (array) $config["permissions"] : [];
|
||||
$this->private_repos = isset($config["private_repos"])
|
||||
? (bool) $config["private_repos"]
|
||||
: false;
|
||||
}
|
||||
|
||||
public function user(): ?User {
|
||||
$cmd = "/usr/bin/sudo /usr/local/hestia/bin/v-list-user";
|
||||
exec($cmd . " " . quoteshellarg($this->hestia_user) . " json", $output, $return_var);
|
||||
|
||||
if ($return_var == 0) {
|
||||
$data = json_decode(implode("", $output), true);
|
||||
$hestia_user_info = $data[$this->hestia_user];
|
||||
return $this->transformUser($hestia_user_info);
|
||||
}
|
||||
|
||||
return $this->getGuest();
|
||||
}
|
||||
|
||||
public function transformUser($hstuser): User {
|
||||
$user = new User();
|
||||
$user->setUsername($this->hestia_user);
|
||||
$user->setName($this->hestia_user . " (" . $hstuser["NAME"] . ")");
|
||||
$user->setRole("user");
|
||||
$user->setPermissions($this->permissions);
|
||||
$user->setHomedir("/");
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function authenticate($username, $password): bool {
|
||||
# Auth is handled by Hestia
|
||||
return false;
|
||||
}
|
||||
|
||||
public function forget() {
|
||||
// Logout return to Hestia
|
||||
return $this->getGuest();
|
||||
}
|
||||
|
||||
public function store(User $user) {
|
||||
return null; // not used
|
||||
}
|
||||
|
||||
public function update($username, User $user, $password = ""): User {
|
||||
// Password change is handled by Hestia
|
||||
return $this->user();
|
||||
}
|
||||
|
||||
public function add(User $user, $password): User {
|
||||
return new User(); // not used
|
||||
}
|
||||
|
||||
public function delete(User $user) {
|
||||
return true; // not used
|
||||
}
|
||||
|
||||
public function find($username): ?User {
|
||||
return null; // not used
|
||||
}
|
||||
|
||||
public function allUsers(): UsersCollection {
|
||||
return new UsersCollection(); // not used
|
||||
}
|
||||
|
||||
public function getGuest(): User {
|
||||
$guest = new User();
|
||||
|
||||
$guest->setUsername("guest");
|
||||
$guest->setName("Guest");
|
||||
$guest->setRole("guest");
|
||||
$guest->setHomedir("/");
|
||||
$guest->setPermissions([]);
|
||||
|
||||
return $guest;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the FileGator package.
|
||||
*
|
||||
* (c) Milos Stojanovic <alcalbg@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE file
|
||||
*/
|
||||
|
||||
namespace Filegator\Services\Session\Adapters;
|
||||
|
||||
use Filegator\Kernel\Request;
|
||||
use Filegator\Services\Service;
|
||||
use Filegator\Services\Session\Session;
|
||||
use Filegator\Services\Session\SessionStorageInterface;
|
||||
|
||||
class SessionStorage implements Service, SessionStorageInterface {
|
||||
protected $request;
|
||||
|
||||
protected $config;
|
||||
|
||||
public function __construct(Request $request) {
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function init(array $config = []) {
|
||||
// we don't have a previous session attached
|
||||
if (!$this->getSession()) {
|
||||
$handler = $config["handler"];
|
||||
$session = new Session($handler());
|
||||
//$session->setName('filegator');
|
||||
$this->setSession($session);
|
||||
}
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$this->getSession()->save();
|
||||
}
|
||||
|
||||
public function set(string $key, $data) {
|
||||
return $this->getSession()->set($key, $data);
|
||||
}
|
||||
|
||||
public function get(string $key, $default = null) {
|
||||
return $this->getSession() ? $this->getSession()->get($key, $default) : $default;
|
||||
}
|
||||
|
||||
public function invalidate() {
|
||||
if (!$this->getSession()->isStarted()) {
|
||||
$this->getSession()->start();
|
||||
}
|
||||
|
||||
$this->getSession()->invalidate();
|
||||
}
|
||||
|
||||
private function setSession(Session $session) {
|
||||
return $this->request->setSession($session);
|
||||
}
|
||||
|
||||
private function getSession(): ?Session {
|
||||
return $this->request->getSession();
|
||||
}
|
||||
}
|
||||
47
install/deb/filemanager/filegator/composer.json
Normal file
47
install/deb/filemanager/filegator/composer.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "filegator/filegator",
|
||||
"description": "Filegator",
|
||||
"license": "MIT",
|
||||
"type": "project",
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.2.5"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2",
|
||||
"monolog/monolog": "^1.24",
|
||||
"nikic/fast-route": "^1.3",
|
||||
"symfony/security-csrf": "^4.4",
|
||||
"symfony/http-foundation": "^4.4",
|
||||
"dibi/dibi": "^4.1",
|
||||
"php-di/php-di": "^6.0",
|
||||
"rakit/validation": "^1.1",
|
||||
"league/flysystem": "^1.1",
|
||||
"league/flysystem-ziparchive": "^1.0",
|
||||
"league/flysystem-sftp": "^1.0",
|
||||
"hestiacp/phpquoteshellarg": "^1.0"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Milos Stojanovic",
|
||||
"email": "alcalbg@gmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Filegator\\": "backend"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/backend/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"symfony/var-dumper": "^4.4",
|
||||
"league/flysystem-memory": "^1.0",
|
||||
"phpstan/phpstan": "^0.11.8"
|
||||
}
|
||||
}
|
||||
4771
install/deb/filemanager/filegator/composer.lock
generated
Normal file
4771
install/deb/filemanager/filegator/composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
175
install/deb/filemanager/filegator/configuration.php
Normal file
175
install/deb/filemanager/filegator/configuration.php
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
use function Hestiacp\quoteshellarg\quoteshellarg;
|
||||
|
||||
$dist_config = require __DIR__ . "/configuration_sample.php";
|
||||
|
||||
$dist_config["public_path"] = "/fm/";
|
||||
$dist_config["frontend_config"]["app_name"] = "File Manager - Hestia Control Panel";
|
||||
$dist_config["frontend_config"]["logo"] = "../images/logo.svg";
|
||||
$dist_config["frontend_config"]["editable"] = [
|
||||
".txt",
|
||||
".css",
|
||||
".js",
|
||||
".ts",
|
||||
".html",
|
||||
".php",
|
||||
".py",
|
||||
".yml",
|
||||
".xml",
|
||||
".md",
|
||||
".log",
|
||||
".csv",
|
||||
".conf",
|
||||
".config",
|
||||
".ini",
|
||||
".scss",
|
||||
".sh",
|
||||
".env",
|
||||
".example",
|
||||
".htaccess",
|
||||
".twig",
|
||||
".tpl",
|
||||
".yaml",
|
||||
];
|
||||
$dist_config["frontend_config"]["guest_redirection"] = "/login/";
|
||||
$dist_config["frontend_config"]["upload_max_size"] = 1024 * 1024 * 1024;
|
||||
|
||||
$dist_config["services"]["Filegator\Services\Storage\Filesystem"]["config"][
|
||||
"adapter"
|
||||
] = function () {
|
||||
if (!empty($_SESSION["INACTIVE_SESSION_TIMEOUT"])) {
|
||||
if ($_SESSION["INACTIVE_SESSION_TIMEOUT"] * 60 + $_SESSION["LAST_ACTIVITY"] < time()) {
|
||||
$v_user = quoteshellarg($_SESSION["user"]);
|
||||
$v_session_id = quoteshellarg($_SESSION["token"]);
|
||||
exec(
|
||||
"/usr/local/hestia/bin/v-log-user-logout " . $v_user . " " . $v_session_id,
|
||||
$output,
|
||||
$return_var,
|
||||
);
|
||||
unset($_SESSION);
|
||||
session_unset();
|
||||
session_destroy();
|
||||
session_start();
|
||||
echo '<meta http-equiv="refresh" content="0; url=/">';
|
||||
exit();
|
||||
} else {
|
||||
$_SESSION["LAST_ACTIVITY"] = time();
|
||||
}
|
||||
} else {
|
||||
echo '<meta http-equiv="refresh" content="0; url=/">';
|
||||
}
|
||||
if (isset($_SESSION["user"])) {
|
||||
$v_user = $_SESSION["user"];
|
||||
}
|
||||
if (!empty($_SESSION["look"])) {
|
||||
if (isset($_SESSION["look"]) && $_SESSION["userContext"] === "admin") {
|
||||
$v_user = $_SESSION["look"];
|
||||
}
|
||||
if (
|
||||
isset($_SESSION["look"]) &&
|
||||
$_SESSION["look"] == "admin" &&
|
||||
$_SESSION["POLICY_SYSTEM_PROTECTED_ADMIN"] == "yes"
|
||||
) {
|
||||
header("Location: /");
|
||||
}
|
||||
}
|
||||
# Create filemanager sftp key if missing and trash it after 30 min
|
||||
if (!file_exists("/home/" . basename($v_user) . "/.ssh/hst-filemanager-key")) {
|
||||
exec(
|
||||
"sudo /usr/local/hestia/bin/v-add-user-sftp-key " .
|
||||
quoteshellarg(basename($v_user)) .
|
||||
" 30",
|
||||
$output,
|
||||
$return_var,
|
||||
);
|
||||
// filemanager also requires .ssh chmod o+x ... hopefully we can improve it to g+x or u+x someday
|
||||
// current minimum for filemanager: chmod 0701 .ssh
|
||||
shell_exec("sudo chmod o+x " . quoteshellarg("/home/" . basename($v_user) . "/.ssh"));
|
||||
}
|
||||
|
||||
if (!isset($_SESSION["SFTP_PORT"])) {
|
||||
exec("sudo /usr/local/hestia/bin/v-list-sys-sshd-port json", $output, $result);
|
||||
$port = json_decode(implode("", $output));
|
||||
if (is_numeric($port[0]) && $port[0] > 0) {
|
||||
$_SESSION["SFTP_PORT"] = $port[0];
|
||||
} elseif (
|
||||
preg_match('/^\s*Port\s+(\d+)$/im', file_get_contents("/etc/ssh/sshd_config"), $matches)
|
||||
) {
|
||||
$_SESSION["SFTP_PORT"] = $matches[1] ?? 22;
|
||||
} else {
|
||||
$_SESSION["SFTP_PORT"] = 22;
|
||||
}
|
||||
}
|
||||
|
||||
preg_match(
|
||||
'/(Hestia SFTP Chroot\nMatch User)(.*)/i',
|
||||
file_get_contents("/etc/ssh/sshd_config"),
|
||||
$matches,
|
||||
);
|
||||
$user_list = explode(",", $matches[2]);
|
||||
if (in_array($v_user, $user_list)) {
|
||||
$root = "/";
|
||||
} else {
|
||||
$root = "/home/" . $v_user;
|
||||
}
|
||||
|
||||
return new \League\Flysystem\Sftp\SftpAdapter([
|
||||
"host" => "127.0.0.1",
|
||||
"port" => intval($_SESSION["SFTP_PORT"]),
|
||||
"username" => basename($v_user),
|
||||
"privateKey" => "/home/" . basename($v_user) . "/.ssh/hst-filemanager-key",
|
||||
"root" => $root,
|
||||
"timeout" => 10,
|
||||
"directoryPerm" => 0755,
|
||||
]);
|
||||
};
|
||||
|
||||
$dist_config["services"]["Filegator\Services\Archiver\ArchiverInterface"] = [
|
||||
"handler" => "\Filegator\Services\Archiver\Adapters\HestiaZipArchiver",
|
||||
"config" => [],
|
||||
];
|
||||
|
||||
$dist_config["services"]["Filegator\Services\Auth\AuthInterface"] = [
|
||||
"handler" => "\Filegator\Services\Auth\Adapters\HestiaAuth",
|
||||
"config" => [
|
||||
"permissions" => ["read", "write", "upload", "download", "batchdownload", "zip"],
|
||||
"private_repos" => false,
|
||||
],
|
||||
];
|
||||
|
||||
$dist_config["services"]["Filegator\Services\View\ViewInterface"]["config"] = [
|
||||
"add_to_head" => '
|
||||
<style>
|
||||
.logo {
|
||||
width: 46px;
|
||||
}
|
||||
</style>
|
||||
',
|
||||
"add_to_body" => '
|
||||
<script>
|
||||
var checkVueLoaded = setInterval(function() {
|
||||
if (document.getElementsByClassName("container").length) {
|
||||
clearInterval(checkVueLoaded);
|
||||
var navProfile = document.getElementsByClassName("navbar-item profile")[0]; navProfile.replaceWith(navProfile.cloneNode(true))
|
||||
document.getElementsByClassName("navbar-item logout")[0].text="Exit to Control Panel \u00BB";
|
||||
div = document.getElementsByClassName("container")[0];
|
||||
callback = function(){
|
||||
if (document.getElementsByClassName("navbar-item logout")[0]){
|
||||
if ( document.getElementsByClassName("navbar-item logout")[0].text != "Exit to Control Panel \u00BB" ){
|
||||
var navProfile = document.getElementsByClassName("navbar-item profile")[0]; navProfile.replaceWith(navProfile.cloneNode(true))
|
||||
document.getElementsByClassName("navbar-item logout")[0].text="Exit to Control Panel \u00BB";
|
||||
}
|
||||
}
|
||||
}
|
||||
config = {
|
||||
childList:true,
|
||||
subtree:true
|
||||
}
|
||||
observer = new MutationObserver(callback);
|
||||
observer.observe(div,config);
|
||||
}
|
||||
}, 200);
|
||||
</script>',
|
||||
];
|
||||
|
||||
return $dist_config;
|
||||
71
install/deb/filemanager/install-fm.sh
Executable file
71
install/deb/filemanager/install-fm.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Checking root permissions
|
||||
if [ "x$(id -u)" != 'x0' ]; then
|
||||
echo "Error: Script can be run executed only by root"
|
||||
exit 10
|
||||
fi
|
||||
|
||||
if [ -z "$HESTIA" ]; then
|
||||
HESTIA="/usr/local/hestia"
|
||||
fi
|
||||
|
||||
user='admin'
|
||||
fm_error='no'
|
||||
source $HESTIA/func/main.sh
|
||||
source $HESTIA/install/upgrade/upgrade.conf
|
||||
|
||||
if [ -z "$HOMEDIR" ] || [ -z "$HESTIA_INSTALL_DIR" ]; then
|
||||
echo "Error: Hestia environment vars not present"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
FM_INSTALL_DIR="$HESTIA/web/fm"
|
||||
|
||||
FM_FILE="filegator_latest"
|
||||
FM_URL="https://github.com/filegator/static/raw/master/builds/filegator_latest.zip"
|
||||
|
||||
COMPOSER_BIN="$HOMEDIR/$user/.composer/composer"
|
||||
if [ ! -f "$COMPOSER_BIN" ]; then
|
||||
$BIN/v-add-user-composer "$user"
|
||||
if [ $? -ne 0 ]; then
|
||||
$BIN/v-add-user-notification admin 'Composer installation failed!' '<p class="u-text-bold">The File Manager will not work without Composer.</p><p>Please try running the installer from a shell session:<br><code>bash $HESTIA/install/deb/filemanager/install-fm.sh</code></p><p>If this issue continues, please <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank">open an issue on GitHub</a>.</p>'
|
||||
fm_error='yes'
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$fm_error" != "yes" ]; then
|
||||
rm --recursive --force "$FM_INSTALL_DIR"
|
||||
mkdir -p "$FM_INSTALL_DIR"
|
||||
cd "$FM_INSTALL_DIR"
|
||||
|
||||
[ ! -f "${FM_INSTALL_DIR}/${FM_FILE}" ] && wget "$FM_URL" --quiet -O "${FM_INSTALL_DIR}/${FM_FILE}.zip"
|
||||
|
||||
unzip -qq "${FM_INSTALL_DIR}/${FM_FILE}.zip"
|
||||
mv --force ${FM_INSTALL_DIR}/filegator/* "${FM_INSTALL_DIR}"
|
||||
rm --recursive --force ${FM_INSTALL_DIR}/${FM_FILE}
|
||||
[[ -f "${FM_INSTALL_DIR}/${FM_FILE}" ]] && rm "${FM_INSTALL_DIR}/${FM_FILE}"
|
||||
|
||||
cp --recursive --force ${HESTIA_INSTALL_DIR}/filemanager/filegator/* "${FM_INSTALL_DIR}"
|
||||
|
||||
chown $user: -R "${FM_INSTALL_DIR}"
|
||||
|
||||
# Check if php7.3 is available and run the installer
|
||||
if [ -f "/usr/bin/php7.3" ]; then
|
||||
COMPOSER_HOME="$HOMEDIR/$user/.config/composer" user_exec /usr/bin/php7.3 $COMPOSER_BIN --quiet --no-dev install
|
||||
if [ $? -ne 0 ]; then
|
||||
$BIN/v-add-user-notification admin 'File Manager installation failed!' '<p>Please try running the installer from a shell session:<br><code>bash $HESTIA/install/deb/filemanager/install-fm.sh</code></p><p>If this issue continues, please <a href="https://github.com/hestiacp/hestiacp/issues" target="_blank">open an issue on GitHub</a>.</p>'
|
||||
fm_error="yes"
|
||||
fi
|
||||
else
|
||||
$BIN/v-add-user-notification admin 'File Manager installation failed!' '<p class="u-text-bold">Unable to proceed with installation of File Manager.</p><p>Package <span class="u-text-bold">php7.3-cli</span> is missing from your system. Please check your PHP installation and environment settings.</p>'
|
||||
fm_error="yes"
|
||||
fi
|
||||
|
||||
if [ "$fm_error" != "yes" ]; then
|
||||
chown root: -R "${FM_INSTALL_DIR}"
|
||||
chown $user: "${FM_INSTALL_DIR}/private"
|
||||
chown $user: "${FM_INSTALL_DIR}/private/logs"
|
||||
chown $user: "${FM_INSTALL_DIR}/repository"
|
||||
fi
|
||||
fi
|
||||
19
install/deb/logrotate/apache2
Normal file
19
install/deb/logrotate/apache2
Normal file
@@ -0,0 +1,19 @@
|
||||
/var/log/apache2/*.log /var/log/apache2/domains/*log {
|
||||
rotate 4
|
||||
weekly
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
delaycompress
|
||||
create 640
|
||||
sharedscripts
|
||||
postrotate
|
||||
/etc/init.d/apache2 reload > /dev/null || true
|
||||
[ ! -f /run/nginx.pid ] || kill -USR1 `cat /run/nginx.pid`
|
||||
endscript
|
||||
prerotate
|
||||
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
|
||||
run-parts /etc/logrotate.d/httpd-prerotate; \
|
||||
fi; \
|
||||
endscript
|
||||
}
|
||||
12
install/deb/logrotate/dovecot
Normal file
12
install/deb/logrotate/dovecot
Normal file
@@ -0,0 +1,12 @@
|
||||
/var/log/dovecot*.log {
|
||||
rotate 4
|
||||
weekly
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
delaycompress
|
||||
sharedscripts
|
||||
postrotate
|
||||
doveadm log reopen
|
||||
endscript
|
||||
}
|
||||
7
install/deb/logrotate/hestia
Normal file
7
install/deb/logrotate/hestia
Normal file
@@ -0,0 +1,7 @@
|
||||
/var/log/hestia/*.log {
|
||||
rotate 12
|
||||
monthly
|
||||
missingok
|
||||
notifempty
|
||||
create 0600 root root
|
||||
}
|
||||
4
install/deb/logrotate/httpd-prerotate/awstats
Executable file
4
install/deb/logrotate/httpd-prerotate/awstats
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Changes made by HestiaCP due to https://github.com/hestiacp/hestiacp/issues/3289
|
||||
/usr/local/hestia/bin/v-update-sys-queue webstats
|
||||
13
install/deb/logrotate/nginx
Normal file
13
install/deb/logrotate/nginx
Normal file
@@ -0,0 +1,13 @@
|
||||
/var/log/nginx/*log /var/log/nginx/domains/*log {
|
||||
rotate 4
|
||||
weekly
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
delaycompress
|
||||
create 640
|
||||
sharedscripts
|
||||
postrotate
|
||||
[ -f /run/nginx.pid ] && kill -USR1 `cat /run/nginx.pid`
|
||||
endscript
|
||||
}
|
||||
7
install/deb/logrotate/roundcube
Normal file
7
install/deb/logrotate/roundcube
Normal file
@@ -0,0 +1,7 @@
|
||||
/var/log/roundcube/*.log {
|
||||
rotate 12
|
||||
monthly
|
||||
missingok
|
||||
notifempty
|
||||
create 644 www-data www-data
|
||||
}
|
||||
50
install/deb/mysql/my-large.cnf
Normal file
50
install/deb/mysql/my-large.cnf
Normal file
@@ -0,0 +1,50 @@
|
||||
[client]
|
||||
port=3306
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
default-character-set=utf8mb4
|
||||
|
||||
[mysql]
|
||||
default-character-set=utf8mb4
|
||||
|
||||
[mysqld_safe]
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
|
||||
[mysqld]
|
||||
user=mysql
|
||||
pid-file=/run/mysqld/mysqld.pid
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
port=3306
|
||||
basedir=/usr
|
||||
datadir=/var/lib/mysql
|
||||
tmpdir=/tmp
|
||||
lc-messages-dir=/usr/share/mysql
|
||||
log_error=/var/log/mysql/error.log
|
||||
collation-server = utf8mb4_unicode_520_ci
|
||||
init-connect='SET NAMES utf8mb4'
|
||||
character-set-server = utf8mb4
|
||||
|
||||
symbolic-links=0
|
||||
local-infile=0
|
||||
|
||||
skip-external-locking
|
||||
key_buffer_size = 256M
|
||||
max_allowed_packet = 32M
|
||||
table_open_cache = 256
|
||||
sort_buffer_size = 1M
|
||||
read_buffer_size = 1M
|
||||
read_rnd_buffer_size = 4M
|
||||
myisam_sort_buffer_size = 64M
|
||||
thread_cache_size = 8
|
||||
query_cache_size= 16M
|
||||
|
||||
#innodb_use_native_aio = 0
|
||||
innodb_file_per_table
|
||||
|
||||
max_connections=200
|
||||
max_user_connections=50
|
||||
wait_timeout=10
|
||||
interactive_timeout=50
|
||||
long_query_time=5
|
||||
|
||||
!includedir /etc/mysql/conf.d/
|
||||
!includedir /etc/mysql/mariadb.conf.d/
|
||||
49
install/deb/mysql/my-medium.cnf
Normal file
49
install/deb/mysql/my-medium.cnf
Normal file
@@ -0,0 +1,49 @@
|
||||
[client]
|
||||
port=3306
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
default-character-set=utf8mb4
|
||||
|
||||
[mysql]
|
||||
default-character-set=utf8mb4
|
||||
|
||||
[mysqld_safe]
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
|
||||
[mysqld]
|
||||
user=mysql
|
||||
pid-file=/run/mysqld/mysqld.pid
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
port=3306
|
||||
basedir=/usr
|
||||
datadir=/var/lib/mysql
|
||||
tmpdir=/tmp
|
||||
lc-messages-dir=/usr/share/mysql
|
||||
log_error=/var/log/mysql/error.log
|
||||
collation-server = utf8mb4_unicode_520_ci
|
||||
init-connect='SET NAMES utf8mb4'
|
||||
character-set-server = utf8mb4
|
||||
|
||||
symbolic-links=0
|
||||
local-infile=0
|
||||
|
||||
skip-external-locking
|
||||
key_buffer_size = 16M
|
||||
max_allowed_packet = 16M
|
||||
table_open_cache = 64
|
||||
sort_buffer_size = 512K
|
||||
net_buffer_length = 8K
|
||||
read_buffer_size = 256K
|
||||
read_rnd_buffer_size = 512K
|
||||
myisam_sort_buffer_size = 8M
|
||||
|
||||
#innodb_use_native_aio = 0
|
||||
innodb_file_per_table
|
||||
|
||||
max_connections=70
|
||||
max_user_connections=30
|
||||
wait_timeout=10
|
||||
interactive_timeout=50
|
||||
long_query_time=5
|
||||
|
||||
!includedir /etc/mysql/conf.d/
|
||||
!includedir /etc/mysql/mariadb.conf.d/
|
||||
49
install/deb/mysql/my-small.cnf
Normal file
49
install/deb/mysql/my-small.cnf
Normal file
@@ -0,0 +1,49 @@
|
||||
[client]
|
||||
port=3306
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
default-character-set=utf8mb4
|
||||
|
||||
[mysql]
|
||||
default-character-set=utf8mb4
|
||||
|
||||
[mysqld_safe]
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
|
||||
[mysqld]
|
||||
user=mysql
|
||||
pid-file=/run/mysqld/mysqld.pid
|
||||
socket=/run/mysqld/mysqld.sock
|
||||
port=3306
|
||||
basedir=/usr
|
||||
datadir=/var/lib/mysql
|
||||
tmpdir=/tmp
|
||||
lc-messages-dir=/usr/share/mysql
|
||||
log_error=/var/log/mysql/error.log
|
||||
collation-server = utf8mb4_unicode_520_ci
|
||||
init-connect='SET NAMES utf8mb4'
|
||||
character-set-server = utf8mb4
|
||||
|
||||
symbolic-links=0
|
||||
local-infile=0
|
||||
|
||||
skip-external-locking
|
||||
key_buffer_size = 16K
|
||||
max_allowed_packet = 1M
|
||||
table_open_cache = 10
|
||||
sort_buffer_size = 64K
|
||||
read_buffer_size = 256K
|
||||
read_rnd_buffer_size = 256K
|
||||
net_buffer_length = 2K
|
||||
thread_stack = 240K
|
||||
|
||||
#innodb_use_native_aio = 0
|
||||
innodb_file_per_table
|
||||
|
||||
max_connections=30
|
||||
max_user_connections=20
|
||||
wait_timeout=10
|
||||
interactive_timeout=50
|
||||
long_query_time=5
|
||||
|
||||
!includedir /etc/mysql/conf.d/
|
||||
!includedir /etc/mysql/mariadb.conf.d/
|
||||
39
install/deb/nginx/0rtt-anti-replay.conf
Normal file
39
install/deb/nginx/0rtt-anti-replay.conf
Normal file
@@ -0,0 +1,39 @@
|
||||
# Implement TLS 1.3 0-RTT anti-replay for NGINX
|
||||
|
||||
# Requires: NGINX directive "ssl_early_data" on
|
||||
|
||||
# Usage:
|
||||
|
||||
# Make sure these "map" blocks are included in "http" block
|
||||
# Put the following two lines in SSL "server" block, before any "location" blocks
|
||||
|
||||
# if ($anti_replay = 307) { return 307 https://$host$request_uri; }
|
||||
# if ($anti_replay = 425) { return 425; }
|
||||
|
||||
# Pass "Early-Data" header to backend/upstream
|
||||
# Only for 0-RTT requests from clients that understand 425 status code (RFC 8470)
|
||||
|
||||
# fastcgi_param HTTP_EARLY_DATA $rfc_early_data if_not_empty;
|
||||
# proxy_set_header Early-Data $rfc_early_data;
|
||||
|
||||
# Copyright © myrevery
|
||||
# Copyright © 7677333 (An anagram of a Anonymous Cybersecurity Research Team)
|
||||
|
||||
map "$request_method:$is_args" $ar_idempotent {
|
||||
default 0;
|
||||
"~^GET:$|^(HEAD|OPTIONS|TRACE):\?*$" 1;
|
||||
}
|
||||
|
||||
map $http_user_agent $ar_support_425 {
|
||||
default 0;
|
||||
"~Firefox/((58|59)|([6-9]\d)|([1-9]\d{2,}))\.\d+" 1;
|
||||
}
|
||||
|
||||
map "$ssl_early_data:$ar_idempotent:$ar_support_425" $anti_replay {
|
||||
1:0:0 307;
|
||||
1:0:1 425;
|
||||
}
|
||||
|
||||
map "$ssl_early_data:$ar_support_425" $rfc_early_data {
|
||||
1:1 1;
|
||||
}
|
||||
16
install/deb/nginx/agents.conf
Normal file
16
install/deb/nginx/agents.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
map $http_user_agent $mobile_request {
|
||||
default desktopversion;
|
||||
"~*ipad" mobileversion;
|
||||
"~*android.*mobile" mobileversion;
|
||||
"~*iphone" mobileversion;
|
||||
"~*ipod.*mobile" mobileversion;
|
||||
"~*BlackBerry*Mobile Safari" mobileversion;
|
||||
"~*BB*Mobile Safari" mobileversion;
|
||||
"~*Opera.*Mini/7" mobileversion;
|
||||
"~*IEMobile/10.*Touch" mobileversion;
|
||||
"~*IEMobile/11.*Touch" mobileversion;
|
||||
"~*IEMobile/7.0" mobileversion;
|
||||
"~*IEMobile/9.0" mobileversion;
|
||||
"~*Firefox.*Mobile" mobileversion;
|
||||
"~*webOS" mobileversion;
|
||||
}
|
||||
130
install/deb/nginx/nginx.conf
Normal file
130
install/deb/nginx/nginx.conf
Normal file
@@ -0,0 +1,130 @@
|
||||
# Server globals
|
||||
user www-data;
|
||||
worker_processes auto;
|
||||
worker_rlimit_nofile 65535;
|
||||
error_log /var/log/nginx/error.log;
|
||||
pid /run/nginx.pid;
|
||||
include /etc/nginx/conf.d/main/*.conf;
|
||||
include /etc/nginx/modules-enabled/*.conf;
|
||||
|
||||
# Worker config
|
||||
events {
|
||||
worker_connections 1024;
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
# Main settings
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
client_header_timeout 180s;
|
||||
client_body_timeout 180s;
|
||||
client_header_buffer_size 2k;
|
||||
client_body_buffer_size 256k;
|
||||
client_max_body_size 1024m;
|
||||
large_client_header_buffers 4 8k;
|
||||
send_timeout 60s;
|
||||
keepalive_timeout 30s;
|
||||
keepalive_requests 10000;
|
||||
reset_timedout_connection on;
|
||||
server_tokens off;
|
||||
server_name_in_redirect off;
|
||||
server_names_hash_max_size 512;
|
||||
server_names_hash_bucket_size 512;
|
||||
charset utf-8;
|
||||
# FastCGI settings
|
||||
fastcgi_buffers 512 4k;
|
||||
fastcgi_buffer_size 256k;
|
||||
fastcgi_busy_buffers_size 256k;
|
||||
fastcgi_temp_file_write_size 256k;
|
||||
fastcgi_connect_timeout 30s;
|
||||
fastcgi_read_timeout 300s;
|
||||
fastcgi_send_timeout 180s;
|
||||
fastcgi_cache_lock on;
|
||||
fastcgi_cache_lock_timeout 5s;
|
||||
fastcgi_cache_background_update on;
|
||||
fastcgi_cache_revalidate on;
|
||||
# Proxy settings
|
||||
proxy_redirect off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Early-Data $rfc_early_data;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass_header Set-Cookie;
|
||||
proxy_buffers 256 4k;
|
||||
proxy_buffer_size 32k;
|
||||
proxy_busy_buffers_size 32k;
|
||||
proxy_temp_file_write_size 256k;
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 180s;
|
||||
# Log format
|
||||
log_format main '$remote_addr - $remote_user [$time_local] $request "$status" $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
|
||||
log_format bytes '$body_bytes_sent';
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
# Mime settings
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
# Compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_static on;
|
||||
gzip_comp_level 6;
|
||||
gzip_min_length 1024;
|
||||
gzip_buffers 128 4k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/css text/javascript text/js text/plain text/richtext text/shtml text/x-component text/x-java-source text/x-markdown text/x-script text/xml image/bmp image/svg+xml image/vnd.microsoft.icon image/x-icon font/otf font/ttf font/x-woff multipart/bag multipart/mixed application/eot application/font application/font-sfnt application/font-woff application/javascript application/javascript-binast application/json application/ld+json application/manifest+json application/opentype application/otf application/rss+xml application/ttf application/truetype application/vnd.api+json application/vnd.ms-fontobject application/wasm application/xhtml+xml application/xml application/xml+rss application/x-httpd-cgi application/x-javascript application/x-opentype application/x-otf application/x-perl application/x-protobuf application/x-ttf;
|
||||
gzip_proxied any;
|
||||
# Cloudflare IPs
|
||||
include /etc/nginx/conf.d/cloudflare.inc;
|
||||
# SSL PCI compliance
|
||||
ssl_buffer_size 1369;
|
||||
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256";
|
||||
ssl_dhparam /etc/ssl/dhparam.pem;
|
||||
ssl_early_data on;
|
||||
ssl_ecdh_curve auto;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_session_cache shared:SSL:20m;
|
||||
ssl_session_tickets on;
|
||||
ssl_session_timeout 7d;
|
||||
resolver 1.0.0.1 8.8.4.4 1.1.1.1 8.8.8.8 valid=300s ipv6=off;
|
||||
resolver_timeout 5s;
|
||||
# Error pages
|
||||
error_page 403 /error/404.html;
|
||||
error_page 404 /error/404.html;
|
||||
error_page 410 /error/410.html;
|
||||
error_page 500 501 502 503 504 505 /error/50x.html;
|
||||
# Proxy cache
|
||||
proxy_cache_path /var/cache/nginx levels=2 keys_zone=cache:10m inactive=60m max_size=1024m;
|
||||
proxy_cache_key "$scheme$request_method$host$request_uri";
|
||||
proxy_temp_path /var/cache/nginx/temp;
|
||||
proxy_ignore_headers Cache-Control Expires;
|
||||
proxy_cache_use_stale error timeout invalid_header updating http_502;
|
||||
proxy_cache_valid any 1d;
|
||||
# FastCGI cache
|
||||
fastcgi_cache_path /var/cache/nginx/micro levels=1:2 keys_zone=microcache:10m inactive=30m max_size=1024m;
|
||||
fastcgi_cache_key "$scheme$request_method$host$request_uri";
|
||||
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
|
||||
fastcgi_cache_use_stale error timeout invalid_header updating http_500 http_503;
|
||||
add_header X-FastCGI-Cache $upstream_cache_status;
|
||||
|
||||
# Cache bypass
|
||||
map $http_cookie $no_cache {
|
||||
default 0;
|
||||
~SESS 1;
|
||||
~wordpress_logged_in 1;
|
||||
}
|
||||
|
||||
# File cache (static assets)
|
||||
open_file_cache max=10000 inactive=30s;
|
||||
open_file_cache_valid 60s;
|
||||
open_file_cache_min_uses 2;
|
||||
open_file_cache_errors off;
|
||||
# Wildcard include
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/conf.d/domains/*.conf;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user