1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2024-12-25 07:47:05 +00:00

remove extra features from master branch

This commit is contained in:
John Supplee 2019-10-11 12:40:50 +02:00
parent 473d4616f2
commit e04f358cc4
20 changed files with 28 additions and 469 deletions

View File

@ -1 +0,0 @@
/usr/bin/doveadm fts rescan -A

View File

@ -1,2 +0,0 @@
*/1 * * * * root /usr/bin/curl http://127.0.0.1:8080/solr/update?commit=true &>/dev/null
30 3 * * * root /usr/bin/curl http://127.0.0.1:8080/solr/update?optimize=true &>/dev/null

View File

@ -1,6 +1,5 @@
## $HOSTNAME ## $HOSTNAME
#BEGIN_HTTP
# Redirect all HTTP to HTTPS *except* the ACME challenges (Let's Encrypt TLS certificate # Redirect all HTTP to HTTPS *except* the ACME challenges (Let's Encrypt TLS certificate
# domain validation challenges) path, which must be served over HTTP per the ACME spec # domain validation challenges) path, which must be served over HTTP per the ACME spec
# (due to some Apache vulnerability). # (due to some Apache vulnerability).
@ -29,12 +28,11 @@ server {
alias $STORAGE_ROOT/ssl/lets_encrypt/webroot/.well-known/acme-challenge/; alias $STORAGE_ROOT/ssl/lets_encrypt/webroot/.well-known/acme-challenge/;
} }
} }
#END_HTTP
# The secure HTTPS server. # The secure HTTPS server.
server { server {
listen $HTTP_SSL_PORT ssl http2; listen 443 ssl http2;
listen [::]:$HTTP_SSL_PORT ssl http2; listen [::]:443 ssl http2;
server_name $HOSTNAME; server_name $HOSTNAME;

View File

@ -59,7 +59,7 @@ class KeyAuthService:
credentials = decode(credentials) credentials = decode(credentials)
if ":" not in credentials: if ":" not in credentials:
return credentials, None return None, None
username, password = credentials.split(':', maxsplit=1) username, password = credentials.split(':', maxsplit=1)
return username, password return username, password

View File

@ -1,7 +1,5 @@
import os, os.path, re, json, time import os, os.path, re, json, time
import subprocess import subprocess
import base64
import sys
from functools import wraps from functools import wraps
@ -349,34 +347,6 @@ def dns_get_dump():
from dns_update import build_recommended_dns from dns_update import build_recommended_dns
return json_response(build_recommended_dns(env)) return json_response(build_recommended_dns(env))
@app.route('/letsencrypt/dns-auth/<domain>/<token>', methods=['GET'])
@authorized_personnel_only
def letsencrypt_dns_auth(domain, token):
from dns_update import do_dns_update, set_custom_dns_record
try:
qname = '_acme-challenge.' + domain
if set_custom_dns_record(qname, 'TXT', token, 'add', env):
if not do_dns_update(env):
return ("Error updating DNS", 400)
return "OK"
except ValueError as e:
return (str(e), 400)
@app.route('/letsencrypt/dns-cleanup/<domain>', methods=['GET'])
@authorized_personnel_only
def letsencrypt_dns_cleanup(domain):
from dns_update import do_dns_update, set_custom_dns_record
try:
qname = '_acme-challenge.' + domain
if set_custom_dns_record(qname, 'TXT', None, 'remove', env):
if not do_dns_update(env):
return ("Error updating DNS", 400)
return "OK"
except ValueError as e:
return (str(e), 400)
# SSL # SSL
@app.route('/ssl/status') @app.route('/ssl/status')
@ -573,62 +543,28 @@ def privacy_status_set():
utils.write_settings(config, env) utils.write_settings(config, env)
return "OK" return "OK"
# Quotas
@app.route('/system/default-quota', methods=["GET"]) @app.route('/system/default-quota', methods=["GET"])
@authorized_personnel_only @authorized_personnel_only
def default_quota_get(): def default_quota_get():
if request.values.get('text'): if request.values.get('text'):
return get_default_quota(env) return get_default_quota(env)
else: else:
return json_response({ return json_response({
"default-quota": get_default_quota(env), "default-quota": get_default_quota(env),
}) })
@app.route('/system/default-quota', methods=["POST"]) @app.route('/system/default-quota', methods=["POST"])
@authorized_personnel_only @authorized_personnel_only
def default_quota_set(): def default_quota_set():
config = utils.load_settings(env) config = utils.load_settings(env)
try: try:
config["default-quota"] = validate_quota(request.values.get('default_quota')) config["default-quota"] = validate_quota(request.values.get('default_quota'))
utils.write_settings(config, env) utils.write_settings(config, env)
except ValueError as e: except ValueError as e:
return ("ERROR: %s" % str(e), 400) return ("ERROR: %s" % str(e), 400)
return "OK"
# Mailgraph
@app.route('/mailgraph/image.cgi', methods=['GET'])
@authorized_personnel_only
def mailgraph():
if request.query_string:
query = request.query_string.decode('utf-8', 'ignore')
if '&' in query:
query = query.split('&')[0]
print("QUERY_STRING=%s" % query, file=sys.stderr)
code, bin_out = utils.shell(
"check_output",
["/usr/share/mailgraph/mailgraph.cgi"],
env={"QUERY_STRING": query},
return_bytes=True,
trap=True
)
if code != 0:
return ('Error generating mailgraph image: %s' % query, 500)
headers, image_bytes = bin_out.split(b'\n\n', 1)
return base64.b64encode(image_bytes)
return ('Mailgraph: no image requested', 500)
return "OK"
# MUNIN # MUNIN

View File

@ -313,7 +313,6 @@ def provision_certificates(env, limit_domains):
webroot = os.path.join(account_path, 'webroot') webroot = os.path.join(account_path, 'webroot')
os.makedirs(webroot, exist_ok=True) os.makedirs(webroot, exist_ok=True)
with tempfile.TemporaryDirectory() as d: with tempfile.TemporaryDirectory() as d:
miab_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
cert_file = os.path.join(d, 'cert_and_chain.pem') cert_file = os.path.join(d, 'cert_and_chain.pem')
print("Provisioning TLS certificates for " + ", ".join(domain_list) + ".") print("Provisioning TLS certificates for " + ", ".join(domain_list) + ".")
certbotret = subprocess.check_output([ certbotret = subprocess.check_output([
@ -329,10 +328,7 @@ def provision_certificates(env, limit_domains):
"--chain-path", os.path.join(d, 'chain'), # we only use the full chain "--chain-path", os.path.join(d, 'chain'), # we only use the full chain
"--fullchain-path", cert_file, "--fullchain-path", cert_file,
"--manual", "--webroot", "--webroot-path", webroot,
"--preferred-challenge", "dns",
"--manual-auth-hook", os.path.join(miab_dir, "tools/dns-auth.sh"),
"--manual-cleanup-hook", os.path.join(miab_dir, "tools/dns-cleanup.sh"),
"--config-dir", account_path, "--config-dir", account_path,
#"--staging", #"--staging",

View File

@ -26,7 +26,6 @@ def get_services():
{ "name": "Dovecot LMTP LDA", "port": 10026, "public": False, }, { "name": "Dovecot LMTP LDA", "port": 10026, "public": False, },
{ "name": "Postgrey", "port": 10023, "public": False, }, { "name": "Postgrey", "port": 10023, "public": False, },
{ "name": "Spamassassin", "port": 10025, "public": False, }, { "name": "Spamassassin", "port": 10025, "public": False, },
{ "name": "IMAP Quota", "port": 12340, "public": False },
{ "name": "OpenDKIM", "port": 8891, "public": False, }, { "name": "OpenDKIM", "port": 8891, "public": False, },
{ "name": "OpenDMARC", "port": 8893, "public": False, }, { "name": "OpenDMARC", "port": 8893, "public": False, },
{ "name": "Mail-in-a-Box Management Daemon", "port": 10222, "public": False, }, { "name": "Mail-in-a-Box Management Daemon", "port": 10222, "public": False, },
@ -39,7 +38,6 @@ def get_services():
{ "name": "Mail Filters (Sieve/dovecot)", "port": 4190, "public": True, }, { "name": "Mail Filters (Sieve/dovecot)", "port": 4190, "public": True, },
{ "name": "HTTP Web (nginx)", "port": 80, "public": True, }, { "name": "HTTP Web (nginx)", "port": 80, "public": True, },
{ "name": "HTTPS Web (nginx)", "port": 443, "public": True, }, { "name": "HTTPS Web (nginx)", "port": 443, "public": True, },
{ "name": "Solr Full Text Search (tomcat)", "port": 8080, "public": False, },
] ]
def run_checks(rounded_values, env, output, pool): def run_checks(rounded_values, env, output, pool):

View File

@ -102,7 +102,6 @@
<li><a href="#mail-guide" onclick="return show_panel(this);">Instructions</a></li> <li><a href="#mail-guide" onclick="return show_panel(this);">Instructions</a></li>
<li><a href="#users" onclick="return show_panel(this);">Users</a></li> <li><a href="#users" onclick="return show_panel(this);">Users</a></li>
<li><a href="#aliases" onclick="return show_panel(this);">Aliases</a></li> <li><a href="#aliases" onclick="return show_panel(this);">Aliases</a></li>
<li><a href="#mailgraph" onclick="return show_panel(this);">Mailgraph</a></li>
</ul> </ul>
</li> </li>
<li><a href="#sync_guide" onclick="return show_panel(this);">Contacts/Calendar</a></li> <li><a href="#sync_guide" onclick="return show_panel(this);">Contacts/Calendar</a></li>
@ -152,10 +151,6 @@
{% include "sync-guide.html" %} {% include "sync-guide.html" %}
</div> </div>
<div id="panel_mailgraph" class="admin_panel">
{% include "mailgraph.html" %}
</div>
<div id="panel_web" class="admin_panel"> <div id="panel_web" class="admin_panel">
{% include "web.html" %} {% include "web.html" %}
</div> </div>

View File

@ -1,48 +0,0 @@
<h2>Mail statistics</h2>
<ul id="jump">
<li><a href="#G0">Day</a>&nbsp;</li>
<li><a href="#G1">Week</a>&nbsp;</li>
<li><a href="#G2">Month</a>&nbsp;</li>
<li><a href="#G3">Year</a>&nbsp;</li>
</ul>
<h3 id="G0">Last Day</h3>
<p><img src="" data-src="/mailgraph/image.cgi?0-n" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?0-e" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?0-g" alt="mailgraph"/></p>
<h3 id="G1">Last Week</h3>
<p><img src="" data-src="/mailgraph/image.cgi?1-n" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?1-e" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?1-g" alt="mailgraph"/></p>
<h3 id="G2">Last Month</h3>
<p><img src="" data-src="/mailgraph/image.cgi?2-n" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?2-e" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?2-g" alt="mailgraph"/></p>
<h3 id="G3">Last Year</h3>
<p><img src="" data-src="/mailgraph/image.cgi?3-n" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?3-e" alt="mailgraph"/></p>
<p><img src="" data-src="/mailgraph/image.cgi?3-g" alt="mailgraph"/></p>
<hr/>
<p><a href="http://mailgraph.schweikert.ch/">Mailgraph</a> 1.14 by <a href="http://david.schweikert.ch/">David Schweikert</a>
(built on Tobi Oetiker's <a href="http://oss.oetiker.ch/rrdtool/">RRDtool</a>)</p>
<script type="text/javascript">
function show_mailgraph() {
$('[data-src]').each(function() {
var that = this;
api(
$(that).attr('data-src'),
'GET',
'',
function(data) {
$(that).attr('src', 'data:image/gif;base64,' + data);
}
);
});
}
</script>

View File

@ -100,20 +100,6 @@ def do_web_update(env):
# Add default 'www.' redirect. # Add default 'www.' redirect.
nginx_conf += make_domain_config(domain, [template0, template3], ssl_certificates, env) nginx_conf += make_domain_config(domain, [template0, template3], ssl_certificates, env)
if str(env['HTTP_SSL_PORT']) != "443":
in_http = False
new_conf = ''
for line in nginx_conf.split('\n'):
if line.strip() == '#BEGIN_HTTP':
in_http = True
elif line.strip() == '#END_HTTP':
in_http = False
if not in_http:
new_conf += line + '\n'
nginx_conf = new_conf
# Did the file change? If not, don't bother writing & restarting nginx. # Did the file change? If not, don't bother writing & restarting nginx.
nginx_conf_fn = "/etc/nginx/conf.d/local.conf" nginx_conf_fn = "/etc/nginx/conf.d/local.conf"
if os.path.exists(nginx_conf_fn): if os.path.exists(nginx_conf_fn):
@ -198,12 +184,8 @@ def make_domain_config(domain, templates, ssl_certificates, env):
nginx_conf = re.sub("[ \t]*# ADDITIONAL DIRECTIVES HERE *\n", t, nginx_conf) nginx_conf = re.sub("[ \t]*# ADDITIONAL DIRECTIVES HERE *\n", t, nginx_conf)
# Replace substitution strings in the template & return. # Replace substitution strings in the template & return.
if int(env['HTTP_SSL_PORT']) != 443:
# disable the regular HTTP server
nginx_conf = re.sub(r'#BEGIN_HTTP.*?#END_HTTP', repl='', string=nginx_conf, flags=re.MULTILINE)
nginx_conf = nginx_conf.replace("$STORAGE_ROOT", env['STORAGE_ROOT']) nginx_conf = nginx_conf.replace("$STORAGE_ROOT", env['STORAGE_ROOT'])
nginx_conf = nginx_conf.replace("$HOSTNAME", domain) nginx_conf = nginx_conf.replace("$HOSTNAME", domain)
nginx_conf = nginx_conf.replace("$HTTP_SSL_PORT", env['HTTP_SSL_PORT'])
nginx_conf = nginx_conf.replace("$ROOT", root) nginx_conf = nginx_conf.replace("$ROOT", root)
nginx_conf = nginx_conf.replace("$SSL_KEY", tls_cert["private-key"]) nginx_conf = nginx_conf.replace("$SSL_KEY", tls_cert["private-key"])
nginx_conf = nginx_conf.replace("$SSL_CERTIFICATE", tls_cert["certificate"]) nginx_conf = nginx_conf.replace("$SSL_CERTIFICATE", tls_cert["certificate"])

View File

@ -1,11 +0,0 @@
rtyaml
email_validator>=1.0.0
exclusiveprocess
flask
dnspython
python-dateutil
idna>=2.0.0
cryptography==2.2.2
boto
psutil
npyscreen

View File

@ -42,8 +42,7 @@ source /etc/mailinabox.conf # load global vars
# * `ca-certificates`: A trust store used to squelch postfix warnings about # * `ca-certificates`: A trust store used to squelch postfix warnings about
# untrusted opportunistically-encrypted connections. # untrusted opportunistically-encrypted connections.
echo "Installing Postfix (SMTP server)..." echo "Installing Postfix (SMTP server)..."
apt_install postfix postfix-sqlite postfix-pcre postgrey ca-certificates \ apt_install postfix postfix-sqlite postfix-pcre postgrey ca-certificates
postfix-policyd-spf-python postsrsd
# ### Basic Settings # ### Basic Settings
@ -98,9 +97,7 @@ tools/editconf.py /etc/postfix/master.cf -s -w \
-o cleanup_service_name=authclean" \ -o cleanup_service_name=authclean" \
"authclean=unix n - - - 0 cleanup "authclean=unix n - - - 0 cleanup
-o header_checks=pcre:/etc/postfix/outgoing_mail_header_filters -o header_checks=pcre:/etc/postfix/outgoing_mail_header_filters
-o nested_header_checks=" \ -o nested_header_checks="
"policy-spf=unix - n n - - spawn
user=nobody argv=/usr/bin/policyd-spf"
# Install the `outgoing_mail_header_filters` file required by the new 'authclean' service. # Install the `outgoing_mail_header_filters` file required by the new 'authclean' service.
cp conf/postfix_outgoing_mail_header_filters /etc/postfix/outgoing_mail_header_filters cp conf/postfix_outgoing_mail_header_filters /etc/postfix/outgoing_mail_header_filters
@ -199,23 +196,9 @@ tools/editconf.py /etc/postfix/main.cf lmtp_destination_recipient_limit=1
# so these IPs get mail delivered quickly. But when an IP is not listed in the permit_dnswl_client list (i.e. it is not #NODOC # so these IPs get mail delivered quickly. But when an IP is not listed in the permit_dnswl_client list (i.e. it is not #NODOC
# whitelisted) then postfix does a DEFER_IF_REJECT, which results in all "unknown user" sorts of messages turning into #NODOC # whitelisted) then postfix does a DEFER_IF_REJECT, which results in all "unknown user" sorts of messages turning into #NODOC
# "450 4.7.1 Client host rejected: Service unavailable". This is a retry code, so the mail doesn't properly bounce. #NODOC # "450 4.7.1 Client host rejected: Service unavailable". This is a retry code, so the mail doesn't properly bounce. #NODOC
tools/editconf.py /etc/postfix/main.cf \
postconf -e smtpd_sender_restrictions="reject_non_fqdn_sender,reject_unknown_sender_domain,reject_authenticated_sender_login_mismatch,reject_rhsbl_sender dbl.spamhaus.org" smtpd_sender_restrictions="reject_non_fqdn_sender,reject_unknown_sender_domain,reject_authenticated_sender_login_mismatch,reject_rhsbl_sender dbl.spamhaus.org" \
smtpd_recipient_restrictions=permit_sasl_authenticated,permit_mynetworks,"reject_rbl_client zen.spamhaus.org",reject_unlisted_recipient,"check_policy_service inet:127.0.0.1:10023","check_policy_service inet:127.0.0.1:12340"
RECIPIENT_RESTRICTIONS="permit_sasl_authenticated,permit_mynetworks,reject_rbl_client zen.spamhaus.org,reject_unlisted_recipient"
if [ $POSTGREY == 1 ]; then
RECIPIENT_RESTRICTIONS="${RECIPIENT_RESTRICTIONS},check_policy_service inet:127.0.0.1:10023"
fi
if [ $POLICY_SPF == 1 ]; then
RECIPIENT_RESTRICTIONS="${RECIPIENT_RESTRICTIONS},check_policy_service unix:private/policy-spf"
fi
# Add quota check
RECIPIENT_RESTRICTIONS="${RECIPIENT_RESTRICTIONS},check_policy_service inet:127.0.0.1:12340"
postconf -e smtpd_recipient_restrictions="$RECIPIENT_RESTRICTIONS"
# Postfix connects to Postgrey on the 127.0.0.1 interface specifically. Ensure that # Postfix connects to Postgrey on the 127.0.0.1 interface specifically. Ensure that
# Postgrey listens on the same interface (and not IPv6, for instance). # Postgrey listens on the same interface (and not IPv6, for instance).
@ -259,29 +242,6 @@ chmod +x /etc/cron.daily/mailinabox-postgrey-whitelist
tools/editconf.py /etc/postfix/main.cf \ tools/editconf.py /etc/postfix/main.cf \
message_size_limit=134217728 message_size_limit=134217728
if [ $POSTSRSD == 1 ]; then
# Setup SRS
postconf -e \
sender_canonical_maps=tcp:localhost:10001 \
sender_canonical_classes=envelope_sender \
recipient_canonical_maps=tcp:localhost:10002 \
recipient_canonical_classes=envelope_recipient,header_recipient
hide_output systemctl enable postsrsd
hide_output systemctl restart postsrsd
else
postconf -e \
sender_canonical_maps= \
sender_canonical_classes= \
recipient_canonical_maps= \
recipient_canonical_classes=
hide_output systemctl disable postsrsd
hide_output systemctl stop postsrsd
fi
# Allow the two SMTP ports in the firewall. # Allow the two SMTP ports in the firewall.
ufw_allow smtp ufw_allow smtp
@ -290,11 +250,4 @@ ufw_allow submission
# Restart services # Restart services
restart_service postfix restart_service postfix
restart_service postgrey
if [ $POSTGREY == 1 ]; then
hide_output systemctl enable postgrey
hide_output systemctl restart postgrey
else
hide_output systemctl disable postgrey
hide_output systemctl stop postgrey
fi

View File

@ -1,93 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
import npyscreen
import sys
import os
class OptionsApp(npyscreen.NPSApp):
def main(self):
# These lines create the form and populate it with widgets.
# A fairly complex screen in only 8 or so lines of code - a line for each control.
npyscreen.setTheme(npyscreen.Themes.BlackOnWhiteTheme)
form = npyscreen.Form(name = "Mail-in-a-Box Options",)
form.add(
npyscreen.TitleFixedText,
name="POSTGREY",
value="",
editable=False
)
form.add(
npyscreen.MultiLineEdit,
value="The Postgrey service greylists incoming messages from unknown senders.\n"
"It can be useful for fighting spam but often causes message delivery\n"
"delays of several minutes.",
max_height=4,
editable=False
)
form.add(
npyscreen.TitleFixedText,
name="POSTSRSD",
value="",
editable=False
)
form.add(
npyscreen.MultiLineEdit,
value="The PostSRSd daemon performs return path rewriting using the SRS protocol.\n"
"Not that all messages, including locally delivered mail will have their return\n"
"paths rewritten",
max_height=4,
editable=False
)
form.add(
npyscreen.TitleFixedText,
name="POLICY_SPF",
value="",
editable=False
)
form.add(
npyscreen.MultiLineEdit,
value=""
"The policy SPF service checks the SPF of incoming mails and rejects those\n"
"that do not qualify. This helps to prevent spoofing, but if valid mail does\n"
"not have SPF configured properly it will be rejected.",
max_height=4,
editable=False
)
init_values = []
if int(os.getenv('POSTGREY', 1)) == 1:
init_values.append(0)
if int(os.getenv('POSTSRSD', 0)) == 1:
init_values.append(1)
if int(os.getenv('POLICY_SPF', 0)) == 1:
init_values.append(2)
options = form.add(
npyscreen.TitleMultiSelect,
max_height=-2,
value=init_values,
name="Options",
values= ["POSTGREY","POSTSRSD","POLICY_SPF"],
scroll_exit=True
)
# This lets the user interact with the Form.
form.edit()
with open('_options.sh', 'w') as output:
print('POSTGREY=%i' % (1 if 0 in options.value else 0), file=output)
print('POSTSRSD=%i' % (1 if 1 in options.value else 0), file=output)
print('POLICY_SPF=%i' % (1 if 2 in options.value else 0), file=output)
# print(npyscreen.ThemeManager.default_colors, file=output)
if __name__ == "__main__":
App = OptionsApp()
App.run()

View File

@ -16,7 +16,6 @@ if [ -z "${NONINTERACTIVE:-}" ]; then
# we install it inside a virtualenv. In this script, we don't have the virtualenv yet # we install it inside a virtualenv. In this script, we don't have the virtualenv yet
# so we install the python package globally. # so we install the python package globally.
hide_output pip3 install "email_validator>=1.0.0" || exit 1 hide_output pip3 install "email_validator>=1.0.0" || exit 1
hide_output pip3 install npyscreen || exit 1
message_box "Mail-in-a-Box Installation" \ message_box "Mail-in-a-Box Installation" \
"Hello and thanks for deploying a Mail-in-a-Box! "Hello and thanks for deploying a Mail-in-a-Box!
@ -194,16 +193,6 @@ if [ -z "${STORAGE_ROOT:-}" ]; then
STORAGE_ROOT=$([[ -z "${DEFAULT_STORAGE_ROOT:-}" ]] && echo "/home/$STORAGE_USER" || echo "$DEFAULT_STORAGE_ROOT") STORAGE_ROOT=$([[ -z "${DEFAULT_STORAGE_ROOT:-}" ]] && echo "/home/$STORAGE_USER" || echo "$DEFAULT_STORAGE_ROOT")
fi fi
# export options variables so they are visible to the options program
export POSTGREY
export POSTSRSD
export POLICY_SPF
python3 setup/options-dialog.py
source ./_options.sh
rm _options.sh
# Show the configuration, since the user may have not entered it manually. # Show the configuration, since the user may have not entered it manually.
echo echo
echo "Primary Hostname: $PRIMARY_HOSTNAME" echo "Primary Hostname: $PRIMARY_HOSTNAME"

View File

@ -1,85 +0,0 @@
#!/bin/bash
#
# Inspired by the solr.sh from jkaberg (https://github.com/jkaberg/mailinabox-sogo)
# with some modifications
#
# IMAP search with lucene via solr
# --------------------------------
#
# By default dovecot uses its own Squat search index that has awful performance
# on large mailboxes. Dovecot 2.1+ has support for using Lucene internally but
# this didn't make it into the Ubuntu packages, so we use Solr instead to run
# Lucene for us.
#
# Solr runs as a tomcat process. The dovecot solr plugin talks to solr via its
# HTTP interface, causing mail to be indexed when searches occur, and getting
# results back.
source setup/functions.sh # load our functions
source /etc/mailinabox.conf # load global vars
# Install packages and basic configuation
# ---------------------------------------
echo "Installing Solr..."
# Install packages
apt_install solr-tomcat dovecot-solr
# Solr requires a schema to tell it how to index data, this is provided by dovecot
cp /usr/share/dovecot/solr-schema.xml /etc/solr/conf/schema.xml
# Update the dovecot plugin configuration
#
# Break-imap-search makes search work the way users expect, rather than the way
# the IMAP specification expects
tools/editconf.py /etc/dovecot/conf.d/10-mail.conf \
mail_plugins="fts fts_solr"
cat > /etc/dovecot/conf.d/90-plugin-fts.conf << EOF;
plugin {
fts = solr
fts_autoindex = yes
fts_solr = break-imap-search url=http://127.0.0.1:8080/solr/
}
EOF
# Bump memory allocation for Solr.
# Not needed? I'll let it sit here for a while.
#echo 'export JAVA_OPTS=-Xms512M -Xmx1024M' > /usr/share/tomcat7/bin/setenv.sh
# Install cronjobs to keep FTS up to date
hide_output install -m 755 conf/cronjob/dovecot /etc/cron.daily/
hide_output install -m 644 conf/cronjob/solr /etc/cron.d/
# PERMISSIONS
# Ensure configuration files are owned by dovecot and not world readable.
chown -R mail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot
mkdir -p /etc/systemd/system/tomcat9.service.d
cat > /etc/systemd/system/tomcat9.service.d/solr-permissions.conf << EOF
[Service]
ReadWritePaths=/var/lib/solr/
ReadWritePaths=/var/lib/solr/data/
EOF
# Restart services to reload solr schema & dovecot plugins
restart_service tomcat9
restart_service dovecot
# Kickoff building the index
# Per doveadm-fts manpage: Scan what mails exist in the full text search index
# and compare those to what actually exist in mailboxes.
# This removes mails from the index that have already been expunged and makes
# sure that the next doveadm index will index all the missing mails (if any).
doveadm fts rescan -A
# Adds unindexed files to the fts database
# * `-q`: Queues the indexing to be run by indexer process. (will background the indexing)
# * `-A`: All users
# * `'*'`: All folders
doveadm index -q -A '*'

View File

@ -42,22 +42,6 @@ else
FIRST_TIME_SETUP=1 FIRST_TIME_SETUP=1
fi fi
if [ -z "${HTTP_SSL_PORT:-}" ]; then
HTTP_SSL_PORT=$([[ -z "${DEFAULT_HTTP_SSL_PORT:-}" ]] && echo "443" || echo "$DEFAULT_HTTP_SSL_PORT")
fi
if [ -z "${POSTGREY:-}" ]; then
POSTGREY=$([[ -z "${DEFAULT_POSTGREY:-}" ]] && echo "1" || echo "$DEFAULT_POSTGREY")
fi
if [ -z "${POSTSRSD:-}" ]; then
POSTSRSD=$([[ -z "${DEFAULT_POSTSRSD:-}" ]] && echo "0" || echo "$DEFAULT_POSTSRSD")
fi
if [ -z "${POLICY_SPF:-}" ]; then
POLICY_SPF=$([[ -z "${DEFAULT_POLICY_SPF:-}" ]] && echo "0" || echo "$DEFAULT_POLICY_SPF")
fi
# Put a start script in a global location. We tell the user to run 'mailinabox' # Put a start script in a global location. We tell the user to run 'mailinabox'
# in the first dialog prompt, so we should do this before that starts. # in the first dialog prompt, so we should do this before that starts.
cat > /usr/local/bin/mailinabox << EOF; cat > /usr/local/bin/mailinabox << EOF;
@ -109,10 +93,6 @@ PUBLIC_IP=$PUBLIC_IP
PUBLIC_IPV6=$PUBLIC_IPV6 PUBLIC_IPV6=$PUBLIC_IPV6
PRIVATE_IP=$PRIVATE_IP PRIVATE_IP=$PRIVATE_IP
PRIVATE_IPV6=$PRIVATE_IPV6 PRIVATE_IPV6=$PRIVATE_IPV6
HTTP_SSL_PORT=$HTTP_SSL_PORT
POSTGREY=$POSTGREY
POSTSRSD=$POSTSRSD
POLICY_SPF=$POLICY_SPF
EOF EOF
# Start service configuration. # Start service configuration.
@ -122,7 +102,6 @@ source setup/dns.sh
source setup/mail-postfix.sh source setup/mail-postfix.sh
source setup/mail-dovecot.sh source setup/mail-dovecot.sh
source setup/mail-users.sh source setup/mail-users.sh
source setup/solr.sh
source setup/dkim.sh source setup/dkim.sh
source setup/spamassassin.sh source setup/spamassassin.sh
source setup/web.sh source setup/web.sh

View File

@ -19,7 +19,7 @@ fi
echo "Installing Nginx (web server)..." echo "Installing Nginx (web server)..."
apt_install nginx php-cli php-fpm fcgiwrap mailgraph apt_install nginx php-cli php-fpm
rm -f /etc/nginx/sites-enabled/default rm -f /etc/nginx/sites-enabled/default
@ -48,12 +48,6 @@ tools/editconf.py /etc/php/7.2/fpm/php.ini -c ';' \
tools/editconf.py /etc/php/7.2/fpm/php.ini -c ';' \ tools/editconf.py /etc/php/7.2/fpm/php.ini -c ';' \
default_charset="UTF-8" default_charset="UTF-8"
# Set higher timeout since searches with Roundcube and Solr may take longer
# than the default 60 seconds. We will also match Roundcube's timeout to the
# same value
tools/editconf.py /etc/php/7.2/fpm/php.ini -c ';' \
default_socket_timeout=180
# Switch from the dynamic process manager to the ondemand manager see #1216 # Switch from the dynamic process manager to the ondemand manager see #1216
tools/editconf.py /etc/php/7.2/fpm/pool.d/www.conf -c ';' \ tools/editconf.py /etc/php/7.2/fpm/pool.d/www.conf -c ';' \
pm=ondemand pm=ondemand
@ -102,9 +96,6 @@ restart_service nginx
restart_service php7.2-fpm restart_service php7.2-fpm
# Open ports. # Open ports.
if [ $HTTP_SSL_PORT == 443 ]; then ufw_allow http
ufw_allow http ufw_allow https
ufw_allow https
else
ufw_allow $HTTP_SSL_PORT
fi

View File

@ -108,7 +108,7 @@ cat > $RCM_CONFIG <<EOF;
'verify_peer_name' => false, 'verify_peer_name' => false,
), ),
); );
\$config['imap_timeout'] = 180; \$config['imap_timeout'] = 15;
\$config['smtp_server'] = 'tls://127.0.0.1'; \$config['smtp_server'] = 'tls://127.0.0.1';
\$config['smtp_port'] = 587; \$config['smtp_port'] = 587;
\$config['smtp_user'] = '%u'; \$config['smtp_user'] = '%u';

View File

@ -1,10 +0,0 @@
#!/usr/bin/env bash
# TODO: Make work with port other than 443
API_KEY=`cat /var/lib/mailinabox/api.key`
HOSTNAME=`hostname`
curl -s -X PUT -d "$CERTBOT_VALIDATION" --user "$API_KEY:" https://$HOSTNAME/admin/dns/custom/_acme-challenge.$CERTBOT_DOMAIN/TXT
sleep 15

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
# TODO: Make work with port other than 443
API_KEY=`cat /var/lib/mailinabox/api.key`
HOSTNAME=`hostname`
curl -s -X DELETE --user "$API_KEY:" https://$HOSTNAME/admin/dns/custom/_acme-challenge.$CERTBOT_DOMAIN/TXT