mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2026-03-13 17:17:23 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b592b1e99 | ||
|
|
a67aa4cfd4 | ||
|
|
b7e9a90005 | ||
|
|
b3b798adf2 | ||
|
|
bd54b41041 | ||
|
|
a211ad422b | ||
|
|
ef28a1defd | ||
|
|
c5c413b447 | ||
|
|
d2beb3919b | ||
|
|
a7dded8182 | ||
|
|
000363492e | ||
|
|
5be74dec6e | ||
|
|
0335595e7e |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,6 +1,23 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
v0.30 (January 9, 2019)
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Setup:
|
||||||
|
|
||||||
|
* Update to Roundcube 1.3.8 and the CardDAV plugin to 3.0.3.
|
||||||
|
* Add missing rsyslog package to install line since some OS images don't have it installed by default.
|
||||||
|
* A log file for nsd was added.
|
||||||
|
|
||||||
|
Control Panel:
|
||||||
|
|
||||||
|
* The users page now documents that passwords should only have ASCII characters to prevent character encoding mismaches between clients and the server.
|
||||||
|
* The users page no longer shows user mailbox sizes because this was extremely slow for very large mailboxes.
|
||||||
|
* The Mail-in-a-Box version is now shown in the system status checks even when the new-version check is disabled.
|
||||||
|
* The alises page now warns that alises should not be used to forward mail off of the box. Mail filters within Roundcube are better for that.
|
||||||
|
* The explanation of greylisting has been improved.
|
||||||
|
|
||||||
v0.29 (October 25, 2018)
|
v0.29 (October 25, 2018)
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ by me:
|
|||||||
$ curl -s https://keybase.io/joshdata/key.asc | gpg --import
|
$ curl -s https://keybase.io/joshdata/key.asc | gpg --import
|
||||||
gpg: key C10BDD81: public key "Joshua Tauberer <jt@occams.info>" imported
|
gpg: key C10BDD81: public key "Joshua Tauberer <jt@occams.info>" imported
|
||||||
|
|
||||||
$ git verify-tag v0.29
|
$ git verify-tag v0.30
|
||||||
gpg: Signature made ..... using RSA key ID C10BDD81
|
gpg: Signature made ..... using RSA key ID C10BDD81
|
||||||
gpg: Good signature from "Joshua Tauberer <jt@occams.info>"
|
gpg: Good signature from "Joshua Tauberer <jt@occams.info>"
|
||||||
gpg: WARNING: This key is not certified with a trusted signature!
|
gpg: WARNING: This key is not certified with a trusted signature!
|
||||||
@@ -72,7 +72,7 @@ and on my [personal homepage](https://razor.occams.info/). (Of course, if this r
|
|||||||
|
|
||||||
Checkout the tag corresponding to the most recent release:
|
Checkout the tag corresponding to the most recent release:
|
||||||
|
|
||||||
$ git checkout v0.29
|
$ git checkout v0.30
|
||||||
|
|
||||||
Begin the installation.
|
Begin the installation.
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ def me():
|
|||||||
@authorized_personnel_only
|
@authorized_personnel_only
|
||||||
def mail_users():
|
def mail_users():
|
||||||
if request.args.get("format", "") == "json":
|
if request.args.get("format", "") == "json":
|
||||||
return json_response(get_mail_users_ex(env, with_archived=True, with_slow_info=True))
|
return json_response(get_mail_users_ex(env, with_archived=True))
|
||||||
else:
|
else:
|
||||||
return "".join(x+"\n" for x in get_mail_users(env))
|
return "".join(x+"\n" for x in get_mail_users(env))
|
||||||
|
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ def scan_mail_log(env):
|
|||||||
|
|
||||||
print(textwrap.fill(
|
print(textwrap.fill(
|
||||||
"The following mail was greylisted, meaning the emails were temporarily rejected. "
|
"The following mail was greylisted, meaning the emails were temporarily rejected. "
|
||||||
"Legitimate senders will try again within ten minutes.",
|
"Legitimate senders must try again after three minutes.",
|
||||||
width=80, initial_indent=" ", subsequent_indent=" "
|
width=80, initial_indent=" ", subsequent_indent=" "
|
||||||
), end='\n\n')
|
), end='\n\n')
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ def get_mail_users(env):
|
|||||||
users = [ row[0] for row in c.fetchall() ]
|
users = [ row[0] for row in c.fetchall() ]
|
||||||
return utils.sort_email_addresses(users, env)
|
return utils.sort_email_addresses(users, env)
|
||||||
|
|
||||||
def get_mail_users_ex(env, with_archived=False, with_slow_info=False):
|
def get_mail_users_ex(env, with_archived=False):
|
||||||
# Returns a complex data structure of all user accounts, optionally
|
# Returns a complex data structure of all user accounts, optionally
|
||||||
# including archived (status="inactive") accounts.
|
# including archived (status="inactive") accounts.
|
||||||
#
|
#
|
||||||
@@ -139,9 +139,6 @@ def get_mail_users_ex(env, with_archived=False, with_slow_info=False):
|
|||||||
}
|
}
|
||||||
users.append(user)
|
users.append(user)
|
||||||
|
|
||||||
if with_slow_info:
|
|
||||||
user["mailbox_size"] = utils.du(os.path.join(env['STORAGE_ROOT'], 'mail/mailboxes', *reversed(email.split("@"))))
|
|
||||||
|
|
||||||
# Add in archived accounts.
|
# Add in archived accounts.
|
||||||
if with_archived:
|
if with_archived:
|
||||||
root = os.path.join(env['STORAGE_ROOT'], 'mail/mailboxes')
|
root = os.path.join(env['STORAGE_ROOT'], 'mail/mailboxes')
|
||||||
@@ -158,8 +155,6 @@ def get_mail_users_ex(env, with_archived=False, with_slow_info=False):
|
|||||||
"mailbox": mbox,
|
"mailbox": mbox,
|
||||||
}
|
}
|
||||||
users.append(user)
|
users.append(user)
|
||||||
if with_slow_info:
|
|
||||||
user["mailbox_size"] = utils.du(mbox)
|
|
||||||
|
|
||||||
# Group by domain.
|
# Group by domain.
|
||||||
domains = { }
|
domains = { }
|
||||||
|
|||||||
@@ -795,14 +795,14 @@ def get_latest_miab_version():
|
|||||||
def check_miab_version(env, output):
|
def check_miab_version(env, output):
|
||||||
config = load_settings(env)
|
config = load_settings(env)
|
||||||
|
|
||||||
if config.get("privacy", True):
|
|
||||||
output.print_warning("Mail-in-a-Box version check disabled by privacy setting.")
|
|
||||||
else:
|
|
||||||
try:
|
try:
|
||||||
this_ver = what_version_is_this(env)
|
this_ver = what_version_is_this(env)
|
||||||
except:
|
except:
|
||||||
this_ver = "Unknown"
|
this_ver = "Unknown"
|
||||||
|
|
||||||
|
if config.get("privacy", True):
|
||||||
|
output.print_warning("You are running version Mail-in-a-Box %s. Mail-in-a-Box version check disabled by privacy setting." % this_ver)
|
||||||
|
else:
|
||||||
latest_ver = get_latest_miab_version()
|
latest_ver = get_latest_miab_version()
|
||||||
|
|
||||||
if this_ver == latest_ver:
|
if this_ver == latest_ver:
|
||||||
|
|||||||
@@ -39,8 +39,9 @@
|
|||||||
<label for="addaliasForwardsTo" class="col-sm-1 control-label">Forwards To</label>
|
<label for="addaliasForwardsTo" class="col-sm-1 control-label">Forwards To</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<textarea class="form-control" rows="3" id="addaliasForwardsTo"></textarea>
|
<textarea class="form-control" rows="3" id="addaliasForwardsTo"></textarea>
|
||||||
<div style="margin-top: 3px; padding-left: 3px; font-size: 90%" class="text-muted">
|
<div style="margin-top: 3px; padding-left: 3px; font-size: 90%">
|
||||||
<span class="domainalias">Enter just the part of an email address starting with the @-sign.</span>
|
<span class="domainalias text-muted">Enter just the part of an email address starting with the @-sign.</span>
|
||||||
|
<span class="text-danger">Only forward mail to addresses handled by this Mail-in-a-Box, since mail forwarded by aliases to other domains may be rejected or filtered by the receiver. To forward mail to other domains, create a mail user and then log into webmail for the user and create a filter rule to forward mail.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<h4>Greylisting</h4>
|
<h4>Greylisting</h4>
|
||||||
<p>Your box using a technique called greylisting to cut down on spam. Greylisting works by delaying mail from people you haven’t received mail from before for up to about 10 minutes. The vast majority of spam gets tricked by this. If you are waiting for an email from someone new, such as if you are registering on a new website and are waiting for an email confirmation, please give it up to 10-15 minutes to arrive.</p>
|
<p>Your box uses a technique called greylisting to cut down on spam. Greylisting works by initially rejecting mail from people you haven’t received mail from before. Legitimate mail servers will attempt redelivery shortly afterwards, but the vast majority of spam gets tricked by this. If you are waiting for an email from someone new, such as if you are registering on a new website and are waiting for an email confirmation, please be aware there will be a minimum of 3 minutes delay, depending how soon the remote server attempts redelivery.</p>
|
||||||
|
|
||||||
<h4>+tag addresses</h4>
|
<h4>+tag addresses</h4>
|
||||||
<p>Every incoming email address also receives mail for <code>+tag</code> addresses. If your email address is <code>you@yourdomain.com</code>, you’ll also automatically get mail sent to <code>you+anythinghere@yourdomain.com</code>. Use this as a fast way to segment incoming mail for your own filtering rules without having to create aliases in this control panel.</p>
|
<p>Every incoming email address also receives mail for <code>+tag</code> addresses. If your email address is <code>you@yourdomain.com</code>, you’ll also automatically get mail sent to <code>you+anythinghere@yourdomain.com</code>. Use this as a fast way to segment incoming mail for your own filtering rules without having to create aliases in this control panel.</p>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<button type="submit" class="btn btn-primary">Add User</button>
|
<button type="submit" class="btn btn-primary">Add User</button>
|
||||||
</form>
|
</form>
|
||||||
<ul style="margin-top: 1em; padding-left: 1.5em; font-size: 90%;">
|
<ul style="margin-top: 1em; padding-left: 1.5em; font-size: 90%;">
|
||||||
<li>Passwords must be at least eight characters and may not contain spaces. For best results, <a href="#" onclick="return generate_random_password()">generate a random password</a>.</li>
|
<li>Passwords must be at least eight characters consisting of English lettters and numbers only. For best results, <a href="#" onclick="return generate_random_password()">generate a random password</a>.</li>
|
||||||
<li>Use <a href="#" onclick="return show_panel('aliases')">aliases</a> to create email addresses that forward to existing accounts.</li>
|
<li>Use <a href="#" onclick="return show_panel('aliases')">aliases</a> to create email addresses that forward to existing accounts.</li>
|
||||||
<li>Administrators get access to this control panel.</li>
|
<li>Administrators get access to this control panel.</li>
|
||||||
<li>User accounts cannot contain any international (non-ASCII) characters, but <a href="#" onclick="return show_panel('aliases');">aliases</a> can.</li>
|
<li>User accounts cannot contain any international (non-ASCII) characters, but <a href="#" onclick="return show_panel('aliases');">aliases</a> can.</li>
|
||||||
@@ -43,7 +43,6 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th width="50%">Email Address</th>
|
<th width="50%">Email Address</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
<th>Mailbox Size</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -73,8 +72,6 @@
|
|||||||
archive account
|
archive account
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class='mailboxsize'>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr id="user-extra-template" class="if_inactive">
|
<tr id="user-extra-template" class="if_inactive">
|
||||||
<td colspan="3" style="border: 0; padding-top: 0">
|
<td colspan="3" style="border: 0; padding-top: 0">
|
||||||
@@ -156,7 +153,6 @@ function show_users() {
|
|||||||
|
|
||||||
n.attr('data-email', user.email);
|
n.attr('data-email', user.email);
|
||||||
n.find('.address').text(user.email)
|
n.find('.address').text(user.email)
|
||||||
n.find('.mailboxsize').text(nice_size(user.mailbox_size))
|
|
||||||
n2.find('.restore_info tt').text(user.mailbox);
|
n2.find('.restore_info tt').text(user.mailbox);
|
||||||
|
|
||||||
if (user.status == 'inactive') continue;
|
if (user.status == 'inactive') continue;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#########################################################
|
#########################################################
|
||||||
|
|
||||||
if [ -z "$TAG" ]; then
|
if [ -z "$TAG" ]; then
|
||||||
TAG=v0.29
|
TAG=v0.30
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Are we running as root?
|
# Are we running as root?
|
||||||
|
|||||||
13
setup/dns.sh
13
setup/dns.sh
@@ -26,6 +26,7 @@ cat > /etc/nsd/nsd.conf << EOF;
|
|||||||
# Do not edit. Overwritten by Mail-in-a-Box setup.
|
# Do not edit. Overwritten by Mail-in-a-Box setup.
|
||||||
server:
|
server:
|
||||||
hide-version: yes
|
hide-version: yes
|
||||||
|
logfile: "/var/log/nsd.log"
|
||||||
|
|
||||||
# identify the server (CH TXT ID.SERVER entry).
|
# identify the server (CH TXT ID.SERVER entry).
|
||||||
identity: ""
|
identity: ""
|
||||||
@@ -41,6 +42,18 @@ server:
|
|||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Add log rotation
|
||||||
|
cat > /etc/logrotate.d/nsd <<EOF;
|
||||||
|
/var/log/nsd.log {
|
||||||
|
weekly
|
||||||
|
missingok
|
||||||
|
rotate 12
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
notifempty
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
# Since we have bind9 listening on localhost for locally-generated
|
# Since we have bind9 listening on localhost for locally-generated
|
||||||
# DNS queries that require a recursive nameserver, and the system
|
# DNS queries that require a recursive nameserver, and the system
|
||||||
# might have other network interfaces for e.g. tunnelling, we have
|
# might have other network interfaces for e.g. tunnelling, we have
|
||||||
|
|||||||
@@ -148,6 +148,40 @@ def migration_11(env):
|
|||||||
# meh
|
# meh
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def migration_12(env):
|
||||||
|
# Upgrading to Carddav Roundcube plugin to version 3+, it requires the carddav_*
|
||||||
|
# tables to be dropped.
|
||||||
|
# Checking that the roundcube database already exists.
|
||||||
|
if os.path.exists(os.path.join(env["STORAGE_ROOT"], "mail/roundcube/roundcube.sqlite")):
|
||||||
|
import sqlite3
|
||||||
|
conn = sqlite3.connect(os.path.join(env["STORAGE_ROOT"], "mail/roundcube/roundcube.sqlite"))
|
||||||
|
c = conn.cursor()
|
||||||
|
# Get a list of all the tables that begin with 'carddav_'
|
||||||
|
c.execute("SELECT name FROM sqlite_master WHERE type = ? AND name LIKE ?", ('table', 'carddav_%'))
|
||||||
|
carddav_tables = c.fetchall()
|
||||||
|
# If there were tables that begin with 'carddav_', drop them
|
||||||
|
if carddav_tables:
|
||||||
|
for table in carddav_tables:
|
||||||
|
try:
|
||||||
|
table = table[0]
|
||||||
|
c = conn.cursor()
|
||||||
|
dropcmd = "DROP TABLE %s" % table
|
||||||
|
c.execute(dropcmd)
|
||||||
|
except:
|
||||||
|
print("Failed to drop table", table, e)
|
||||||
|
# Save.
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# Delete all sessions, requring users to login again to recreate carddav_*
|
||||||
|
# databases
|
||||||
|
conn = sqlite3.connect(os.path.join(env["STORAGE_ROOT"], "mail/roundcube/roundcube.sqlite"))
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("delete from session;")
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
def get_current_migration():
|
def get_current_migration():
|
||||||
ver = 0
|
ver = 0
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ echo Installing system packages...
|
|||||||
apt_install python3 python3-dev python3-pip \
|
apt_install python3 python3-dev python3-pip \
|
||||||
netcat-openbsd wget curl git sudo coreutils bc \
|
netcat-openbsd wget curl git sudo coreutils bc \
|
||||||
haveged pollinate unzip \
|
haveged pollinate unzip \
|
||||||
unattended-upgrades cron ntp fail2ban
|
unattended-upgrades cron ntp fail2ban rsyslog
|
||||||
|
|
||||||
# ### Add PHP7 PPA
|
# ### Add PHP7 PPA
|
||||||
|
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ apt-get purge -qq -y roundcube* #NODOC
|
|||||||
# Install Roundcube from source if it is not already present or if it is out of date.
|
# Install Roundcube from source if it is not already present or if it is out of date.
|
||||||
# Combine the Roundcube version number with the commit hash of plugins to track
|
# Combine the Roundcube version number with the commit hash of plugins to track
|
||||||
# whether we have the latest version of everything.
|
# whether we have the latest version of everything.
|
||||||
VERSION=1.3.7
|
VERSION=1.3.8
|
||||||
HASH=df0e29d09aae0b7a7ae98023dcd1ae3c6be77cd0
|
HASH=90c7900ccf7b2f46fe49c650d5adb9b85ee9cc22
|
||||||
PERSISTENT_LOGIN_VERSION=dc5ca3d3f4415cc41edb2fde533c8a8628a94c76
|
PERSISTENT_LOGIN_VERSION=dc5ca3d3f4415cc41edb2fde533c8a8628a94c76
|
||||||
HTML5_NOTIFIER_VERSION=4b370e3cd60dabd2f428a26f45b677ad1b7118d5
|
HTML5_NOTIFIER_VERSION=4b370e3cd60dabd2f428a26f45b677ad1b7118d5
|
||||||
CARDDAV_VERSION=2.0.4
|
CARDDAV_VERSION=3.0.3
|
||||||
CARDDAV_HASH=d93f3cfb3038a519e71c7c3212c1d16f5da609a4
|
CARDDAV_HASH=d1e3b0d851ffa2c6bd42bf0c04f70d0e1d0d78f8
|
||||||
|
|
||||||
UPDATE_KEY=$VERSION:$PERSISTENT_LOGIN_VERSION:$HTML5_NOTIFIER_VERSION:$CARDDAV_VERSION
|
UPDATE_KEY=$VERSION:$PERSISTENT_LOGIN_VERSION:$HTML5_NOTIFIER_VERSION:$CARDDAV_VERSION
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user