apt-get update && apt-get upgrade -y --force-yes
apt-get install -y --force-yes git
cd /usr/src
git clone https://github.com/fusionpbx/fusionpbx-install.sh.git
chmod 755 -R /usr/src/fusionpbx-install.sh
cd /usr/src/fusionpbx-install.sh/debian
./install.sh
After install, use the generated username/password to login to web UI, go to the navigation and do the following:
Advanced -> Upgrade select the checkbox for App defaults then execute.
Go to Status -> SIP Status and start the SIP profiles
Go to Advanced -> Modules and find the module Memcached and click start.
cd /usr/src/
git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
cd /opt/letsencrypt
chmod a+x ./certbot-auto
mkdir /etc/letsencrypt
cd /etc/letsencrypt/
mkdir -p configs
cd configs
nano /etc/letsencrypt/configs/example.com.conf
# the domain we want to get the cert for;
# technically it's possible to have multiple of this lines, but it only worked
# with one domain for me, another one only got one cert, so I would recommend
# separate config files per domain.
domains = my-domain
# increase key size
rsa-key-size = 2048 # Or 4096
# the current closed beta (as of 2015-Nov-07) is using this server
server = https://acme-v01.api.letsencrypt.org/directory
# this address will receive renewal reminders
email = my-email
# turn off the ncurses UI, we want this to be run as a cronjob
text = True
# authenticate by placing a file in the webroot (under .well-known/acme-upatechallenge/)
# and then letting LE fetch it
authenticator = webroot
webroot-path = /var/www/letsencrypt/
nano /etc/nginx/sites-available/fusionpbx
location /.well-known/acme-challenge {
root /var/www/letsencrypt;
}
nginx -t && nginx -s reload
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
cd /opt/letsencrypt
./letsencrypt-auto --config /etc/letsencrypt/configs/domain.tld.conf certonly
nano /etc/nginx/sites-available/fusionpbx
#ssl_certificate /etc/ssl/certs/nginx.crt;
#ssl_certificate_key /etc/ssl/private/nginx.key;
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
cd /etc/fusionpbx
nano renew-letsencrypt.sh
#!/bin/sh
cd /opt/letsencrypt/
./certbot-auto --config /etc/letsencrypt/configs/my-domain.conf certonly --non-interactive --keep-until-expiring --agree-tos --quiet
if [ $? -ne 0 ]
then
ERRORLOG=`tail /var/log/letsencrypt/letsencrypt.log`
echo -e "The Let's Encrypt cert has not been renewed! \n \n" \
$ERRORLOG
else
nginx -s reload
fi
chmod +x renew-letsencrypt.sh
crontab -e
30 2 * * 1 /etc/fusionpbx/renew-letsencrypt.sh
[OLD - This is done automatically by Fusion - Allow HTTP requests without rewriting to HTTPS if dir = provision or fw]
nano /etc/nginx/sites-enabled/fusionpbx
server {
listen 80;
server_name fusionpbx;
set $prov_test 0;
if ($uri ~* ^.*provision.*$) {
set $prov_test 1;
}
if ($uri ~* ^.*/fw/.*$) {
set $prov_test 1;
}
if ($prov_test != 1) {
rewrite ^(.*) https://$host$1 permanent;
break;
}
Web GUI: Advanced > SIP Profiles > interal-ipv6
Web GUI: Advanced > SIP Profiles > external-ipv6
[OLD - now I am using FusionPBX device provisioning app and IP whitelist by device for security instead] Security Recommendation - Limit access to xml phone configuration directories by nginx directory IP address whitelist
mkdir /var/www/fusionpbx/xml
chown www-data:www-data /var/www/fusionpbx/xml
nano /etc/nginx/includes/admin-ips
allow 1.2.3.4;
nano /etc/nginx/includes/customer1-ips
allow 4.4.4.4;
nano /etc/nginx/sites-enabled/fusionpbx
location ^~ /app/provision/ {
include /etc/nginx/includes/admin-ips;
deny all;
}
location ^~ /xml/ {
root /var/www/fusionpbx;
include /etc/nginx/includes/admin-ips;
deny all;
}
location ^~ /xml/customer1/ {
root /var/www/fusionpbx;
include /etc/nginx/includes/admin-ips;
include /etc/nginx/includes/customer1-ips;
deny all;
}
Here I am making a firmware directory called /fw, and I don't care who reads those files, it will just be used for phones to download firmware updates
location ^~ /fw/ {
root /var/www/fusionpbx;
allow all;
}
service nginx reload
Now the directories are secured per customer using IP address whitelists. We also to make a modification to nginx to not force HTTPS on these directories because, unfortunately, some phones do not support HTTPS config download. Here is how to do that (this only needs to be applied under the Listen 80 server directive):
listen 80;
server_name fusionpbx;
set $allow_http 0;
if ($uri ~* ^.*provision.*$) {
set $allow_http 1;
}
if ($uri ~* ^.*xml.*$) {
set $allow_http 1;
}
if ($uri ~* ^.*fw.*$) {
set $allow_http 1;
}
if ($allow_http = 0) {
rewrite ^(.*) https://$host$1 permanent;
break;
}
This allows only admins to access the xml directory, but customer1 can access /xm/customer1 where that customer's configs are. If I later set up customer2, they wouldn't be able to access configs in directories other than their own.
location ^~ /app/provision/ {
include /etc/nginx/includes/admin-ips;
deny all;
}
location ^~ /xml/ {
root /var/www/fusionpbx;
include /etc/nginx/includes/admin-ips;
deny all;
}
location ^~ /xml/customer1/ {
root /var/www/fusionpbx;
include /etc/nginx/includes/admin-ips;
include /etc/nginx/includes/customer1-ips;
deny all;
}
Here I am making a firmware directory called /fw, and I don't care who reads those files, it will just be used for phones to download firmware updates
location ^~ /fw/ {
root /var/www/fusionpbx;
allow all;
}
service nginx reload
DHCP option 66 is used for zero-touch provisioning. A factory reset phone will grab DHCP and if option 66 is included it will use that to contact the provisioning server to download its configuration, upgrade firmware etc. DHCP option 66 is usually not available on consumer routers unless Linux firmware is used. Windows servers also have the option available.
From web GUI:
Administration > System > Enable JFFS partition > Yes
Administration > System > Format JFFS partition at next boot > No
Administration > System > Enable SSH > Yes
From SSH
cd /jffs/configs
vi dnsmasq.conf.add
dhcp-option=66,"http://yourpbx.yourdomain.com"
Save that then reload dnsmasq:
service restart_dnsmasq
Here's my guide on DHCP option 66 for Ubiquiti's Unifi Security Gateway https://github.com/reillychase/Ubiquiti-USG-DHCP-Option-66
Advanced > default settings -> Add > category: user
subcategory: unique
type: text
value: global
hit the reload button
now usernames have to be unique across the entire system for it to work
Advanced -> Default Settings
Edit Provision subcat: enabled, change enabled: false to enabled: true
Advanced > default settings -> Add > category: provision
subcategory: cidr
type: array
value: ip/32
[OLD - I couldn't get HTTP AUTH over HTTPS to work with zero touch provisioning using DHCP option 66, now I'm just restricting by IP whitelist] Enable HTTP AUTH username and password for secure provisioning
Advanced > default settings -> http_auth_password -> <set to password and enable>
Advanced > default settings -> http_auth_username -> <set to username and enable>
Advanced > domains > pencil (edit) > (+) add per domain setting
[OLD - now I just put fw dir in /app/provision/fw] Allow HTTP download of firmware files in dir /fw/
nano /etc/nginx/sites-enabled/fusionpbx
server {
listen 80;
server_name fusionpbx;
set $prov_test 0;
if ($uri ~* ^.*provision.*$) {
set $prov_test 1;
}
if ($uri ~* ^.*/fw/.*$) {
set $prov_test 1;
}
if ($prov_test != 1) {
rewrite ^(.*) https://$host$1 permanent;
break;
}