Skip to content

Instantly share code, notes, and snippets.

@kelsotodd
Forked from hisnameisjimmy/le-install.sh
Last active October 25, 2017 12:55
Show Gist options
  • Save kelsotodd/ebf648b835ff0b4f434e9754507c89e5 to your computer and use it in GitHub Desktop.
Save kelsotodd/ebf648b835ff0b4f434e9754507c89e5 to your computer and use it in GitHub Desktop.
Unifi Controller one-shot install script for Ubuntu 16.04 with Lets Encrypt on Digital Ocean
#!/bin/sh
#
# This script stands on the shoulders of giants.
#
# It is written and tested for Ubuntu 16.04 on Digital Ocean using a 1GB droplet.
# Anything less than 1GB of memory may cause issues with anything memory intensive
# like imports/exports.
#
# It does the following:
# 1) Opens the appropriate ports for Unifi, SSH, Web/SSL traffic via ufw
# 2) Makes the Unifi/Certbot software available as a package
# 3) Uses Certbot to request a Lets Encrypt Certificate, and then installs it
# 4) Writes an NGINX proxy config
# 5) Writes out an automatic renewal cron for Lets Encrypt (as the certs expire every 3 months)
#
# I recommend running it from /opt on your server. In my installation I called it 'le-install.sh'
# Run it with the following:
# bash /opt/le-install.sh
#
# Alternatively you can make it executable and run it without specifying bash, but this is a one
# time script, so it seems unnecessary.
#
# Thanks to these resources below:
# https://community.ubnt.com/t5/UniFi-Wireless/Ubuntu-single-script-LetsEncrypt-Nginx-Proxy-UniFi-5-Repo/m-p/1626526/highlight/false#M172872
# http://www.jeff-ferguson.com/2016/11/21/unifi-5-2-9-installation-script-for-digital-ocean/
# https://murfy.nz/2017/01/ubiquiti-unifi-secure-installation/
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
# OR OTHER DEALINGS IN THE SOFTWARE.
#
RED='\033[0;31m'
CYAN='\033[0;36m'
NC='\033[0m'
# Gathering variables to use for the rest of the script
echo -en "${CYAN}Enter your domain name [my.fqdn.com]: ${NC}"
read NAME
echo -en "${CYAN}Enter your email address [somebody@somewhere.com]: ${NC}"
read EMAIL
echo "These parameters are used exclusively by LetsEncrypt to register your SSL certificate and provide notifications:"
echo "Domain: $NAME"
echo "E-Mail: $EMAIL"
# Update local software to avoid any issues with dpkg prompts
echo -e "${CYAN}Upgrading system${NC}"
apt-get update
echo y | apt-get upgrade
# Installing UNIFI software
echo -e "${CYAN}Installing UniFi${NC}"
echo "deb http://www.ubnt.com/downloads/unifi/debian unifi5 ubiquiti" > /etc/apt/sources.list.d/unifi.list
echo y | apt-key adv --keyserver keyserver.ubuntu.com --recv C0A52C50
apt update
echo y | apt-get install unifi
# ufw config
echo "${CYAN}Opening relevant ports via ufw${NC}"
ufw allow 80
ufw allow 443
ufw allow 22
ufw allow 6787
ufw allow 8081
ufw allow 8080
ufw allow 8443
ufw allow 8880
ufw allow 8843
ufw allow 27117
ufw status
ufw enable
# Install relevant packages
echo -e "${CYAN}Updating and installing relevant packages for CertBot${NC}"
echo y | apt-get install software-properties-common
echo y | add-apt-repository ppa:certbot/certbot
apt-get update
echo y | apt-get install nginx certbot
# Lets Encrypt certificate request, run it non-interactively (-n) so we don't have to agree to anything
echo -e "${CYAN}Requesting Certificate for $NAME${NC}"
service nginx stop
certbot -n certonly -d $NAME --standalone --agree-tos --preferred-challenges http-01 --email $EMAIL
service nginx start
echo -e "${CYAN}Adding certificate to UniFi Controller for $NAME${NC}"
service unifi stop
echo aircontrolenterprise | openssl pkcs12 -export -inkey /etc/letsencrypt/live/$NAME/privkey.pem -in /etc/letsencrypt/live/$NAME/cert.pem -name unifi -out /etc/letsencrypt/live/$NAME/keys.p12 -password stdin
echo y | keytool -importkeystore -srckeystore /etc/letsencrypt/live/$NAME/keys.p12 -srcstoretype pkcs12 -destkeystore /usr/lib/unifi/data/keystore -storepass aircontrolenterprise -srcstorepass aircontrolenterprise
service unifi start
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
# NGINX Proxy
echo -e "${CYAN}Writing nginx proxy configuration${NC}"
service nginx stop
printf "server_tokens off;\n\
add_header X-Frame-Options SAMEORIGIN;\n\
add_header X-XSS-Protection \"1; mode=block\";\n\
server {\n\
listen 80;\n\
server_name $NAME;\n\
return 301 https://$NAME\$request_uri;\n\
}\n\
server {\n\
listen 443 ssl default_server http2;\n\
server_name $NAME;\n\
ssl_dhparam /etc/ssl/certs/dhparam.pem;\n\
ssl_certificate /etc/letsencrypt/live/$NAME/fullchain.pem;\n\
ssl_certificate_key /etc/letsencrypt/live/$NAME/privkey.pem;\n\
ssl_session_cache shared:SSL:10m;\n\
ssl_session_timeout 10m;\n\
keepalive_timeout 300;\n\
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n\
ssl_prefer_server_ciphers on;\n\
ssl_stapling on;\n\
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA;
add_header Strict-Transport-Security max-age=31536000;\n\
add_header X-Frame-Options DENY;\n\
error_log /var/log/unifi/nginx.log;\n\
proxy_cache off;\n\
proxy_store off;\n\
location / {\n\
proxy_set_header Referer \"\";\n\
proxy_pass https://localhost:8443;\n\
proxy_set_header Host \$host;\n\
proxy_set_header X-Real-IP \$remote_addr;\n\
proxy_set_header X-Forward-For \$proxy_add_x_forwarded_for;\n\
proxy_http_version 1.1;\n\
proxy_set_header Upgrade \$http_upgrade;\n\
proxy_set_header Connection \"upgrade\";\n\
}\n\
}\n\
" > /etc/nginx/sites-enabled/default
service nginx start
# Automatic LE Certificate renewals - This creates a crontab for you
echo -e "${CYAN}Writing Crontab for LetsEncrypt renewals to /etc/cron.monthly/le-unifi-renew${NC}"
echo -e "#!/bin/sh\n\
service nginx stop\n\
echo y | certbot renew --standalone --preferred-challenges http-01\n\
service nginx start\n\
service unifi stop\n\
echo aircontrolenterprise | openssl pkcs12 -export -inkey /etc/letsencrypt/live/$NAME/privkey.pem -in /etc/letsencrypt/live/$NAME/cert.pem -name unifi -out /etc/letsencrypt/live/$NAME/keys.p12 -password stdin\n\
echo y | keytool -importkeystore -srckeystore /etc/letsencrypt/live/$NAME/keys.p12 -srcstoretype pkcs12 -destkeystore /usr/lib/unifi/data/keystore -storepass aircontrolenterprise -srcstorepass aircontrolenterprise\n\
service unifi start\n\" > /etc/cron.monthly/le-unifi-renew
chmod +x /etc/cron.monthly/le-unifi-renew
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment