mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2024-11-26 02:57:04 +00:00
Merge branch 'usedialog'
This commit is contained in:
commit
844f744a09
1
Vagrantfile
vendored
1
Vagrantfile
vendored
@ -18,6 +18,7 @@ Vagrant.configure("2") do |config|
|
|||||||
# machine figure out its own public IP and it'll take a
|
# machine figure out its own public IP and it'll take a
|
||||||
# subdomain on our justtesting.email domain so we can get
|
# subdomain on our justtesting.email domain so we can get
|
||||||
# started quickly.
|
# started quickly.
|
||||||
|
export NONINTERACTIVE=1
|
||||||
export PUBLIC_IP=auto
|
export PUBLIC_IP=auto
|
||||||
export PUBLIC_IPV6=auto
|
export PUBLIC_IPV6=auto
|
||||||
export PRIMARY_HOSTNAME=auto-easy
|
export PRIMARY_HOSTNAME=auto-easy
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
#########################################################
|
#########################################################
|
||||||
# This script is intended to be run like this:
|
# This script is intended to be run like this:
|
||||||
#
|
#
|
||||||
# wget https://raw.githubusercontent.com/mail-in-a-box/mailinabox/master/setup/bootstrap.sh
|
# wget https://.../bootstrap.sh | sudo bash
|
||||||
# sudo bash bootstrap.sh
|
|
||||||
#
|
|
||||||
# We can't pipe directly to bash because setup/start.sh
|
|
||||||
# asks for user input on stdin.
|
|
||||||
#
|
#
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|
||||||
|
if [ -z "$TAG" ]; then
|
||||||
|
TAG=14.08-beta
|
||||||
|
fi
|
||||||
|
|
||||||
# Are we running as root?
|
# Are we running as root?
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
echo "This script must be run as root. Did you leave out sudo?"
|
echo "This script must be run as root. Did you leave out sudo?"
|
||||||
@ -23,14 +23,16 @@ cd
|
|||||||
if [ ! -d mailinabox ]; then
|
if [ ! -d mailinabox ]; then
|
||||||
echo Downloading Mail-in-a-Box . . .
|
echo Downloading Mail-in-a-Box . . .
|
||||||
apt-get -q -q install -y git
|
apt-get -q -q install -y git
|
||||||
git clone -q --depth 1 -b master https://github.com/mail-in-a-box/mailinabox
|
git clone -q https://github.com/mail-in-a-box/mailinabox
|
||||||
cd mailinabox
|
cd mailinabox
|
||||||
|
git checkout -q $TAG
|
||||||
|
|
||||||
# If it does exist, update it.
|
# If it does exist, update it.
|
||||||
else
|
else
|
||||||
echo Updating Mail-in-a-Box . . .
|
echo Updating Mail-in-a-Box to $TAG . . .
|
||||||
cd mailinabox
|
cd mailinabox
|
||||||
if ! git pull -q --ff-only; then
|
git fetch
|
||||||
|
if ! git checkout -q $TAG; then
|
||||||
echo "Update failed. Did you modify something in `pwd`?"
|
echo "Update failed. Did you modify something in `pwd`?"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
253
setup/csr_country_codes.tsv
Normal file
253
setup/csr_country_codes.tsv
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
# This list is derived from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2.
|
||||||
|
# The columns are ISO_3166-1_alpha-2 code, display name, Wikipedia page name.
|
||||||
|
# The top 20 countries by number of Internet users are grouped first, see
|
||||||
|
# https://en.wikipedia.org/wiki/List_of_countries_by_number_of_Internet_users.
|
||||||
|
BR Brazil
|
||||||
|
CA Canada
|
||||||
|
CN China
|
||||||
|
EG Egypt
|
||||||
|
FR France
|
||||||
|
DE Germany
|
||||||
|
IN India
|
||||||
|
ID Indonesia
|
||||||
|
IT Italy
|
||||||
|
JP Japan
|
||||||
|
MX Mexico
|
||||||
|
NG Nigeria
|
||||||
|
PH Philippines
|
||||||
|
RU Russian Federation Russia
|
||||||
|
ES Spain
|
||||||
|
KR South Korea
|
||||||
|
TR Turkey
|
||||||
|
GB United Kingdom
|
||||||
|
US United States
|
||||||
|
VN Vietnam
|
||||||
|
AD Andorra
|
||||||
|
AE United Arab Emirates
|
||||||
|
AF Afghanistan
|
||||||
|
AG Antigua and Barbuda
|
||||||
|
AI Anguilla
|
||||||
|
AL Albania
|
||||||
|
AM Armenia
|
||||||
|
AO Angola
|
||||||
|
AQ Antarctica
|
||||||
|
AR Argentina
|
||||||
|
AS American Samoa
|
||||||
|
AT Austria
|
||||||
|
AU Australia
|
||||||
|
AW Aruba
|
||||||
|
AX Åland Islands
|
||||||
|
AZ Azerbaijan
|
||||||
|
BA Bosnia and Herzegovina
|
||||||
|
BB Barbados
|
||||||
|
BD Bangladesh
|
||||||
|
BE Belgium
|
||||||
|
BF Burkina Faso
|
||||||
|
BG Bulgaria
|
||||||
|
BH Bahrain
|
||||||
|
BI Burundi
|
||||||
|
BJ Benin
|
||||||
|
BL Saint Barthélemy
|
||||||
|
BM Bermuda
|
||||||
|
BN Brunei
|
||||||
|
BO Bolivia
|
||||||
|
BQ Bonaire, Sint Eustatius and Saba Caribbean Netherlands
|
||||||
|
BS Bahamas The Bahamas
|
||||||
|
BT Bhutan
|
||||||
|
BV Bouvet Island
|
||||||
|
BW Botswana
|
||||||
|
BY Belarus
|
||||||
|
BZ Belize
|
||||||
|
CC Cocos (Keeling) Islands
|
||||||
|
CD Congo, the Democratic Republic of the Democratic Republic of the Congo
|
||||||
|
CF Central African Republic
|
||||||
|
CG Congo Republic of the Congo
|
||||||
|
CH Switzerland
|
||||||
|
CI Côte d'Ivoire
|
||||||
|
CK Cook Islands
|
||||||
|
CL Chile
|
||||||
|
CM Cameroon
|
||||||
|
CO Colombia
|
||||||
|
CR Costa Rica
|
||||||
|
CU Cuba
|
||||||
|
CV Cabo Verde
|
||||||
|
CW Curaçao
|
||||||
|
CX Christmas Island
|
||||||
|
CY Cyprus
|
||||||
|
CZ Czech Republic
|
||||||
|
DJ Djibouti
|
||||||
|
DK Denmark
|
||||||
|
DM Dominica
|
||||||
|
DO Dominican Republic
|
||||||
|
DZ Algeria
|
||||||
|
EC Ecuador
|
||||||
|
EE Estonia
|
||||||
|
EH Western Sahara
|
||||||
|
ER Eritrea
|
||||||
|
ET Ethiopia
|
||||||
|
FI Finland
|
||||||
|
FJ Fiji
|
||||||
|
FK Falkland Islands (Malvinas) Falkland Islands
|
||||||
|
FM Federated States of Micronesia
|
||||||
|
FO Faroe Islands
|
||||||
|
GA Gabon
|
||||||
|
GD Grenada
|
||||||
|
GE Georgia Georgia (country)
|
||||||
|
GF French Guiana
|
||||||
|
GG Guernsey
|
||||||
|
GH Ghana
|
||||||
|
GI Gibraltar
|
||||||
|
GL Greenland
|
||||||
|
GM Gambia The Gambia
|
||||||
|
GN Guinea
|
||||||
|
GP Guadeloupe
|
||||||
|
GQ Equatorial Guinea
|
||||||
|
GR Greece
|
||||||
|
GS South Georgia and the South Sandwich Islands
|
||||||
|
GT Guatemala
|
||||||
|
GU Guam
|
||||||
|
GW Guinea-Bissau
|
||||||
|
GY Guyana
|
||||||
|
HK Hong Kong
|
||||||
|
HM Heard Island and McDonald Islands
|
||||||
|
HN Honduras
|
||||||
|
HR Croatia
|
||||||
|
HT Haiti
|
||||||
|
HU Hungary
|
||||||
|
IE Ireland Republic of Ireland
|
||||||
|
IL Israel
|
||||||
|
IM Isle of Man
|
||||||
|
IO British Indian Ocean Territory
|
||||||
|
IQ Iraq
|
||||||
|
IR Iran
|
||||||
|
IS Iceland
|
||||||
|
JE Jersey
|
||||||
|
JM Jamaica
|
||||||
|
JO Jordan
|
||||||
|
KE Kenya
|
||||||
|
KG Kyrgyzstan
|
||||||
|
KH Cambodia
|
||||||
|
KI Kiribati
|
||||||
|
KM Comoros
|
||||||
|
KN Saint Kitts and Nevis
|
||||||
|
KP North Korea
|
||||||
|
KW Kuwait
|
||||||
|
KY Cayman Islands
|
||||||
|
KZ Kazakhstan
|
||||||
|
LA Laos
|
||||||
|
LB Lebanon
|
||||||
|
LC Saint Lucia
|
||||||
|
LI Liechtenstein
|
||||||
|
LK Sri Lanka
|
||||||
|
LR Liberia
|
||||||
|
LS Lesotho
|
||||||
|
LT Lithuania
|
||||||
|
LU Luxembourg
|
||||||
|
LV Latvia
|
||||||
|
LY Libya
|
||||||
|
MA Morocco
|
||||||
|
MC Monaco
|
||||||
|
MD Moldova
|
||||||
|
ME Montenegro
|
||||||
|
MF Saint Martin (French part) Collectivity of Saint Martin
|
||||||
|
MG Madagascar
|
||||||
|
MH Marshall Islands
|
||||||
|
MK Macedonia Republic of Macedonia
|
||||||
|
ML Mali
|
||||||
|
MM Myanmar
|
||||||
|
MN Mongolia
|
||||||
|
MO Macao Macau
|
||||||
|
MP Northern Mariana Islands
|
||||||
|
MQ Martinique
|
||||||
|
MR Mauritania
|
||||||
|
MS Montserrat
|
||||||
|
MT Malta
|
||||||
|
MU Mauritius
|
||||||
|
MV Maldives
|
||||||
|
MW Malawi
|
||||||
|
MY Malaysia
|
||||||
|
MZ Mozambique
|
||||||
|
NA Namibia
|
||||||
|
NC New Caledonia
|
||||||
|
NE Niger
|
||||||
|
NF Norfolk Island
|
||||||
|
NI Nicaragua
|
||||||
|
NL Netherlands
|
||||||
|
NO Norway
|
||||||
|
NP Nepal
|
||||||
|
NR Nauru
|
||||||
|
NU Niue
|
||||||
|
NZ New Zealand
|
||||||
|
OM Oman
|
||||||
|
PA Panama
|
||||||
|
PE Peru
|
||||||
|
PF French Polynesia
|
||||||
|
PG Papua New Guinea
|
||||||
|
PK Pakistan
|
||||||
|
PL Poland
|
||||||
|
PM Saint Pierre and Miquelon
|
||||||
|
PN Pitcairn Pitcairn Islands
|
||||||
|
PR Puerto Rico
|
||||||
|
PS Palestine State of Palestine
|
||||||
|
PT Portugal
|
||||||
|
PW Palau
|
||||||
|
PY Paraguay
|
||||||
|
QA Qatar
|
||||||
|
RE Réunion
|
||||||
|
RO Romania
|
||||||
|
RS Serbia
|
||||||
|
RW Rwanda
|
||||||
|
SA Saudi Arabia
|
||||||
|
SB Solomon Islands
|
||||||
|
SC Seychelles
|
||||||
|
SD Sudan
|
||||||
|
SE Sweden
|
||||||
|
SG Singapore
|
||||||
|
SH Saint Helena, Ascension and Tristan da Cunha
|
||||||
|
SI Slovenia
|
||||||
|
SJ Svalbard and Jan Mayen
|
||||||
|
SK Slovakia
|
||||||
|
SL Sierra Leone
|
||||||
|
SM San Marino
|
||||||
|
SN Senegal
|
||||||
|
SO Somalia
|
||||||
|
SR Suriname
|
||||||
|
SS South Sudan
|
||||||
|
ST Sao Tome and Principe
|
||||||
|
SV El Salvador
|
||||||
|
SX Sint Maarten (Dutch part) Sint Maarten
|
||||||
|
SY Syria
|
||||||
|
SZ Swaziland
|
||||||
|
TC Turks and Caicos Islands
|
||||||
|
TD Chad
|
||||||
|
TF French Southern Territories French Southern and Antarctic Lands
|
||||||
|
TG Togo
|
||||||
|
TH Thailand
|
||||||
|
TJ Tajikistan
|
||||||
|
TK Tokelau
|
||||||
|
TL Timor-Leste East Timor
|
||||||
|
TM Turkmenistan
|
||||||
|
TN Tunisia
|
||||||
|
TO Tonga
|
||||||
|
TT Trinidad and Tobago
|
||||||
|
TV Tuvalu
|
||||||
|
TW Taiwan
|
||||||
|
TZ Tanzania
|
||||||
|
UA Ukraine
|
||||||
|
UG Uganda
|
||||||
|
UM United States Minor Outlying Islands
|
||||||
|
UY Uruguay
|
||||||
|
UZ Uzbekistan
|
||||||
|
VA Vatican City
|
||||||
|
VC Saint Vincent and the Grenadines
|
||||||
|
VE Venezuela
|
||||||
|
VG Virgin Islands, British British Virgin Islands
|
||||||
|
VI Virgin Islands, U.S. United States Virgin Islands
|
||||||
|
VU Vanuatu
|
||||||
|
WF Wallis and Futuna
|
||||||
|
WS Samoa
|
||||||
|
YE Yemen
|
||||||
|
YT Mayotte
|
||||||
|
ZA South Africa
|
||||||
|
ZM Zambia
|
||||||
|
ZW Zimbabwe
|
Can't render this file because it has a wrong number of fields in line 5.
|
57
setup/firstuser.sh
Normal file
57
setup/firstuser.sh
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# If there aren't any mail users yet, create one.
|
||||||
|
if [ -z "`tools/mail.py user`" ]; then
|
||||||
|
# The outut of "tools/mail.py user" is a list of mail users. If there
|
||||||
|
# aren't any yet, it'll be empty.
|
||||||
|
|
||||||
|
# If we didn't ask for an email address at the start, do so now.
|
||||||
|
if [ -z "$EMAIL_ADDR" ]; then
|
||||||
|
# In an interactive shell, ask the user for an email address.
|
||||||
|
if [ -z "$NONINTERACTIVE" ]; then
|
||||||
|
input_box "Mail Account" \
|
||||||
|
"Let's create your first mail account.
|
||||||
|
\n\nWhat email address do you want?" \
|
||||||
|
me@`get_default_hostname` \
|
||||||
|
EMAIL_ADDR
|
||||||
|
|
||||||
|
if [ -z "$EMAIL_ADDR" ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
while ! management/mailconfig.py validate-email "$EMAIL_ADDR"
|
||||||
|
do
|
||||||
|
input_box "Mail Account" \
|
||||||
|
"That's not a valid email address.
|
||||||
|
\n\nWhat email address do you want?" \
|
||||||
|
$EMAIL_ADDR \
|
||||||
|
EMAIL_ADDR
|
||||||
|
if [ -z "$EMAIL_ADDR" ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# But in a non-interactive shell, just make something up.
|
||||||
|
# This is normally for testing.
|
||||||
|
else
|
||||||
|
# Use me@PRIMARY_HOSTNAME
|
||||||
|
EMAIL_ADDR=me@$PRIMARY_HOSTNAME
|
||||||
|
EMAIL_PW=1234
|
||||||
|
echo
|
||||||
|
echo "Creating a new administrative mail account for $EMAIL_ADDR with password $EMAIL_PW."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo "Okay. I'm about to set up $EMAIL_ADDR for you. This account will also"
|
||||||
|
echo "have access to the box's control panel."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the user's mail account. This will ask for a password if none was given above.
|
||||||
|
tools/mail.py user add $EMAIL_ADDR $EMAIL_PW
|
||||||
|
|
||||||
|
# Make it an admin.
|
||||||
|
hide_output tools/mail.py user make-admin $EMAIL_ADDR
|
||||||
|
|
||||||
|
# Create an alias to which we'll direct all automatically-created administrative aliases.
|
||||||
|
tools/mail.py alias add administrator@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
||||||
|
fi
|
@ -127,3 +127,29 @@ function ufw_allow {
|
|||||||
function restart_service {
|
function restart_service {
|
||||||
hide_output service $1 restart
|
hide_output service $1 restart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## Dialog Functions ##
|
||||||
|
function message_box {
|
||||||
|
dialog --title "$1" --msgbox "$2" 0 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function input_box {
|
||||||
|
# input_box "title" "prompt" "defaultvalue" VARIABLE
|
||||||
|
# The user's input will be stored in the variable VARIABLE.
|
||||||
|
# The exit code from dialog will be stored in VARIABLE_EXITCODE.
|
||||||
|
declare -n result=$4
|
||||||
|
declare -n result_code=$4_EXITCODE
|
||||||
|
result=$(dialog --stdout --title "$1" --inputbox "$2" 0 0 "$3")
|
||||||
|
result_code=$?
|
||||||
|
}
|
||||||
|
|
||||||
|
function input_menu {
|
||||||
|
# input_menu "title" "prompt" "tag item tag item" VARIABLE
|
||||||
|
# The user's input will be stored in the variable VARIABLE.
|
||||||
|
# The exit code from dialog will be stored in VARIABLE_EXITCODE.
|
||||||
|
declare -n result=$4
|
||||||
|
declare -n result_code=$4_EXITCODE
|
||||||
|
local IFS=^$'\n'
|
||||||
|
result=$(dialog --stdout --title "$1" --menu "$2" 0 0 0 $3)
|
||||||
|
result_code=$?
|
||||||
|
}
|
||||||
|
29
setup/preflight.sh
Normal file
29
setup/preflight.sh
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Are we running as root?
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "This script must be run as root. Please re-run like this:"
|
||||||
|
echo
|
||||||
|
echo "sudo setup/start.sh"
|
||||||
|
echo
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check that we are running on Ubuntu 14.04 LTS (or 14.04.xx).
|
||||||
|
if [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/14\.04\.[0-9]/14.04/' `" != "Ubuntu 14.04 LTS" ]; then
|
||||||
|
echo "Mail-in-a-Box only supports being installed on Ubuntu 14.04, sorry. You are running:"
|
||||||
|
echo
|
||||||
|
lsb_release -d | sed 's/.*:\s*//'
|
||||||
|
echo
|
||||||
|
echo "We can't write scripts that run on every possible setup, sorry."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check that we have enough memory. Skip the check if we appear to be
|
||||||
|
# running inside of Vagrant, because that's really just for testing.
|
||||||
|
TOTAL_PHYSICAL_MEM=$(free -m | grep ^Mem: | sed "s/^Mem: *\([0-9]*\).*/\1/")
|
||||||
|
if [ $TOTAL_PHYSICAL_MEM -lt 768 ]; then
|
||||||
|
if [ ! -d /vagrant ]; then
|
||||||
|
echo "Your Mail-in-a-Box needs more than $TOTAL_PHYSICAL_MEM MB RAM."
|
||||||
|
echo "Please provision a machine with at least 768 MB, 1 GB recommended."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
188
setup/questions.sh
Normal file
188
setup/questions.sh
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
if [ -z "$NONINTERACTIVE" ]; then
|
||||||
|
# Install 'dialog' so we can ask the user questions. The original motivation for
|
||||||
|
# this was being able to ask the user for input even if stdin has been redirected,
|
||||||
|
# e.g. if we piped a bootstrapping install script to bash to get started. In that
|
||||||
|
# case, the nifty '[ -t 0 ]' test won't work. But with Vagrant we must suppress so we
|
||||||
|
# use a shell flag instead.
|
||||||
|
apt_install dialog
|
||||||
|
message_box "Mail-in-a-Box Installation" \
|
||||||
|
"Hello and thanks for deploying a Mail-in-a-Box!
|
||||||
|
\n\nI'm going to ask you a few questions.
|
||||||
|
\n\nTo change your answers later, just re-run this script."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The box needs a name.
|
||||||
|
if [ -z "$PRIMARY_HOSTNAME" ]; then
|
||||||
|
if [ -z "$DEFAULT_PRIMARY_HOSTNAME" ]; then
|
||||||
|
# We recommend to use box.example.com as this hosts name. The
|
||||||
|
# domain the user possibly wants to use is example.com then.
|
||||||
|
# We strip the string "box." from the hostname to get the mail
|
||||||
|
# domain. If the hostname differs, nothing happens here.
|
||||||
|
DEFAULT_DOMAIN_GUESS=$(echo $(get_default_hostname) | sed -e 's/^box\.//')
|
||||||
|
|
||||||
|
# This is the first run. Ask the user for his email address so we can
|
||||||
|
# provide the best default for the box's hostname.
|
||||||
|
input_box "Your Email Address" \
|
||||||
|
"What email address are you setting this box up to manage?
|
||||||
|
\n\nThe part after the @-sign must be a domain name or subdomain
|
||||||
|
that you control. You can add other email addresses to this
|
||||||
|
box later (including email addresses on other domain names
|
||||||
|
or subdomains you control).
|
||||||
|
\n\nWe've guessed an email address. Backspace it and type in what
|
||||||
|
you really want.
|
||||||
|
\n\nEmail Address:" \
|
||||||
|
"me@$DEFAULT_DOMAIN_GUESS" \
|
||||||
|
EMAIL_ADDR
|
||||||
|
|
||||||
|
if [ -z "$EMAIL_ADDR" ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
while ! management/mailconfig.py validate-email "$EMAIL_ADDR"
|
||||||
|
do
|
||||||
|
input_box "Your Email Address" \
|
||||||
|
"That's not a valid email address.\n\nWhat email address are you setting this box up to manage?" \
|
||||||
|
$EMAIL_ADDR \
|
||||||
|
EMAIL_ADDR
|
||||||
|
if [ -z "$EMAIL_ADDR" ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Take the part after the @-sign as the user's domain name, and add
|
||||||
|
# 'box.' to the beginning to create a default hostname for this machine.
|
||||||
|
DEFAULT_PRIMARY_HOSTNAME=box.$(echo $EMAIL_ADDR | sed 's/.*@//')
|
||||||
|
fi
|
||||||
|
|
||||||
|
input_box "Hostname" \
|
||||||
|
"This box needs a name, called a 'hostname'. The name will form a part of the box's web address.
|
||||||
|
\n\nWe recommend that the name be a subdomain of the domain in your email
|
||||||
|
address, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME.
|
||||||
|
\n\nYou can change it, but we recommend you don't.
|
||||||
|
\n\nHostname:" \
|
||||||
|
$DEFAULT_PRIMARY_HOSTNAME \
|
||||||
|
PRIMARY_HOSTNAME
|
||||||
|
|
||||||
|
if [ -z "$PRIMARY_HOSTNAME" ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the machine is behind a NAT, inside a VM, etc., it may not know
|
||||||
|
# its IP address on the public network / the Internet. Ask the Internet
|
||||||
|
# and possibly confirm with user.
|
||||||
|
if [ -z "$PUBLIC_IP" ]; then
|
||||||
|
# Ask the Internet.
|
||||||
|
GUESSED_IP=$(get_publicip_from_web_service 4)
|
||||||
|
|
||||||
|
# On the first run, if we got an answer from the Internet then don't
|
||||||
|
# ask the user.
|
||||||
|
if [[ -z "$DEFAULT_PUBLIC_IP" && ! -z "$GUESSED_IP" ]]; then
|
||||||
|
PUBLIC_IP=$GUESSED_IP
|
||||||
|
|
||||||
|
# Otherwise on the first run at least provide a default.
|
||||||
|
elif [[ -z "$DEFAULT_PUBLIC_IP" ]]; then
|
||||||
|
DEFAULT_PUBLIC_IP=$(get_default_privateip 4)
|
||||||
|
|
||||||
|
# On later runs, if the previous value matches the guessed value then
|
||||||
|
# don't ask the user either.
|
||||||
|
elif [ "$DEFAULT_PUBLIC_IP" == "$GUESSED_IP" ]; then
|
||||||
|
PUBLIC_IP=$GUESSED_IP
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$PUBLIC_IP" ]; then
|
||||||
|
input_box "Public IP Address" \
|
||||||
|
"Enter the public IP address of this machine, as given to you by your ISP.
|
||||||
|
\n\nPublic IP address:" \
|
||||||
|
$DEFAULT_PUBLIC_IP \
|
||||||
|
PUBLIC_IP
|
||||||
|
|
||||||
|
if [ -z "$PUBLIC_IP" ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Same for IPv6. But it's optional. Also, if it looks like the system
|
||||||
|
# doesn't have an IPv6, don't ask for one.
|
||||||
|
if [ -z "$PUBLIC_IPV6" ]; then
|
||||||
|
# Ask the Internet.
|
||||||
|
GUESSED_IP=$(get_publicip_from_web_service 6)
|
||||||
|
MATCHED=0
|
||||||
|
if [[ -z "$DEFAULT_PUBLIC_IPV6" && ! -z "$GUESSED_IP" ]]; then
|
||||||
|
PUBLIC_IPV6=$GUESSED_IP
|
||||||
|
elif [[ "$DEFAULT_PUBLIC_IPV6" == "$GUESSED_IP" ]]; then
|
||||||
|
# No IPv6 entered and machine seems to have none, or what
|
||||||
|
# the user entered matches what the Internet tells us.
|
||||||
|
PUBLIC_IPV6=$GUESSED_IP
|
||||||
|
MATCHED=1
|
||||||
|
elif [[ -z "$DEFAULT_PUBLIC_IPV6" ]]; then
|
||||||
|
DEFAULT_PUBLIC_IP=$(get_default_privateip 6)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$PUBLIC_IPV6" && $MATCHED == 0 ]]; then
|
||||||
|
input_box "IPv6 Address (Optional)" \
|
||||||
|
"Enter the public IPv6 address of this machine, as given to you by your ISP.
|
||||||
|
\n\nLeave blank if the machine does not have an IPv6 address.
|
||||||
|
\n\nPublic IPv6 address:"
|
||||||
|
$DEFAULT_PUBLIC_IPV6 \
|
||||||
|
PUBLIC_IPV6
|
||||||
|
|
||||||
|
if [ ! $PUBLIC_IPV6_EXITCODE ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the IP addresses of the local network interface(s) that are connected
|
||||||
|
# to the Internet. We need these when we want to have services bind only to
|
||||||
|
# the public network interfaces (not loopback, not tunnel interfaces).
|
||||||
|
if [ -z "$PRIVATE_IP" ]; then
|
||||||
|
PRIVATE_IP=$(get_default_privateip 4)
|
||||||
|
fi
|
||||||
|
if [ -z "$PRIVATE_IPV6" ]; then
|
||||||
|
PRIVATE_IPV6=$(get_default_privateip 6)
|
||||||
|
fi
|
||||||
|
if [[ -z "$PRIVATE_IP" && -z "$PRIVATE_IPV6" ]]; then
|
||||||
|
echo
|
||||||
|
echo "I could not determine the IP or IPv6 address of the network inteface"
|
||||||
|
echo "for connecting to the Internet. Setup must stop."
|
||||||
|
echo
|
||||||
|
hostname -I
|
||||||
|
route
|
||||||
|
echo
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We need a country code to generate a certificate signing request. However
|
||||||
|
# if a CSR already exists then we won't be generating a new one and there's
|
||||||
|
# no reason to ask for the country code now. $STORAGE_ROOT has not yet been
|
||||||
|
# set so we'll check if $DEFAULT_STORAGE_ROOT and $DEFAULT_CSR_COUNTRY are
|
||||||
|
# set (the values from the current mailinabox.conf) and if the CSR exists
|
||||||
|
# in the expected location.
|
||||||
|
if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $DEFAULT_STORAGE_ROOT/ssl/ssl_cert_sign_req.csr ]; then
|
||||||
|
CSR_COUNTRY=$DEFAULT_CSR_COUNTRY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$CSR_COUNTRY" ]; then
|
||||||
|
# Get a list of country codes. Separate codes from country names with a ^.
|
||||||
|
# The input_menu function modifies shell word expansion to ignore spaces
|
||||||
|
# (since country names can have spaces) and use ^ instead.
|
||||||
|
country_code_list=$(grep -v "^#" setup/csr_country_codes.tsv | sed "s/\(..\)\t\([^\t]*\).*/\1^\2/")
|
||||||
|
|
||||||
|
input_menu "Country Code" \
|
||||||
|
"Choose the country where you live or where your organization is based.
|
||||||
|
\n\n(This is used to create an SSL certificate.)
|
||||||
|
\n\nCountry Code:" \
|
||||||
|
"$country_code_list" \
|
||||||
|
CSR_COUNTRY
|
||||||
|
|
||||||
|
if [ -z "$CSR_COUNTRY" ]; then
|
||||||
|
# user hit ESC/cancel
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
238
setup/start.sh
238
setup/start.sh
@ -4,47 +4,9 @@
|
|||||||
|
|
||||||
source setup/functions.sh # load our functions
|
source setup/functions.sh # load our functions
|
||||||
|
|
||||||
# Check system setup.
|
# Check system setup: Are we running as root on Ubuntu 14.04 on a
|
||||||
|
# machine with enough memory? If not, this shows an error and exits.
|
||||||
# Are we running as root?
|
. setup/preflight.sh
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
echo "This script must be run as root. Please re-run like this:"
|
|
||||||
echo
|
|
||||||
echo "sudo setup/start.sh"
|
|
||||||
echo
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check that we are running on Ubuntu 14.04 LTS (or 14.04.xx).
|
|
||||||
if [ "`lsb_release -d | sed 's/.*:\s*//' | sed 's/14\.04\.[0-9]/14.04/' `" != "Ubuntu 14.04 LTS" ]; then
|
|
||||||
echo "Mail-in-a-Box only supports being installed on Ubuntu 14.04, sorry. You are running:"
|
|
||||||
echo
|
|
||||||
lsb_release -d | sed 's/.*:\s*//'
|
|
||||||
echo
|
|
||||||
echo "We can't write scripts that run on every possible setup, sorry."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check that we have enough memory. Skip the check if we appear to be
|
|
||||||
# running inside of Vagrant, because that's really just for testing.
|
|
||||||
TOTAL_PHYSICAL_MEM=$(free -m | grep ^Mem: | sed "s/^Mem: *\([0-9]*\).*/\1/")
|
|
||||||
if [ $TOTAL_PHYSICAL_MEM -lt 768 ]; then
|
|
||||||
if [ ! -d /vagrant ]; then
|
|
||||||
echo "Your Mail-in-a-Box needs more than $TOTAL_PHYSICAL_MEM MB RAM."
|
|
||||||
echo "Please provision a machine with at least 768 MB, 1 GB recommended."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -t 0 ]; then
|
|
||||||
# In an interactive shell...
|
|
||||||
echo
|
|
||||||
echo "Hello and thanks for deploying a Mail-in-a-Box!"
|
|
||||||
echo "-----------------------------------------------"
|
|
||||||
echo
|
|
||||||
echo "I'm going to ask you a few questions. To change your answers later,"
|
|
||||||
echo "just re-run this script."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Recall the last settings used if we're running this a second time.
|
# Recall the last settings used if we're running this a second time.
|
||||||
if [ -f /etc/mailinabox.conf ]; then
|
if [ -f /etc/mailinabox.conf ]; then
|
||||||
@ -59,157 +21,10 @@ if [ -f /etc/mailinabox.conf ]; then
|
|||||||
rm -f /tmp/mailinabox.prev.conf
|
rm -f /tmp/mailinabox.prev.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The box needs a name.
|
# Ask the user for the PRIMARY_HOSTNAME, PUBLIC_IP, PUBLIC_IPV6, and CSR_COUNTRY
|
||||||
if [ -z "$PRIMARY_HOSTNAME" ]; then
|
# if values have not already been set in environment variables. When running
|
||||||
if [ -z "$DEFAULT_PRIMARY_HOSTNAME" ]; then
|
# non-interactively, be sure to set values for all!
|
||||||
# We recommend to use box.example.com as this hosts name. The
|
. setup/questions.sh
|
||||||
# domain the user possibly wants to use is example.com then.
|
|
||||||
# We strip the string "box." from the hostname to get the mail
|
|
||||||
# domain. If the hostname differs, nothing happens here.
|
|
||||||
DEFAULT_DOMAIN_GUESS=$(echo $(get_default_hostname) | sed -e 's/^box\.//')
|
|
||||||
|
|
||||||
# This is the first run. Ask the user for his email address so we can
|
|
||||||
# provide the best default for the box's hostname.
|
|
||||||
echo
|
|
||||||
echo "What email address are you setting this box up to manage?"
|
|
||||||
echo ""
|
|
||||||
echo "The part after the @-sign must be a domain name or subdomain"
|
|
||||||
echo "that you control. You can add other email addresses to this"
|
|
||||||
echo "box later (including email addresses on other domain names"
|
|
||||||
echo "or subdomains you control)."
|
|
||||||
echo
|
|
||||||
echo "We've guessed an email address. Backspace it and type in what"
|
|
||||||
echo "you really want."
|
|
||||||
echo
|
|
||||||
read -e -i "me@$DEFAULT_DOMAIN_GUESS" -p "Email Address: " EMAIL_ADDR
|
|
||||||
|
|
||||||
while ! management/mailconfig.py validate-email "$EMAIL_ADDR"
|
|
||||||
do
|
|
||||||
echo "That's not a valid email address."
|
|
||||||
echo
|
|
||||||
read -e -i "$EMAIL_ADDR" -p "Email Address: " EMAIL_ADDR
|
|
||||||
done
|
|
||||||
|
|
||||||
# Take the part after the @-sign as the user's domain name, and add
|
|
||||||
# 'box.' to the beginning to create a default hostname for this machine.
|
|
||||||
DEFAULT_PRIMARY_HOSTNAME=box.$(echo $EMAIL_ADDR | sed 's/.*@//')
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "This box needs a name, called a 'hostname'. The name will form a part"
|
|
||||||
echo "of the box's web address."
|
|
||||||
echo
|
|
||||||
echo "We recommend that the name be a subdomain of the domain in your email"
|
|
||||||
echo "address, so we're suggesting $DEFAULT_PRIMARY_HOSTNAME."
|
|
||||||
echo
|
|
||||||
echo "You can change it, but we recommend you don't."
|
|
||||||
echo
|
|
||||||
|
|
||||||
read -e -i "$DEFAULT_PRIMARY_HOSTNAME" -p "Hostname: " PRIMARY_HOSTNAME
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If the machine is behind a NAT, inside a VM, etc., it may not know
|
|
||||||
# its IP address on the public network / the Internet. Ask the Internet
|
|
||||||
# and possibly confirm with user.
|
|
||||||
if [ -z "$PUBLIC_IP" ]; then
|
|
||||||
# Ask the Internet.
|
|
||||||
GUESSED_IP=$(get_publicip_from_web_service 4)
|
|
||||||
|
|
||||||
# On the first run, if we got an answer from the Internet then don't
|
|
||||||
# ask the user.
|
|
||||||
if [[ -z "$DEFAULT_PUBLIC_IP" && ! -z "$GUESSED_IP" ]]; then
|
|
||||||
PUBLIC_IP=$GUESSED_IP
|
|
||||||
|
|
||||||
# Otherwise on the first run at least provide a default.
|
|
||||||
elif [[ -z "$DEFAULT_PUBLIC_IP" ]]; then
|
|
||||||
DEFAULT_PUBLIC_IP=$(get_default_privateip 4)
|
|
||||||
|
|
||||||
# On later runs, if the previous value matches the guessed value then
|
|
||||||
# don't ask the user either.
|
|
||||||
elif [ "$DEFAULT_PUBLIC_IP" == "$GUESSED_IP" ]; then
|
|
||||||
PUBLIC_IP=$GUESSED_IP
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$PUBLIC_IP" ]; then
|
|
||||||
echo
|
|
||||||
echo "Enter the public IP address of this machine, as given to you by your ISP."
|
|
||||||
echo
|
|
||||||
|
|
||||||
read -e -i "$DEFAULT_PUBLIC_IP" -p "Public IP: " PUBLIC_IP
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Same for IPv6. But it's optional. Also, if it looks like the system
|
|
||||||
# doesn't have an IPv6, don't ask for one.
|
|
||||||
if [ -z "$PUBLIC_IPV6" ]; then
|
|
||||||
# Ask the Internet.
|
|
||||||
GUESSED_IP=$(get_publicip_from_web_service 6)
|
|
||||||
MATCHED=0
|
|
||||||
if [[ -z "$DEFAULT_PUBLIC_IPV6" && ! -z "$GUESSED_IP" ]]; then
|
|
||||||
PUBLIC_IPV6=$GUESSED_IP
|
|
||||||
elif [[ "$DEFAULT_PUBLIC_IPV6" == "$GUESSED_IP" ]]; then
|
|
||||||
# No IPv6 entered and machine seems to have none, or what
|
|
||||||
# the user entered matches what the Internet tells us.
|
|
||||||
PUBLIC_IPV6=$GUESSED_IP
|
|
||||||
MATCHED=1
|
|
||||||
elif [[ -z "$DEFAULT_PUBLIC_IPV6" ]]; then
|
|
||||||
DEFAULT_PUBLIC_IP=$(get_default_privateip 6)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$PUBLIC_IPV6" && $MATCHED == 0 ]]; then
|
|
||||||
echo
|
|
||||||
echo "Optional:"
|
|
||||||
echo "Enter the public IPv6 address of this machine, as given to you by your ISP."
|
|
||||||
echo "Leave blank if the machine does not have an IPv6 address."
|
|
||||||
echo
|
|
||||||
|
|
||||||
read -e -i "$DEFAULT_PUBLIC_IPV6" -p "Public IPv6: " PUBLIC_IPV6
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the IP addresses of the local network interface(s) that are connected
|
|
||||||
# to the Internet. We need these when we want to have services bind only to
|
|
||||||
# the public network interfaces (not loopback, not tunnel interfaces).
|
|
||||||
if [ -z "$PRIVATE_IP" ]; then
|
|
||||||
PRIVATE_IP=$(get_default_privateip 4)
|
|
||||||
fi
|
|
||||||
if [ -z "$PRIVATE_IPV6" ]; then
|
|
||||||
PRIVATE_IPV6=$(get_default_privateip 6)
|
|
||||||
fi
|
|
||||||
if [[ -z "$PRIVATE_IP" && -z "$PRIVATE_IPV6" ]]; then
|
|
||||||
echo
|
|
||||||
echo "I could not determine the IP or IPv6 address of the network inteface"
|
|
||||||
echo "for connecting to the Internet. Setup must stop."
|
|
||||||
echo
|
|
||||||
hostname -I
|
|
||||||
route
|
|
||||||
echo
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# We need a country code to generate a certificate signing request. However
|
|
||||||
# if a CSR already exists then we won't be generating a new one and there's
|
|
||||||
# no reason to ask for the country code now. $STORAGE_ROOT has not yet been
|
|
||||||
# set so we'll check if $DEFAULT_STORAGE_ROOT and $DEFAULT_CSR_COUNTRY are
|
|
||||||
# set (the values from the current mailinabox.conf) and if the CSR exists
|
|
||||||
# in the expected location.
|
|
||||||
if [ ! -z "$DEFAULT_STORAGE_ROOT" ] && [ ! -z "$DEFAULT_CSR_COUNTRY" ] && [ -f $DEFAULT_STORAGE_ROOT/ssl/ssl_cert_sign_req.csr ]; then
|
|
||||||
CSR_COUNTRY=$DEFAULT_CSR_COUNTRY
|
|
||||||
fi
|
|
||||||
if [ -z "$CSR_COUNTRY" ]; then
|
|
||||||
echo
|
|
||||||
echo "Enter the two-letter, uppercase country code for where you"
|
|
||||||
echo "live or where your organization is based. (This is used to"
|
|
||||||
echo "create an SSL certificate.)"
|
|
||||||
echo
|
|
||||||
|
|
||||||
#if [ -z "$DEFAULT_CSR_COUNTRY" ]; then
|
|
||||||
# # set a default on first run
|
|
||||||
# DEFAULT_CSR_COUNTRY=...?
|
|
||||||
#fi
|
|
||||||
|
|
||||||
read -e -i "$DEFAULT_CSR_COUNTRY" -p "Country Code: " CSR_COUNTRY
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Automatic configuration, e.g. as used in our Vagrant configuration.
|
# Automatic configuration, e.g. as used in our Vagrant configuration.
|
||||||
if [ "$PUBLIC_IP" = "auto" ]; then
|
if [ "$PUBLIC_IP" = "auto" ]; then
|
||||||
@ -290,44 +105,9 @@ curl -s -d POSTDATA --user $(</var/lib/mailinabox/api.key): http://127.0.0.1:102
|
|||||||
curl -s -d POSTDATA --user $(</var/lib/mailinabox/api.key): http://127.0.0.1:10222/web/update
|
curl -s -d POSTDATA --user $(</var/lib/mailinabox/api.key): http://127.0.0.1:10222/web/update
|
||||||
|
|
||||||
# If there aren't any mail users yet, create one.
|
# If there aren't any mail users yet, create one.
|
||||||
if [ -z "`tools/mail.py user`" ]; then
|
. setup/firstuser.sh
|
||||||
# The outut of "tools/mail.py user" is a list of mail users. If there
|
|
||||||
# aren't any yet, it'll be empty.
|
|
||||||
|
|
||||||
# If we didn't ask for an email address at the start, do so now.
|
|
||||||
if [ -z "$EMAIL_ADDR" ]; then
|
|
||||||
# In an interactive shell, ask the user for an email address.
|
|
||||||
if [ -t 0 ]; then
|
|
||||||
echo
|
|
||||||
echo "Let's create your first mail user."
|
|
||||||
read -e -i "user@$PRIMARY_HOSTNAME" -p "Email Address: " EMAIL_ADDR
|
|
||||||
|
|
||||||
# But in a non-interactive shell, just make something up. This
|
|
||||||
# is normally for testing.
|
|
||||||
else
|
|
||||||
# Use me@PRIMARY_HOSTNAME
|
|
||||||
EMAIL_ADDR=me@$PRIMARY_HOSTNAME
|
|
||||||
EMAIL_PW=1234
|
|
||||||
echo
|
|
||||||
echo "Creating a new administrative mail account for $EMAIL_ADDR with password $EMAIL_PW."
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo
|
|
||||||
echo "Okay. I'm about to set up $EMAIL_ADDR for you. This account will also"
|
|
||||||
echo "have access to the box's control panel."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create the user's mail account. This will ask for a password if none was given above.
|
|
||||||
tools/mail.py user add $EMAIL_ADDR $EMAIL_PW
|
|
||||||
|
|
||||||
# Make it an admin.
|
|
||||||
hide_output tools/mail.py user make-admin $EMAIL_ADDR
|
|
||||||
|
|
||||||
# Create an alias to which we'll direct all automatically-created administrative aliases.
|
|
||||||
tools/mail.py alias add administrator@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
# Done.
|
||||||
echo
|
echo
|
||||||
echo "-----------------------------------------------"
|
echo "-----------------------------------------------"
|
||||||
echo
|
echo
|
||||||
|
Loading…
Reference in New Issue
Block a user