mirror of
				https://github.com/mail-in-a-box/mailinabox.git
				synced 2025-11-03 19:30:54 +00:00 
			
		
		
		
	remove extra features from master branch
This commit is contained in:
		
							parent
							
								
									473d4616f2
								
							
						
					
					
						commit
						e04f358cc4
					
				@ -1 +0,0 @@
 | 
				
			|||||||
/usr/bin/doveadm fts rescan -A
 | 
					 | 
				
			||||||
@ -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
 | 
					 | 
				
			||||||
@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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,9 +543,6 @@ 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():
 | 
				
			||||||
@ -599,37 +566,6 @@ def default_quota_set():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return "OK"
 | 
						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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# MUNIN
 | 
					# MUNIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route('/munin/')
 | 
					@app.route('/munin/')
 | 
				
			||||||
 | 
				
			|||||||
@ -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",
 | 
				
			||||||
 | 
				
			|||||||
@ -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):
 | 
				
			||||||
 | 
				
			|||||||
@ -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>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,48 +0,0 @@
 | 
				
			|||||||
<h2>Mail statistics</h2>
 | 
					 | 
				
			||||||
<ul id="jump">
 | 
					 | 
				
			||||||
  <li><a href="#G0">Day</a> </li>
 | 
					 | 
				
			||||||
  <li><a href="#G1">Week</a> </li>
 | 
					 | 
				
			||||||
  <li><a href="#G2">Month</a> </li>
 | 
					 | 
				
			||||||
  <li><a href="#G3">Year</a> </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>
 | 
					 | 
				
			||||||
@ -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"])
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
					 | 
				
			||||||
@ -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
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -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()
 | 
					 | 
				
			||||||
@ -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"
 | 
				
			||||||
 | 
				
			|||||||
@ -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 '*'
 | 
					 | 
				
			||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								setup/web.sh
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								setup/web.sh
									
									
									
									
									
								
							@ -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
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -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';
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
					 | 
				
			||||||
@ -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
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user