mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2026-03-04 15:54:48 +01:00
Merge branch 'master' into EHDD
This commit is contained in:
@@ -20,7 +20,7 @@ if [ -z "$TAG" ]; then
|
||||
# want to display in status checks.
|
||||
if [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/18\.04\.[0-9]/18.04/' `" == "Ubuntu 18.04 LTS" ]; then
|
||||
# This machine is running Ubuntu 18.04.
|
||||
TAG=v0.45
|
||||
TAG=v0.46
|
||||
|
||||
elif [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/14\.04\.[0-9]/14.04/' `" == "Ubuntu 14.04 LTS" ]; then
|
||||
# This machine is running Ubuntu 14.04.
|
||||
|
||||
18
setup/dns.sh
18
setup/dns.sh
@@ -62,6 +62,24 @@ for ip in $PRIVATE_IP $PRIVATE_IPV6; do
|
||||
echo " ip-address: $ip" >> /etc/nsd/nsd.conf;
|
||||
done
|
||||
|
||||
# nsd fails to start when ipv6 is disabled by the kernel on certain
|
||||
# interfaces without "do-ip6" set to "no" and "control-enable" to "no"
|
||||
# [confirm]. Even though the nsd docs say the default value for
|
||||
# control-enable is no, running "nsd-checkconf -o control-enable
|
||||
# /etc/nsd/nsd.conf" returns "yes", so we explicitly set it here.
|
||||
#
|
||||
# For instance, on Travis-CI, ipv6 is disabled on the lo and docker
|
||||
# interfaces, but enabled on the primary interface ens4. nsd fails to
|
||||
# start without these additions.
|
||||
if kernel_ipv6_lo_disabled; then
|
||||
cat >> /etc/nsd/nsd.conf <<EOF
|
||||
do-ip4: yes
|
||||
do-ip6: no
|
||||
remote-control:
|
||||
control-enable: no
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "include: /etc/nsd/zones.conf" >> /etc/nsd/nsd.conf;
|
||||
|
||||
# Create DNSSEC signing keys.
|
||||
|
||||
@@ -137,7 +137,14 @@ function get_default_privateip {
|
||||
function ufw_allow {
|
||||
if [ -z "${DISABLE_FIREWALL:-}" ]; then
|
||||
# ufw has completely unhelpful output
|
||||
ufw allow $1 > /dev/null;
|
||||
ufw allow "$1" > /dev/null;
|
||||
fi
|
||||
}
|
||||
|
||||
function ufw_limit {
|
||||
if [ -z "${DISABLE_FIREWALL:-}" ]; then
|
||||
# ufw has completely unhelpful output
|
||||
ufw limit "$1" > /dev/null;
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -235,3 +242,9 @@ function generate_password() {
|
||||
dd if=/dev/urandom bs=1 count=$input_len 2>/dev/null | base64 --wrap=0 | awk '{ gsub("/", ",", $0); print $0}'
|
||||
}
|
||||
|
||||
function kernel_ipv6_lo_disabled() {
|
||||
# Returns 0 if ipv6 is disabled on the loopback adapter
|
||||
local v="$(sysctl -n net.ipv6.conf.lo.disable_ipv6)"
|
||||
[ "$v" == "1" ] && return 0
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -71,42 +71,46 @@ wait_slapd_start() {
|
||||
say_verbose "...ok"
|
||||
}
|
||||
|
||||
_add_if_missing() {
|
||||
local var="$1"
|
||||
local val="$2"
|
||||
local conf="$MIAB_INTERNAL_CONF_FILE"
|
||||
if [ $(grep -c "^${var}=" "$conf") -eq 0 ]; then
|
||||
echo "${var}=\"${val}\"" >> "$conf"
|
||||
fi
|
||||
}
|
||||
|
||||
create_miab_conf() {
|
||||
# create (if non-existing) or load (existing) ldap/miab_ldap.conf
|
||||
if [ ! -e "$MIAB_INTERNAL_CONF_FILE" ]; then
|
||||
say_verbose "Generating a new $MIAB_INTERNAL_CONF_FILE"
|
||||
mkdir -p "$(dirname $MIAB_INTERNAL_CONF_FILE)"
|
||||
|
||||
# Use 64-character secret keys of safe characters
|
||||
cat > "$MIAB_INTERNAL_CONF_FILE" <<EOF
|
||||
LDAP_SERVER=127.0.0.1
|
||||
LDAP_SERVER_PORT=389
|
||||
LDAP_SERVER_STARTTLS=no
|
||||
LDAP_SERVER_TLS=no
|
||||
LDAP_URL=ldap://127.0.0.1/
|
||||
LDAP_BASE="${LDAP_BASE}"
|
||||
LDAP_SERVICES_BASE="${LDAP_SERVICES_BASE}"
|
||||
LDAP_CONFIG_BASE="${LDAP_CONFIG_BASE}"
|
||||
LDAP_DOMAINS_BASE="${LDAP_DOMAINS_BASE}"
|
||||
LDAP_PERMITTED_SENDERS_BASE="${LDAP_PERMITTED_SENDERS_BASE}"
|
||||
LDAP_USERS_BASE="${LDAP_USERS_BASE}"
|
||||
LDAP_ALIASES_BASE="${LDAP_ALIASES_BASE}"
|
||||
LDAP_ADMIN_DN="${LDAP_ADMIN_DN}"
|
||||
LDAP_ADMIN_PASSWORD="$(generate_password 64)"
|
||||
EOF
|
||||
touch "$MIAB_INTERNAL_CONF_FILE"
|
||||
fi
|
||||
|
||||
# ensure all required values exist, and if not set to default values
|
||||
_add_if_missing LDAP_SERVER 127.0.0.1
|
||||
_add_if_missing LDAP_SERVER_PORT 389
|
||||
_add_if_missing LDAP_SERVER_STARTTLS no
|
||||
_add_if_missing LDAP_SERVER_TLS no
|
||||
_add_if_missing LDAP_URL ldap://127.0.0.1/
|
||||
_add_if_missing LDAP_BASE "${LDAP_BASE}"
|
||||
_add_if_missing LDAP_SERVICES_BASE "${LDAP_SERVICES_BASE}"
|
||||
_add_if_missing LDAP_CONFIG_BASE "${LDAP_CONFIG_BASE}"
|
||||
_add_if_missing LDAP_DOMAINS_BASE "${LDAP_DOMAINS_BASE}"
|
||||
_add_if_missing LDAP_PERMITTED_SENDERS_BASE "${LDAP_PERMITTED_SENDERS_BASE}"
|
||||
_add_if_missing LDAP_USERS_BASE "${LDAP_USERS_BASE}"
|
||||
_add_if_missing LDAP_ALIASES_BASE "${LDAP_ALIASES_BASE}"
|
||||
_add_if_missing LDAP_ADMIN_DN "${LDAP_ADMIN_DN}"
|
||||
_add_if_missing LDAP_ADMIN_PASSWORD "$(generate_password 64)"
|
||||
|
||||
# add service account credentials
|
||||
local prefix
|
||||
for prefix in ${SERVICE_ACCOUNTS[*]}
|
||||
do
|
||||
if [ $(grep -c "^$prefix" "$MIAB_INTERNAL_CONF_FILE") -eq 0 ]; then
|
||||
local cn=$(awk -F_ '{print tolower($2)}' <<< $prefix)
|
||||
cat >>"$MIAB_INTERNAL_CONF_FILE" <<EOF
|
||||
${prefix}_DN="cn=$cn,$LDAP_SERVICES_BASE"
|
||||
${prefix}_PASSWORD="$(generate_password 64)"
|
||||
EOF
|
||||
fi
|
||||
local cn=$(awk -F_ '{print tolower($2)}' <<< $prefix)
|
||||
_add_if_missing "${prefix}_DN" "cn=$cn,$LDAP_SERVICES_BASE"
|
||||
_add_if_missing "${prefix}_PASSWORD" "$(generate_password 64)"
|
||||
done
|
||||
|
||||
chmod 0640 "$MIAB_INTERNAL_CONF_FILE"
|
||||
@@ -853,7 +857,13 @@ cat > /etc/logrotate.d/slapd <<EOF;
|
||||
EOF
|
||||
|
||||
# Modify olc server config like TLS
|
||||
modify_global_config
|
||||
# Skip this step if no ca_certificate.pem exists - this indicates
|
||||
# that the system hasn't yet been migrated from sqlite
|
||||
if [ -e "$STORAGE_ROOT/ssl/ca_certificate.pem" ]; then
|
||||
modify_global_config
|
||||
else
|
||||
say_debug "Not enabling TLS at this time - ca_certificate hasn't been generated yet"
|
||||
fi
|
||||
|
||||
# Add overlays and ensure mail-related attributes are indexed
|
||||
add_overlays
|
||||
|
||||
@@ -61,7 +61,7 @@ tools/editconf.py /etc/postfix/main.cf \
|
||||
myhostname=$PRIMARY_HOSTNAME\
|
||||
smtpd_banner="\$myhostname ESMTP Hi, I'm a Mail-in-a-Box (Ubuntu/Postfix; see https://mailinabox.email/)" \
|
||||
mydestination=localhost
|
||||
|
||||
|
||||
# Tweak some queue settings:
|
||||
# * Inform users when their e-mail delivery is delayed more than 3 hours (default is not to warn).
|
||||
# * Stop trying to send an undeliverable e-mail after 2 days (instead of 5), and for bounce messages just try for 1 day.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# helper functions for migration #13
|
||||
#
|
||||
|
||||
import uuid, os, sqlite3, ldap3
|
||||
import uuid, os, sqlite3, ldap3, hashlib
|
||||
|
||||
|
||||
def add_user(env, ldapconn, search_base, users_base, domains_base, email, password, privs, cn=None):
|
||||
@@ -29,9 +29,13 @@ def add_user(env, ldapconn, search_base, users_base, domains_base, email, passwo
|
||||
print("user already exists: %s" % email)
|
||||
return ldapconn.response[0]['dn']
|
||||
|
||||
# Generate a unique id for uid
|
||||
uid = '%s' % uuid.uuid4()
|
||||
|
||||
## Generate a unique id for uid
|
||||
#uid = '%s' % uuid.uuid4()
|
||||
# use a sha-1 hash of the email address for uid
|
||||
m = hashlib.sha1()
|
||||
m.update(bytearray(email.lower(),'utf-8'))
|
||||
uid = m.hexdigest()
|
||||
|
||||
# Attributes to apply to the new ldap entry
|
||||
attrs = {
|
||||
"mail" : email,
|
||||
|
||||
16
setup/mods.available/conf/zpush/backend_caldav.php
Normal file
16
setup/mods.available/conf/zpush/backend_caldav.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/***********************************************
|
||||
* File : config.php
|
||||
* Project : Z-Push
|
||||
* Descr : CalDAV backend configuration file
|
||||
************************************************/
|
||||
|
||||
define('CALDAV_PROTOCOL', 'NC_PROTO');
|
||||
define('CALDAV_SERVER', 'NC_HOST');
|
||||
define('CALDAV_PORT', 'NC_PORT');
|
||||
define('CALDAV_PATH', 'NC_PREFIX/remote.php/dav/calendars/%u/');
|
||||
define('CALDAV_PERSONAL', 'PRINCIPAL');
|
||||
define('CALDAV_SUPPORTS_SYNC', false);
|
||||
define('CALDAV_MAX_SYNC_PERIOD', 2147483647);
|
||||
|
||||
?>
|
||||
31
setup/mods.available/conf/zpush/backend_carddav.php
Normal file
31
setup/mods.available/conf/zpush/backend_carddav.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/***********************************************
|
||||
* File : config.php
|
||||
* Project : Z-Push
|
||||
* Descr : CardDAV backend configuration file
|
||||
************************************************/
|
||||
|
||||
|
||||
define('CARDDAV_PROTOCOL', 'NC_PROTO'); /* http or https */
|
||||
define('CARDDAV_SERVER', 'NC_HOST');
|
||||
define('CARDDAV_PORT', 'NC_PORT');
|
||||
define('CARDDAV_PATH', 'NC_PREFIX/remote.php/dav/addressbooks/users/%u/');
|
||||
define('CARDDAV_DEFAULT_PATH', 'NC_PREFIX/remote.php/dav/addressbooks/users/%u/contacts/'); /* subdirectory of the main path */
|
||||
define('CARDDAV_GAL_PATH', ''); /* readonly, searchable, not syncd */
|
||||
define('CARDDAV_GAL_MIN_LENGTH', 5);
|
||||
define('CARDDAV_CONTACTS_FOLDER_NAME', '%u Addressbook');
|
||||
define('CARDDAV_SUPPORTS_SYNC', false);
|
||||
|
||||
// If the CardDAV server supports the FN attribute for searches
|
||||
// DAViCal supports it, but SabreDav, Nextcloud and SOGo don't
|
||||
// Setting this to true will search by FN. If false will search by sn, givenName and email
|
||||
// It's safe to leave it as false
|
||||
define('CARDDAV_SUPPORTS_FN_SEARCH', false);
|
||||
|
||||
|
||||
// If your carddav server needs to use file extension to recover a vcard.
|
||||
// Davical needs it
|
||||
// SOGo official demo online needs it, but some SOGo installation don't need it, so test it
|
||||
define('CARDDAV_URL_VCARD_EXTENSION', '.vcf');
|
||||
|
||||
?>
|
||||
398
setup/mods.available/remote-nextcloud-use-miab.sh
Executable file
398
setup/mods.available/remote-nextcloud-use-miab.sh
Executable file
@@ -0,0 +1,398 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Run this script on your remote Nextcloud to configure it to use
|
||||
# Mail-in-a-Box-LDAP.
|
||||
#
|
||||
# The script will:
|
||||
# 1. enable the "LDAP user and group backend" in Nextcloud
|
||||
# 2. install calendar and contacts
|
||||
# 3. configure Nextcloud to access MiaB-LDAP for users and groups
|
||||
# 4. optionally install and configure ssmtp so system mail is
|
||||
# sent to MiaB-LDAP
|
||||
#
|
||||
VERBOSE=0
|
||||
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 <NCDIR> <NC_ADMIN_USER> <NC_ADMIN_PASSWORD> <MIAB_HOSTNAME> <LDAP_NEXTCLOUD_PASS> [ <SSMTP_ALERTS_EMAIL> <SSMTP_AUTH_USER> <SSMTP_AUTH_PASS> ]
|
||||
Configure Nextcloud to use MiaB-LDAP for users and groups
|
||||
Optionally configure a mail relay to MiaB-LDAP
|
||||
|
||||
Arguments:
|
||||
NCDIR
|
||||
the path to the local Nextcloud installation directory
|
||||
NC_ADMIN_USER
|
||||
a current Nextcloud username that has ADMIN rights
|
||||
NC_ADMIN_PASSWORD
|
||||
the password for NC_ADMIN
|
||||
MIAB_HOSTNAME
|
||||
the fully-qualified host name of MiaB-LDAP
|
||||
LDAP_NEXTCLOUD_PASS
|
||||
supply the password for the LDAP service account Nextcloud
|
||||
uses to locate and enumerate users and groups. A MiaB-LDAP
|
||||
installation automatically creates this limited-access service
|
||||
account with a long random password. Open
|
||||
/home/user-data/ldap/miab_ldap.conf on your MiaB-LDAP box,
|
||||
then paste the password for "$LDAP_NEXTCLOUD_DN" as a script
|
||||
argument. It will be the value of the LDAP_NEXTCLOUD_PASSWORD
|
||||
key.
|
||||
SSMTP_ALERTS_EMAIL / SSMTP_AUTH_USER / SSMTP_AUTH_PASS
|
||||
OPTIONAL. Supplying these arguments will setup ssmtp on your
|
||||
system and configure it to use MiaB-LDAP as its mail relay.
|
||||
Email sent with sendmail or ssmtp will be relayed to
|
||||
MiaB-LDAP. SSMTP_ALERTS_EMAIL is the email address that will
|
||||
receive messages for all userids less than
|
||||
1000. SSMTP_AUTH_USER / SSMTP_AUTH_PASS is the email address
|
||||
that will be used to authenticate with MiaB-LDAP (the sender
|
||||
or envelope FROM address). You probably want a new/dedicated
|
||||
email address for this - create a new account in the MiaB-LDAP
|
||||
admin interface. More information on ssmtp is available at
|
||||
https://help.ubuntu.com/community/EmailAlerts.
|
||||
|
||||
The script must be run as root.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "$1" == "-v" ]; then
|
||||
VERBOSE=1
|
||||
shift
|
||||
fi
|
||||
|
||||
# Directory where Nextcloud is installed (must contain occ)
|
||||
NCDIR="$1"
|
||||
|
||||
# Nextcloud admin credentials for making user-ldap API calls via curl
|
||||
NC_ADMIN_USER="$2"
|
||||
NC_ADMIN_PASSWORD="$3"
|
||||
|
||||
# Hostname of the remote MiaB-LDAP
|
||||
MAILINABOX_HOSTNAME="$4"
|
||||
|
||||
# LDAP service account Nextcloud uses to perform ldap searches.
|
||||
# Values are found in mailinabox:/home/user-data/ldap/miab_ldap.conf
|
||||
LDAP_NEXTCLOUD_DN="cn=nextcloud,ou=Services,dc=mailinabox"
|
||||
LDAP_NEXTCLOUD_PASSWORD="$5"
|
||||
|
||||
# ssmtp: the person who gets all emails for userids < 1000
|
||||
SSMTP_ALERTS_EMAIL="$6"
|
||||
SSMTP_AUTH_USER="$7"
|
||||
SSMTP_AUTH_PASS="$8"
|
||||
|
||||
#
|
||||
# validate arguments
|
||||
#
|
||||
if [ -z "$NCDIR" -o "$1" == "-h" -o "$1" == "--help" ]
|
||||
then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -z "$NCDIR" -o ! -d "$NCDIR" ]
|
||||
then
|
||||
echo "Invalid directory: $NCDIR" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -e "$NCDIR/occ" ]; then
|
||||
echo "OCC not found at: $NCDIR/occ !" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$NC_ADMIN_USER" -o \
|
||||
-z "$MAILINABOX_HOSTNAME" -o \
|
||||
-z "$LDAP_NEXTCLOUD_PASSWORD" ]
|
||||
then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ ! -z "$SSMTP_ALERTS_EMAIL" ]; then
|
||||
if [ -z "$(awk -F@ '{print $2}' <<< "$SSMTP_ALERTS_EMAIL")" ]; then
|
||||
echo "Invalid email address: $SSMTP_ALERTS_EMAIL" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$(awk -F@ '{print $2}' <<< "$SSMTP_AUTH_USER")" ]; then
|
||||
echo "Invalid email address: $SSMTP_AUTH_USER" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -s /etc/mailinabox.conf ]; then
|
||||
echo "Run on your remote Nextcloud, not on Mail-in-a-Box !!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$EUID" != "0" ]; then
|
||||
echo "The script must be run as root (sudo)" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# other constants
|
||||
#
|
||||
|
||||
LDAP_URL="ldaps://$MAILINABOX_HOSTNAME"
|
||||
LDAP_SERVER="$MAILINABOX_HOSTNAME"
|
||||
LDAP_SERVER_PORT="636"
|
||||
LDAP_SERVER_STARTTLS="no"
|
||||
LDAP_BASE="dc=mailinabox"
|
||||
LDAP_USERS_BASE="ou=Users,dc=mailinabox"
|
||||
PRIMARY_HOSTNAME="$(hostname --fqdn)"
|
||||
|
||||
#
|
||||
# get the url used to access nextcloud as NC_ADMIN_USER
|
||||
#
|
||||
NC_CONFIG_CLI_URL="$(cd "$NCDIR/config"; php -n -r 'include "config.php"; print $CONFIG["overwrite.cli.url"];')"
|
||||
case "$NC_CONFIG_CLI_URL" in
|
||||
http:* | https:* )
|
||||
urlproto=$(awk -F/ '{print $1}' <<< "$NC_CONFIG_CLI_URL")
|
||||
urlhost=$(awk -F/ '{print $3}' <<< "$NC_CONFIG_CLI_URL")
|
||||
urlprefix=$(awk -F/ "{ print substr(\$0,length(\"$urlproto\")+length(\"\
|
||||
$urlhost\")+4) }" <<<"$NC_CONFIG_CLI_URL")
|
||||
NC_AUTH_URL="$urlproto//${NC_ADMIN_USER}:${NC_ADMIN_PASSWORD}@$urlhost/\
|
||||
$urlprefix"
|
||||
;;
|
||||
* )
|
||||
NC_AUTH_URL="https://${NC_ADMIN_USER}:${NC_ADMIN_PASSWORD}@$PRIMARY_HOS\
|
||||
TNAME${NC_CONFIG_CLI_URL:-/}"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
say() {
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
say_verbose() {
|
||||
if [ $VERBOSE -gt 0 ]; then
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "$@" 1>&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
|
||||
|
||||
#
|
||||
# configure Nextcloud's user-ldap for MiaB-LDAP
|
||||
#
|
||||
# See: https://docs.nextcloud.com/server/17/admin_manual/configuration_user/user_auth_ldap_api.html
|
||||
#
|
||||
config_user_ldap() {
|
||||
local id="${1:-s01}"
|
||||
local first_call="${2:-yes}"
|
||||
local starttls=0
|
||||
[ "$LDAP_SERVER_STARTTLS" == "yes" ] && starttls=1
|
||||
|
||||
local c=(
|
||||
"--data-urlencode configData[ldapHost]=$LDAP_URL"
|
||||
"--data-urlencode configData[ldapPort]=$LDAP_SERVER_PORT"
|
||||
"--data-urlencode configData[ldapBase]=$LDAP_USERS_BASE"
|
||||
"--data-urlencode configData[ldapTLS]=$starttls"
|
||||
|
||||
"--data-urlencode configData[ldapAgentName]=$LDAP_NEXTCLOUD_DN"
|
||||
"--data-urlencode configData[ldapAgentPassword]=$LDAP_NEXTCLOUD_PASSWORD"
|
||||
|
||||
"--data-urlencode configData[ldapUserDisplayName]=cn"
|
||||
"--data-urlencode configData[ldapUserDisplayName2]="
|
||||
"--data-urlencode configData[ldapUserFilter]=(&(objectClass=inetOrgPerson)(objectClass=mailUser))"
|
||||
"--data-urlencode configData[ldapUserFilterMode]=1"
|
||||
"--data-urlencode configData[ldapLoginFilter]=(&(objectClass=inetOrgPerson)(objectClass=mailUser)(|(mail=%uid)(uid=%uid)))"
|
||||
"--data-urlencode configData[ldapEmailAttribute]=mail"
|
||||
|
||||
"--data-urlencode configData[ldapGroupFilter]=(objectClass=mailGroup)"
|
||||
"--data-urlencode configData[ldapGroupMemberAssocAttr]=member"
|
||||
"--data-urlencode configData[ldapGroupDisplayName]=mail"
|
||||
"--data-urlencode configData[ldapNestedGroups]=1"
|
||||
"--data-urlencode configData[turnOnPasswordChange]=1"
|
||||
|
||||
"--data-urlencode configData[ldapExpertUsernameAttr]=maildrop"
|
||||
"--data-urlencode configData[ldapExpertUUIDUserAttr]=uid"
|
||||
"--data-urlencode configData[ldapExpertUUIDGroupAttr]=entryUUID"
|
||||
|
||||
"--data-urlencode configData[ldapConfigurationActive]=1"
|
||||
)
|
||||
|
||||
# apply the settings - note: we can't use localhost because nginx
|
||||
# will route to the wrong virtual host
|
||||
local xml
|
||||
say_verbose "curl \"${NC_AUTH_URL%/}/ocs/v2.php/apps/user_ldap/api/v1/config/$id\""
|
||||
xml="$(curl -s -S --insecure -X PUT "${NC_AUTH_URL%/}/ocs/v2.php/apps/user_ldap/api/v1/config/$id" -H "OCS-APIREQUEST: true" ${c[@]})"
|
||||
[ $? -ne 0 ] &&
|
||||
die "Unable to issue a REST call as $NC_ADMIN_USER to nextcloud. url=$NC_AUTH_URL/ocs/v2.php/apps/user_ldap/api/v1/config/$id"
|
||||
|
||||
# did it work?
|
||||
if [ -z "$xml" ]; then
|
||||
die "Invalid response from Nextcloud using url '$NC_AUTH_URL'. reponse was '$xml'. Cannot continue."
|
||||
fi
|
||||
|
||||
local statuscode
|
||||
statuscode=$(python3 -c "import xml.etree.ElementTree as ET; print(ET.fromstring(r'''$xml''').findall('meta')[0].findall('statuscode')[0].text)")
|
||||
|
||||
if [ "$statuscode" == "404" -a "$first_call" == "yes" ]; then
|
||||
# got a 404 so maybe this is the first time -- we have to create
|
||||
# an initial blank ldap configuration and try again
|
||||
xml="$(curl -s -S --insecure -X POST "${NC_AUTH_URL%/}/ocs/v2.php/apps/user_ldap/api/v1/config" -H "OCS-APIREQUEST: true")"
|
||||
[ $? -ne 0 ] &&
|
||||
die "Unable to issue a REST call as $NC_ADMIN_USER to nextcloud: $xml"
|
||||
statuscode=$(python3 -c "import xml.etree.ElementTree as ET; print(ET.fromstring(r'''$xml''').findall('meta')[0].findall('statuscode')[0].text)")
|
||||
[ $? -ne 0 -o "$statuscode" != "200" ] &&
|
||||
die "Error creating initial ldap configuration: $xml"
|
||||
|
||||
id=$(python3 -c "import xml.etree.ElementTree as ET; print(ET.fromstring(r'''$xml''').findall('data')[0].findall('configID')[0].text)" 2>/dev/null)
|
||||
[ $? -ne 0 ] &&
|
||||
die "Error creating initial ldap configuration: $xml"
|
||||
|
||||
config_user_ldap "$id" no
|
||||
|
||||
elif [ "$statuscode" == "997" -a "$first_call" == "yes" ]; then
|
||||
# could not log in
|
||||
die "Could not authenticate as $NC_ADMIN_USER to perform user-ldap API call. statuscode=$statuscode: $xml"
|
||||
|
||||
elif [ "$statuscode" != "200" ]; then
|
||||
die "Unable to apply ldap configuration to nextcloud: id=$id first_call=$first_call statuscode=$statuscode: $xml"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
enable_user_ldap() {
|
||||
# install prerequisite package php-ldap
|
||||
# if using Docker Hub's php image, don't install at all
|
||||
if [ ! -e /etc/apt/preferences.d/no-debian-php ]; then
|
||||
say_verbose "Installing system package php-ldap"
|
||||
apt-get install -y -qq php-ldap || die "Could not install php-ldap package"
|
||||
#restart_service php7.2-fpm
|
||||
fi
|
||||
|
||||
# enable user_ldap
|
||||
if [ ! -x /usr/bin/sudo ]; then
|
||||
say "WARNING: sudo is not installed: Unable to run occ to check and/or enable Nextcloud app \"user-ldap\"."
|
||||
else
|
||||
say_verbose "Enable user-ldap"
|
||||
sudo -E -u www-data php $NCDIR/occ app:enable user_ldap -q
|
||||
[ $? -ne 0 ] && die "Unable to enable user_ldap nextcloud app"
|
||||
fi
|
||||
}
|
||||
|
||||
install_app() {
|
||||
local app="$1"
|
||||
if [ ! -x /usr/bin/sudo ]; then
|
||||
say "WARNING: sudo is not installed: Unable to run occ to check and/or install Nextcloud app \"$app\"."
|
||||
|
||||
elif [ -z "$(sudo -E -u www-data php $NCDIR/occ app:list | grep $app)" ]; then
|
||||
say_verbose "Install app '$app'"
|
||||
sudo -E -u www-data php $NCDIR/occ app:install $app
|
||||
[ $? -ne 0 ] && die "Unable to install Nextcloud app '$app'"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
setup_ssmtp() {
|
||||
# sendmail-like mailer with a mailhub to remote mail-in-a-box
|
||||
# see: https://help.ubuntu.com/community/EmailAlerts
|
||||
|
||||
if [ "$(. /etc/os-release; echo $NAME)" != "Ubuntu" ]; then
|
||||
die "Sorry, ssmtp is only supported on Ubuntu"
|
||||
fi
|
||||
|
||||
say_verbose "Installing system package ssmtp"
|
||||
apt-get install -y -qq ssmtp
|
||||
|
||||
if [ ! -e /etc/ssmtp/ssmtp.conf.orig ]; then
|
||||
cp /etc/ssmtp/ssmtp.conf /etc/ssmtp/ssmtp.conf.orig
|
||||
fi
|
||||
|
||||
cat <<EOF >/etc/ssmtp/ssmtp.conf
|
||||
# Generated by MiaB-LDAP integration script on $(date)
|
||||
|
||||
# The person who gets all mail for userids < 1000
|
||||
root=${SSMTP_ALERTS_EMAIL}
|
||||
|
||||
# The place where mail goes
|
||||
mailhub=${MAILINABOX_HOSTNAME}:587
|
||||
AuthUser=${SSMTP_AUTH_USER}
|
||||
AuthPass=${SSMTP_AUTH_PASS}
|
||||
UseTLS=YES
|
||||
UseSTARTTLS=YES
|
||||
|
||||
# The full hostname
|
||||
hostname=${PRIMARY_HOSTNAME}
|
||||
|
||||
# Are users allowed to set their own From address?
|
||||
FromLineOverride=YES
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
|
||||
remote_mailinabox_handler() {
|
||||
say_verbose "Installing system package ldap-utils"
|
||||
apt-get install -y -qq ldap-utils python3 || die "Could not install required packages"
|
||||
|
||||
local count=0
|
||||
local ldap_debug=""
|
||||
|
||||
while /bin/true; do
|
||||
# ensure we can search
|
||||
local output
|
||||
say ""
|
||||
say "Testing MiaB-LDAP connection..."
|
||||
output="$(ldapsearch $ldap_debug -v -H $LDAP_URL -x -D "$LDAP_NEXTCLOUD_DN" -w "$LDAP_NEXTCLOUD_PASSWORD" -b "$LDAP_BASE" -s base 2>&1)"
|
||||
local code=$?
|
||||
if [ $code -ne 0 ]; then
|
||||
say "Unable to contact $LDAP_URL"
|
||||
say " base=$LDAP_BASE"
|
||||
say " user=$LDAP_NEXTCLOUD_DN"
|
||||
say " error code=$code"
|
||||
say " msg= $output"
|
||||
say ""
|
||||
say "You may need to permit access to the ldap server running on $LDAP_SERVER"
|
||||
say "On $LDAP_SERVER execute:"
|
||||
local ip
|
||||
for ip in $(hostname -I); do
|
||||
say " \$ ufw allow proto tcp from $ip to any port ldaps"
|
||||
done
|
||||
say ""
|
||||
let count+=1
|
||||
if [ $count -gt 5 ]; then
|
||||
die "Giving up"
|
||||
fi
|
||||
read -p "Press [enter] when ready, or \"no\" to quit: " ans
|
||||
[ "$ans" == "no" ] && die "Quit"
|
||||
ldap_debug="-d 9"
|
||||
|
||||
else
|
||||
say "Test successful - able to bind and search as $LDAP_NEXTCLOUD_DN"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
enable_user_ldap
|
||||
config_user_ldap
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
echo "Integrating Nextcloud with Mail-in-a-box LDAP"
|
||||
remote_mailinabox_handler
|
||||
|
||||
# contacts and calendar are required for Roundcube and Z-Push
|
||||
install_app "calendar"
|
||||
install_app "contacts"
|
||||
|
||||
if [ ! -z "${SSMTP_ALERTS_EMAIL}" ]; then
|
||||
setup_ssmtp
|
||||
fi
|
||||
|
||||
say ""
|
||||
say "Done!"
|
||||
161
setup/mods.available/remote-nextcloud.sh
Executable file
161
setup/mods.available/remote-nextcloud.sh
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/bin/bash
|
||||
|
||||
source setup/functions.sh # load our functions
|
||||
source /etc/mailinabox.conf # load global vars
|
||||
|
||||
# maintain a separate conf file because setup rewrites mailinabox.conf
|
||||
touch /etc/mailinabox_mods.conf
|
||||
. /etc/mailinabox_mods.conf
|
||||
|
||||
# where webmail.sh installs roundcube
|
||||
RCM_DIR=/usr/local/lib/roundcubemail
|
||||
RCM_PLUGIN_DIR=${RCM_DIR}/plugins
|
||||
|
||||
# where zpush.sh installs z-push
|
||||
ZPUSH_DIR=/usr/local/lib/z-push
|
||||
|
||||
|
||||
configure_zpush() {
|
||||
# have zpush use the remote nextcloud for carddav/caldav
|
||||
# instead of the nextcloud that comes with mail-in-a-box
|
||||
|
||||
cp setup/mods.available/conf/zpush/backend_carddav.php $ZPUSH_DIR/backend/carddav/config.php
|
||||
cp setup/mods.available/conf/zpush/backend_caldav.php $ZPUSH_DIR/backend/caldav/config.php
|
||||
local var val
|
||||
for var in NC_PROTO NC_HOST NC_PORT NC_PREFIX; do
|
||||
eval "val=\$$var"
|
||||
sed -i "s^$var^${val%/}^g" $ZPUSH_DIR/backend/carddav/config.php
|
||||
sed -i "s^$var^${val%/}^g" $ZPUSH_DIR/backend/caldav/config.php
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
configure_roundcube() {
|
||||
# replace the plugin configuration from the default Mail-In-A-Box
|
||||
local name="${1:-$NC_HOST}"
|
||||
local baseurl="$NC_PROTO://$NC_HOST:$NC_PORT$NC_PREFIX"
|
||||
|
||||
# Configure CardDav plugin
|
||||
#
|
||||
# 1. make MiaB ownCloud contacts read-only so users can still
|
||||
# access them, but not change them, and no sync occurs
|
||||
#
|
||||
# a. set 'active' to 'false'
|
||||
# regular expression before "bashing" it:
|
||||
# (['"]active['"][ \t]*=>[ \t]*)true
|
||||
#
|
||||
sed -i 's/\(['"'"'"]active['"'"'"][ \t]*=>[ \t]*\)true/\1false/' ${RCM_PLUGIN_DIR}/carddav/config.inc.php
|
||||
|
||||
# b. set 'readonly' to 'true'
|
||||
# regular expressions is like above
|
||||
sed -i 's/\(['"'"'"]readonly['"'"'"][ \t]*=>[ \t]*\)false/\1true/' ${RCM_PLUGIN_DIR}/carddav/config.inc.php
|
||||
|
||||
#
|
||||
# 2. add the remote Nextcloud
|
||||
#
|
||||
cat >> ${RCM_PLUGIN_DIR}/carddav/config.inc.php <<EOF
|
||||
<?php
|
||||
/* Do not edit. Written by Mail-in-a-Box-LDAP. Regenerated on updates. */
|
||||
//\$prefs['_GLOBAL']['hide_preferences'] = true;
|
||||
//\$prefs['_GLOBAL']['suppress_version_warning'] = true;
|
||||
\$prefs['cloud'] = array(
|
||||
'name' => '$name',
|
||||
'username' => '%u', // login username
|
||||
'password' => '%p', // login password
|
||||
'url' => '${baseurl%/}/remote.php/carddav/addressbooks/%u/contacts',
|
||||
'active' => true,
|
||||
'readonly' => false,
|
||||
'refresh_time' => '02:00:00',
|
||||
'fixed' => array('username','password'),
|
||||
'preemptive_auth' => '1',
|
||||
'hide' => false,
|
||||
);
|
||||
?>
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
|
||||
remote_nextcloud_handler() {
|
||||
echo ""
|
||||
echo "============================"
|
||||
echo "Configure a remote Nextcloud"
|
||||
echo "============================"
|
||||
echo 'Enter the url or hostname and web prefix of your remote Nextcloud'
|
||||
echo 'For example:'
|
||||
echo ' "cloud.mydomain.com/" - Nextcloud server with no prefix'
|
||||
echo ' "cloud.mydomain.com" - same as above'
|
||||
echo ' "www.mydomain.com/cloud" - a Nextcloud server having a prefix /cloud'
|
||||
echo ''
|
||||
|
||||
local ans
|
||||
local current_url=""
|
||||
|
||||
if [ -z "${NC_HOST:-}" ]; then
|
||||
if [ -z "${NONINTERACTIVE:-}" ]; then
|
||||
read -p "[your Nextcloud's hostname/prefix] " ans
|
||||
fi
|
||||
[ -z "$ans" ] && return 0
|
||||
else
|
||||
current_url="$NC_PROTO://$NC_HOST:$NC_PORT$NC_PREFIX"
|
||||
if [ -z "${NONINTERACTIVE:-}" ]; then
|
||||
read -p "[$current_url] " ans
|
||||
if [ -z "$ans" ]; then
|
||||
ans="$current_url"
|
||||
|
||||
elif [ "$ans" == "none" ]; then
|
||||
ans=""
|
||||
fi
|
||||
else
|
||||
ans="$current_url"
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$ans" in
|
||||
https://* )
|
||||
NC_PROTO="https"
|
||||
NC_PORT="443"
|
||||
ans="$(awk -F: '{print substr($0,9)}' <<< "$ans")"
|
||||
;;
|
||||
http://* )
|
||||
NC_PROTO="http"
|
||||
NC_PORT="80"
|
||||
ans="$(awk -F: '{print substr($0,8)}' <<< "$ans")"
|
||||
;;
|
||||
* )
|
||||
NC_PROTO="https"
|
||||
NC_PORT="443"
|
||||
;;
|
||||
esac
|
||||
|
||||
NC_PREFIX="/$(awk -F/ '{print substr($0,length($1)+2)}' <<< "$ans")"
|
||||
NC_HOST="$(awk -F/ '{print $1}' <<< "$ans")"
|
||||
|
||||
if grep ":" <<< "$NC_HOST" >/dev/null; then
|
||||
NC_PORT="$(awk -F: '{print $2}' <<< "$NC_HOST")"
|
||||
NC_HOST="$(awk -F: '{print $1}' <<< "$NC_HOST")"
|
||||
fi
|
||||
|
||||
local new_url="$NC_PROTO://$NC_HOST:$NC_PORT$NC_PREFIX"
|
||||
|
||||
if [ ! -z "$NC_HOST" ]; then
|
||||
echo "Using Nextcloud ${new_url}"
|
||||
|
||||
# configure roundcube contacts
|
||||
configure_roundcube "$NC_HOST"
|
||||
|
||||
# configure zpush (which links to contacts & calendar)
|
||||
configure_zpush
|
||||
|
||||
# prevent nginx from serving any miab-installed nextcloud files
|
||||
chmod 000 /usr/local/lib/owncloud
|
||||
fi
|
||||
|
||||
tools/editconf.py /etc/mailinabox_mods.conf \
|
||||
"NC_PROTO=$NC_PROTO" \
|
||||
"NC_HOST=$NC_HOST" \
|
||||
"NC_PORT=$NC_PORT" \
|
||||
"NC_PREFIX=$NC_PREFIX"
|
||||
}
|
||||
|
||||
remote_nextcloud_handler
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Munin: resource monitoring tool
|
||||
#################################################
|
||||
[ "${FEATURE_MUNIN:-true}" == "false" ] && return 0
|
||||
|
||||
source setup/functions.sh # load our functions
|
||||
source /etc/mailinabox.conf # load global vars
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Nextcloud
|
||||
##########################
|
||||
[ "${FEATURE_NEXTCLOUD:-true}" == "false" ] && return 0
|
||||
|
||||
source setup/functions.sh # load our functions
|
||||
source /etc/mailinabox.conf # load global vars
|
||||
@@ -100,6 +101,10 @@ nextcloud_hash=50b98d2c2f18510b9530e558ced9ab51eb4f11b0
|
||||
# version.php since the restore procedure can leave the system in a state where you have a newer Nextcloud
|
||||
# application version than the database.
|
||||
|
||||
# ensure directory is accessible
|
||||
if [ -d "/usr/local/lib/owncloud" ]; then
|
||||
chmod u+rx /usr/local/lib/owncloud
|
||||
fi
|
||||
# If config.php exists, get version number, otherwise CURRENT_NEXTCLOUD_VER is empty.
|
||||
if [ -f "$STORAGE_ROOT/owncloud/config.php" ]; then
|
||||
CURRENT_NEXTCLOUD_VER=$(php -r "include(\"$STORAGE_ROOT/owncloud/config.php\"); echo(\$CONFIG['version']);")
|
||||
|
||||
18
setup/ssl.sh
18
setup/ssl.sh
@@ -96,11 +96,6 @@ if [ ! -s $STORAGE_ROOT/ssl/ssl_private_key.pem ]; then
|
||||
# Set the umask so the key file is never world-readable.
|
||||
(umask 037; hide_output \
|
||||
openssl genrsa -out $STORAGE_ROOT/ssl/ssl_private_key.pem 2048)
|
||||
|
||||
# Give the group 'ssl-cert' read access so slapd can read it
|
||||
groupadd -fr ssl-cert
|
||||
chgrp ssl-cert $STORAGE_ROOT/ssl/ssl_private_key.pem
|
||||
chmod g+r $STORAGE_ROOT/ssl/ssl_private_key.pem
|
||||
|
||||
# Remove the ssl_certificate.pem symbolic link to force a
|
||||
# regeneration of the server certificate. It needs to be
|
||||
@@ -110,6 +105,11 @@ if [ ! -s $STORAGE_ROOT/ssl/ssl_private_key.pem ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Give the group 'ssl-cert' read access so slapd can read it
|
||||
groupadd -fr ssl-cert
|
||||
chgrp ssl-cert $STORAGE_ROOT/ssl/ssl_private_key.pem
|
||||
chmod g+r $STORAGE_ROOT/ssl/ssl_private_key.pem
|
||||
|
||||
#
|
||||
# Generate a root CA certificate
|
||||
#
|
||||
@@ -123,15 +123,21 @@ if [ ! -f $STORAGE_ROOT/ssl/ca_certificate.pem ]; then
|
||||
-passin 'pass:SECRET-PASSWORD' \
|
||||
-out $CERT \
|
||||
-subj '/CN=Temporary-Mail-In-A-Box-CA'
|
||||
fi
|
||||
|
||||
# add the certificate to the system's trusted root ca list
|
||||
if [ ! -e /usr/local/share/ca-certificates/mailinabox.crt ]; then
|
||||
# add the CA certificate to the system's trusted root ca list
|
||||
# this is required for openldap's TLS implementation
|
||||
# do this as a separate step in case a CA certificate is manually
|
||||
# copied onto the machine for QA/test
|
||||
CERT=$STORAGE_ROOT/ssl/ca_certificate.pem
|
||||
hide_output \
|
||||
cp $CERT /usr/local/share/ca-certificates/mailinabox.crt
|
||||
hide_output \
|
||||
update-ca-certificates
|
||||
fi
|
||||
|
||||
|
||||
# Generate a signed SSL certificate because things like nginx, dovecot,
|
||||
# etc. won't even start without some certificate in place, and we need nginx
|
||||
# so we can offer the user a control panel to install a better certificate.
|
||||
|
||||
@@ -147,6 +147,15 @@ echo
|
||||
certbot register --register-unsafely-without-email --agree-tos --config-dir $STORAGE_ROOT/ssl/lets_encrypt
|
||||
fi
|
||||
|
||||
#
|
||||
# Run setup mods
|
||||
#
|
||||
if [ -d "${LOCAL_MODS_DIR:-local}" ]; then
|
||||
for mod in $(ls "${LOCAL_MODS_DIR:-local}" | grep -v '~$'); do
|
||||
${LOCAL_MODS_DIR:-local}/$mod
|
||||
done
|
||||
fi
|
||||
|
||||
# Done.
|
||||
echo
|
||||
echo "-----------------------------------------------"
|
||||
|
||||
@@ -256,7 +256,7 @@ if [ -z "${DISABLE_FIREWALL:-}" ]; then
|
||||
apt_install ufw
|
||||
|
||||
# Allow incoming connections to SSH.
|
||||
ufw_allow ssh;
|
||||
ufw_limit ssh;
|
||||
|
||||
# ssh might be running on an alternate port. Use sshd -T to dump sshd's #NODOC
|
||||
# settings, find the port it is supposedly running on, and open that port #NODOC
|
||||
@@ -266,7 +266,7 @@ if [ -z "${DISABLE_FIREWALL:-}" ]; then
|
||||
if [ "$SSH_PORT" != "22" ]; then
|
||||
|
||||
echo Opening alternate SSH port $SSH_PORT. #NODOC
|
||||
ufw_allow $SSH_PORT #NODOC
|
||||
ufw_limit $SSH_PORT #NODOC
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -29,8 +29,8 @@ apt_install \
|
||||
# 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
|
||||
# whether we have the latest version of everything.
|
||||
VERSION=1.4.4
|
||||
HASH=4e425263f5bec27d39c07bde524f421bda205c07
|
||||
VERSION=1.4.6
|
||||
HASH=44961ef62bb9c9875141ca34704bbc7d6f36373d
|
||||
PERSISTENT_LOGIN_VERSION=6b3fc450cae23ccb2f393d0ef67aa319e877e435
|
||||
HTML5_NOTIFIER_VERSION=4b370e3cd60dabd2f428a26f45b677ad1b7118d5
|
||||
CARDDAV_VERSION=3.0.3
|
||||
|
||||
Reference in New Issue
Block a user