merge upstream changes proposed for 2204
This commit is contained in:
parent
9327a1df4f
commit
9ee26d3ef1
|
@ -15,12 +15,18 @@ LINK TBD
|
||||||
No features of Mail-in-a-Box have changed in this release, but with the newer version of Ubuntu the following software packages we use are updated:
|
No features of Mail-in-a-Box have changed in this release, but with the newer version of Ubuntu the following software packages we use are updated:
|
||||||
|
|
||||||
* dovecot is upgraded to 2.3.16, postfix to 3.6.4, opendmark to 1.4 (which adds ARC-Authentication-Results headers), and spampd to 2.53 (alleviating a mail delivery rate limiting bug).
|
* dovecot is upgraded to 2.3.16, postfix to 3.6.4, opendmark to 1.4 (which adds ARC-Authentication-Results headers), and spampd to 2.53 (alleviating a mail delivery rate limiting bug).
|
||||||
* Nextcloud is upgraded to 24.0.0 with PHP updated from 7.2 to 8.1.
|
* Nextcloud is upgraded to 24.0.0
|
||||||
|
* Roundcube is upgraded to 1.6.0.
|
||||||
* certbot is upgraded to 1.21 (via the Ubuntu repository instead of a PPA).
|
* certbot is upgraded to 1.21 (via the Ubuntu repository instead of a PPA).
|
||||||
* fail2ban is upgraded to 0.11.2.
|
* fail2ban is upgraded to 0.11.2.
|
||||||
* nginx is upgraded to 1.18.
|
* nginx is upgraded to 1.18.
|
||||||
|
* PHP is upgraded from 7.2 to 8.1.
|
||||||
* bind9 is replaced with unbound
|
* bind9 is replaced with unbound
|
||||||
|
|
||||||
|
Also:
|
||||||
|
|
||||||
|
* Roundcube's login session cookie was tightened. Existing sessions may require a manual logout.
|
||||||
|
|
||||||
Version 57a (June 19, 2022)
|
Version 57a (June 19, 2022)
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ After=multi-user.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=idle
|
Type=idle
|
||||||
|
IgnoreSIGPIPE=False
|
||||||
ExecStart=/usr/local/lib/mailinabox/start
|
ExecStart=/usr/local/lib/mailinabox/start
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|
|
@ -22,20 +22,8 @@ class AuthService:
|
||||||
def init_system_api_key(self):
|
def init_system_api_key(self):
|
||||||
"""Write an API key to a local file so local processes can use the API"""
|
"""Write an API key to a local file so local processes can use the API"""
|
||||||
|
|
||||||
def create_file_with_mode(path, mode):
|
with open(self.key_path, 'r') as file:
|
||||||
# Based on answer by A-B-B: http://stackoverflow.com/a/15015748
|
self.key = file.read()
|
||||||
old_umask = os.umask(0)
|
|
||||||
try:
|
|
||||||
return os.fdopen(os.open(path, os.O_WRONLY | os.O_CREAT, mode), 'w')
|
|
||||||
finally:
|
|
||||||
os.umask(old_umask)
|
|
||||||
|
|
||||||
self.key = secrets.token_hex(32)
|
|
||||||
|
|
||||||
os.makedirs(os.path.dirname(self.key_path), exist_ok=True)
|
|
||||||
|
|
||||||
with create_file_with_mode(self.key_path, 0o640) as key_file:
|
|
||||||
key_file.write(self.key + '\n')
|
|
||||||
|
|
||||||
def authenticate(self, request, env, login_only=False, logout=False):
|
def authenticate(self, request, env, login_only=False, logout=False):
|
||||||
"""Test if the HTTP Authorization header's username matches the system key, a session key,
|
"""Test if the HTTP Authorization header's username matches the system key, a session key,
|
||||||
|
|
|
@ -463,7 +463,7 @@ def list_target_files(config):
|
||||||
path = ''
|
path = ''
|
||||||
|
|
||||||
if bucket == "":
|
if bucket == "":
|
||||||
raise ValueError(f"Enter an S3 bucket name. // {url}")
|
raise ValueError("Enter an S3 bucket name.")
|
||||||
|
|
||||||
# connect to the region & bucket
|
# connect to the region & bucket
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -123,8 +123,8 @@ def index():
|
||||||
no_admins_exist = (len(get_admins(env)) == 0)
|
no_admins_exist = (len(get_admins(env)) == 0)
|
||||||
|
|
||||||
import boto3.s3
|
import boto3.s3
|
||||||
from urllib.parse import urlparse
|
backup_s3_hosts = [(r, f"s3.{r}.amazonaws.com") for r in boto3.session.Session().get_available_regions('s3')]
|
||||||
backup_s3_hosts = [(r, urlparse(boto3.client('s3', region_name=r).meta.endpoint_url).netloc) for r in boto3.session.Session().get_available_regions('s3')]
|
|
||||||
|
|
||||||
return render_template('index.html',
|
return render_template('index.html',
|
||||||
hostname=env['PRIMARY_HOSTNAME'],
|
hostname=env['PRIMARY_HOSTNAME'],
|
||||||
|
|
|
@ -269,6 +269,7 @@ function show_custom_backup() {
|
||||||
$("#backup-target-type").val("s3");
|
$("#backup-target-type").val("s3");
|
||||||
var hostpath = r.target.substring(5).split('/');
|
var hostpath = r.target.substring(5).split('/');
|
||||||
var host = hostpath.shift();
|
var host = hostpath.shift();
|
||||||
|
$("#backup-target-s3-host-select").val(host);
|
||||||
$("#backup-target-s3-host").val(host);
|
$("#backup-target-s3-host").val(host);
|
||||||
$("#backup-target-s3-path").val(hostpath.join('/'));
|
$("#backup-target-s3-path").val(hostpath.join('/'));
|
||||||
} else if (r.target.substring(0, 5) == "b2://") {
|
} else if (r.target.substring(0, 5) == "b2://") {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
from daemon import app
|
||||||
|
import auth, utils
|
||||||
|
|
||||||
|
app.logger.addHandler(utils.create_syslog_handler())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(port=10222)
|
|
@ -26,10 +26,6 @@ if [ -z "$TAG" ]; then
|
||||||
# This machine is running Ubuntu 22.04, which is supported by
|
# This machine is running Ubuntu 22.04, which is supported by
|
||||||
# Mail-in-a-Box versions 60 and later.
|
# Mail-in-a-Box versions 60 and later.
|
||||||
TAG=v60
|
TAG=v60
|
||||||
elif [ "$UBUNTU_VERSION" == "Ubuntu 20.04 LTS" ]; then
|
|
||||||
# This machine is running Ubuntu 20.04, which is supported by
|
|
||||||
# Mail-in-a-Box versions 56 and later.
|
|
||||||
TAG=v57a
|
|
||||||
elif [ "$UBUNTU_VERSION" == "Ubuntu 18.04 LTS" ]; then
|
elif [ "$UBUNTU_VERSION" == "Ubuntu 18.04 LTS" ]; then
|
||||||
# This machine is running Ubuntu 18.04, which is supported by
|
# This machine is running Ubuntu 18.04, which is supported by
|
||||||
# Mail-in-a-Box versions 0.40 through 5x.
|
# Mail-in-a-Box versions 0.40 through 5x.
|
||||||
|
@ -46,7 +42,7 @@ if [ -z "$TAG" ]; then
|
||||||
echo "The last version of Mail-in-a-Box supporting Ubuntu 14.04 will be installed."
|
echo "The last version of Mail-in-a-Box supporting Ubuntu 14.04 will be installed."
|
||||||
TAG=v0.30
|
TAG=v0.30
|
||||||
else
|
else
|
||||||
echo "This script may be used only on a machine running Ubuntu 14.04, 18.04, 20.04 or 22.04."
|
echo "This script may be used only on a machine running Ubuntu 14.04, 18.04, or 22.04."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -50,7 +50,7 @@ hide_output $venv/bin/pip install --upgrade pip
|
||||||
# NOTE: email_validator is repeated in setup/questions.sh, so please keep the versions synced.
|
# NOTE: email_validator is repeated in setup/questions.sh, so please keep the versions synced.
|
||||||
hide_output $venv/bin/pip install --upgrade \
|
hide_output $venv/bin/pip install --upgrade \
|
||||||
rtyaml "email_validator>=1.0.0" "exclusiveprocess" \
|
rtyaml "email_validator>=1.0.0" "exclusiveprocess" \
|
||||||
flask dnspython python-dateutil expiringdict \
|
flask dnspython python-dateutil expiringdict gunicorn \
|
||||||
qrcode[pil] pyotp \
|
qrcode[pil] pyotp \
|
||||||
"idna>=2.0.0" "cryptography==37.0.2" psutil postfix-mta-sts-resolver \
|
"idna>=2.0.0" "cryptography==37.0.2" psutil postfix-mta-sts-resolver \
|
||||||
b2sdk boto3
|
b2sdk boto3
|
||||||
|
@ -90,6 +90,7 @@ rm -f /tmp/bootstrap.zip
|
||||||
|
|
||||||
# Create an init script to start the management daemon and keep it
|
# Create an init script to start the management daemon and keep it
|
||||||
# running after a reboot.
|
# running after a reboot.
|
||||||
|
# Note: Authentication currently breaks with more than 1 gunicorn worker.
|
||||||
cat > $inst_dir/start <<EOF;
|
cat > $inst_dir/start <<EOF;
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Set character encoding flags to ensure that any non-ASCII don't cause problems.
|
# Set character encoding flags to ensure that any non-ASCII don't cause problems.
|
||||||
|
@ -98,8 +99,13 @@ export LC_ALL=en_US.UTF-8
|
||||||
export LANG=en_US.UTF-8
|
export LANG=en_US.UTF-8
|
||||||
export LC_TYPE=en_US.UTF-8
|
export LC_TYPE=en_US.UTF-8
|
||||||
|
|
||||||
|
mkdir -p /var/lib/mailinabox
|
||||||
|
tr -cd '[:xdigit:]' < /dev/urandom | head -c 32 > /var/lib/mailinabox/api.key
|
||||||
|
chmod 640 /var/lib/mailinabox/api.key
|
||||||
|
|
||||||
source $venv/bin/activate
|
source $venv/bin/activate
|
||||||
exec python $(pwd)/management/daemon.py
|
export PYTHONPATH=$(pwd)/management
|
||||||
|
exec gunicorn -b localhost:10222 -w 1 wsgi:app
|
||||||
EOF
|
EOF
|
||||||
chmod +x $inst_dir/start
|
chmod +x $inst_dir/start
|
||||||
cp --remove-destination conf/mailinabox.service /lib/systemd/system/mailinabox.service # target was previously a symlink so remove it first
|
cp --remove-destination conf/mailinabox.service /lib/systemd/system/mailinabox.service # target was previously a symlink so remove it first
|
||||||
|
|
|
@ -386,9 +386,6 @@ cat > /etc/cron.d/mailinabox-nextcloud << EOF;
|
||||||
EOF
|
EOF
|
||||||
chmod +x /etc/cron.d/mailinabox-nextcloud
|
chmod +x /etc/cron.d/mailinabox-nextcloud
|
||||||
|
|
||||||
# Remove previous hourly cronjob
|
|
||||||
rm -f /etc/cron.hourly/mailinabox-owncloud
|
|
||||||
|
|
||||||
# There's nothing much of interest that a user could do as an admin for Nextcloud,
|
# There's nothing much of interest that a user could do as an admin for Nextcloud,
|
||||||
# and there's a lot they could mess up, so we don't make any users admins of Nextcloud.
|
# and there's a lot they could mess up, so we don't make any users admins of Nextcloud.
|
||||||
# But if we wanted to, we would do this:
|
# But if we wanted to, we would do this:
|
||||||
|
|
|
@ -7,9 +7,9 @@ if [[ $EUID -ne 0 ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check that we are running on Ubuntu 20.04 LTS or Ubuntu 22.04 LTS
|
# Check that we are running on Ubuntu 22.04 LTS (or 22.04.xx).
|
||||||
if [ "$( lsb_release --id --short )" != "Ubuntu" ] || [ "$( lsb_release --release --short )" != "22.04" -a "$( lsb_release --release --short )" != "20.04" ]; then
|
if [ "$( lsb_release --id --short )" != "Ubuntu" ] || [ "$( lsb_release --release --short )" != "22.04" ]; then
|
||||||
echo "Mail-in-a-Box only supports being installed on Ubuntu 20.04 or 22.04, sorry. You are running:"
|
echo "Mail-in-a-Box only supports being installed on Ubuntu 22.04, sorry. You are running:"
|
||||||
echo
|
echo
|
||||||
lsb_release --description --short
|
lsb_release --description --short
|
||||||
echo
|
echo
|
||||||
|
|
|
@ -22,7 +22,7 @@ source /etc/mailinabox.conf # load global vars
|
||||||
echo "Installing Roundcube (webmail)..."
|
echo "Installing Roundcube (webmail)..."
|
||||||
apt_install \
|
apt_install \
|
||||||
dbconfig-common \
|
dbconfig-common \
|
||||||
php-cli php-sqlite3 php-intl php-json php-common php-curl php-ldap \
|
php-cli php-sqlite3 php-intl php-json php-common php-curl php-imap \
|
||||||
php-gd php-pspell libjs-jquery libjs-jquery-mousewheel libmagic1 php-mbstring
|
php-gd php-pspell libjs-jquery libjs-jquery-mousewheel libmagic1 php-mbstring
|
||||||
|
|
||||||
# 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.
|
||||||
|
@ -124,8 +124,7 @@ cat > $RCM_CONFIG <<EOF;
|
||||||
\$config['log_dir'] = '/var/log/roundcubemail/';
|
\$config['log_dir'] = '/var/log/roundcubemail/';
|
||||||
\$config['temp_dir'] = '/var/tmp/roundcubemail/';
|
\$config['temp_dir'] = '/var/tmp/roundcubemail/';
|
||||||
\$config['db_dsnw'] = 'sqlite:///$STORAGE_ROOT/mail/roundcube/roundcube.sqlite?mode=0640';
|
\$config['db_dsnw'] = 'sqlite:///$STORAGE_ROOT/mail/roundcube/roundcube.sqlite?mode=0640';
|
||||||
\$config['default_host'] = 'ssl://localhost';
|
\$config['imap_host'] = 'ssl://localhost:993';
|
||||||
\$config['default_port'] = 993;
|
|
||||||
\$config['imap_conn_options'] = array(
|
\$config['imap_conn_options'] = array(
|
||||||
'ssl' => array(
|
'ssl' => array(
|
||||||
'verify_peer' => false,
|
'verify_peer' => false,
|
||||||
|
@ -133,7 +132,7 @@ cat > $RCM_CONFIG <<EOF;
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
\$config['imap_timeout'] = 180;
|
\$config['imap_timeout'] = 180;
|
||||||
\$config['smtp_server'] = 'tls://127.0.0.1';
|
\$config['smtp_host'] = 'tls://127.0.0.1';
|
||||||
\$config['smtp_conn_options'] = array(
|
\$config['smtp_conn_options'] = array(
|
||||||
'ssl' => array(
|
'ssl' => array(
|
||||||
'verify_peer' => false,
|
'verify_peer' => false,
|
||||||
|
@ -150,6 +149,10 @@ cat > $RCM_CONFIG <<EOF;
|
||||||
\$config['login_username_filter'] = 'email';
|
\$config['login_username_filter'] = 'email';
|
||||||
\$config['password_charset'] = 'UTF-8';
|
\$config['password_charset'] = 'UTF-8';
|
||||||
\$config['junk_mbox'] = 'Spam';
|
\$config['junk_mbox'] = 'Spam';
|
||||||
|
/* ensure roudcube session id's aren't leaked to other parts of the server */
|
||||||
|
\$config['session_path'] = '/mail/';
|
||||||
|
/* prevent CSRF, requires php 7.3+ */
|
||||||
|
\$config['session_samesite'] = 'Strict';
|
||||||
?>
|
?>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -216,5 +219,5 @@ chown www-data:www-data $STORAGE_ROOT/mail/roundcube/roundcube.sqlite
|
||||||
chmod 664 $STORAGE_ROOT/mail/roundcube/roundcube.sqlite
|
chmod 664 $STORAGE_ROOT/mail/roundcube/roundcube.sqlite
|
||||||
|
|
||||||
# Enable PHP modules.
|
# Enable PHP modules.
|
||||||
phpenmod -v php mcrypt imap
|
phpenmod -v php imap
|
||||||
restart_service php$PHP_VER-fpm
|
restart_service php$PHP_VER-fpm
|
||||||
|
|
|
@ -136,8 +136,9 @@ while len(input_lines) > 0:
|
||||||
# Put any settings we didn't see at the end of the file,
|
# Put any settings we didn't see at the end of the file,
|
||||||
# except settings being cleared.
|
# except settings being cleared.
|
||||||
for i in range(len(settings)):
|
for i in range(len(settings)):
|
||||||
if (i not in found) and not (not val and erase_setting):
|
if i not in found:
|
||||||
name, val = settings[i].split("=", 1)
|
name, val = settings[i].split("=", 1)
|
||||||
|
if not (not val and erase_setting):
|
||||||
buf += name + delimiter + val + "\n"
|
buf += name + delimiter + val + "\n"
|
||||||
|
|
||||||
if not testing:
|
if not testing:
|
||||||
|
|
Loading…
Reference in New Issue