diff --git a/Vagrantfile b/Vagrantfile index ea8464dd..2a21dd08 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -18,6 +18,7 @@ Vagrant.configure("2") do |config| # machine figure out its own public IP and it'll take a # subdomain on our justtesting.email domain so we can get # started quickly. + export NONINTERACTIVE=1 export PUBLIC_IP=auto export PUBLIC_IPV6=auto export PRIMARY_HOSTNAME=auto-easy diff --git a/setup/bootstrap.sh b/setup/bootstrap.sh index 7bc4ccf7..dd8f2566 100755 --- a/setup/bootstrap.sh +++ b/setup/bootstrap.sh @@ -2,14 +2,14 @@ ######################################################### # This script is intended to be run like this: # -# wget https://raw.githubusercontent.com/mail-in-a-box/mailinabox/master/setup/bootstrap.sh -# sudo bash bootstrap.sh -# -# We can't pipe directly to bash because setup/start.sh -# asks for user input on stdin. +# wget https://.../bootstrap.sh | sudo bash # ######################################################### +if [ -z "$TAG" ]; then + TAG=14.08-beta +fi + # Are we running as root? if [[ $EUID -ne 0 ]]; then echo "This script must be run as root. Did you leave out sudo?" @@ -23,14 +23,16 @@ cd if [ ! -d mailinabox ]; then echo Downloading Mail-in-a-Box . . . 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 + git checkout -q $TAG # If it does exist, update it. else - echo Updating Mail-in-a-Box . . . + echo Updating Mail-in-a-Box to $TAG . . . 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`?" exit fi diff --git a/setup/csr_country_codes.tsv b/setup/csr_country_codes.tsv new file mode 100644 index 00000000..3f8f6586 --- /dev/null +++ b/setup/csr_country_codes.tsv @@ -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 diff --git a/setup/firstuser.sh b/setup/firstuser.sh new file mode 100644 index 00000000..c1e2d6cb --- /dev/null +++ b/setup/firstuser.sh @@ -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 \ No newline at end of file diff --git a/setup/functions.sh b/setup/functions.sh index 0140baf7..78e67eda 100644 --- a/setup/functions.sh +++ b/setup/functions.sh @@ -127,3 +127,29 @@ function ufw_allow { function restart_service { 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=$? +} diff --git a/setup/preflight.sh b/setup/preflight.sh new file mode 100644 index 00000000..742d6db9 --- /dev/null +++ b/setup/preflight.sh @@ -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 diff --git a/setup/questions.sh b/setup/questions.sh new file mode 100644 index 00000000..fd4d0f85 --- /dev/null +++ b/setup/questions.sh @@ -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 diff --git a/setup/start.sh b/setup/start.sh index 7d26466a..87136f03 100755 --- a/setup/start.sh +++ b/setup/start.sh @@ -4,47 +4,9 @@ source setup/functions.sh # load our functions -# Check system setup. - -# 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 - -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 +# 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. +. setup/preflight.sh # Recall the last settings used if we're running this a second time. if [ -f /etc/mailinabox.conf ]; then @@ -59,157 +21,10 @@ if [ -f /etc/mailinabox.conf ]; then rm -f /tmp/mailinabox.prev.conf 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. - 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 +# Ask the user for the PRIMARY_HOSTNAME, PUBLIC_IP, PUBLIC_IPV6, and CSR_COUNTRY +# if values have not already been set in environment variables. When running +# non-interactively, be sure to set values for all! +. setup/questions.sh # Automatic configuration, e.g. as used in our Vagrant configuration. if [ "$PUBLIC_IP" = "auto" ]; then @@ -290,44 +105,9 @@ curl -s -d POSTDATA --user $(