I have a new Ubiquiti Unifi Security Gateway Pro 4 which is pretty neat; however, the Unifi web interface is pretty limited. Most advanced firewall functions must be configured outside of the GUI. One must create a .json file with the configuration they need, copy that file to the Unifi controller, and then force a provision of the gateway to get it to pick up the new config.
I wanted a way to automate this process but very frustratingly Ubiquiti hasn’t documented their Unifi Controller API. I had to resort to reverse engineering their API by using my browser’s developer console to figure out which API calls were needed to do what I wanted. I then took the API functions from https://dl.ui.com/unifi/5.10.25/unifi_sh_api (the current unifi controller software download link which has unifi_sh_api) and embedded them into a bash script. Thanks to this forum post for the information on how to do this.
This bash script copies the specified config file to the Unifi controller via SCP, then uses curl to issue the API call to tell the controller to force a provision to the device having the supplied mac address.
#!/bin/bash
# Written by Nick Jeppson 08/01/2019
# Inspired by posts made from ubiquiti forums: https://community.ui.com/questions/API/82a3a9c7-60da-4ec2-a4d1-cac68e86b53c
# API interface functions taken from unifi_sh_api shipped with controller version 5.10.25, https://dl.ui.com/unifi/5.10.25/unifi_sh_api
#
# This bash script copies the specified config file to the Unifi controller via SCP
# It then uses curl to issue an API call to tell the controller to force a provision to the device with the supplied mac address.
#### BEGIN VARIABLES ####
#Fill out to match your environment
gateway_mac="12:34:56:78:90:ab" #MAC address of the gateway you wish to manage
config_file="your_config_file.json" #Path to config file
unifi_server="unifi_server_name" #Name/IP of unifi controller server
unifi_gateway_path="/usr/lib/unifi/data/sites/default/config.gateway.json" #Path to config.gateway.json on the controller
ssh_user="root" #User to SSH to controller as
username="unifi_admin_username" #Unifi username
password="unifi_admin_password" #Unifi password
baseurl="https://unifi_server_name:8443" #Unifi URL
site="default" #Unifi site the gateway resides in
#### END VARIABLES ####
#Copy updated config to controller
scp $config_file $ssh_user@$unifi_server:$unifi_gateway_path
#API interface functions
cookie=$(mktemp)
curl_cmd="curl --tlsv1 --silent --cookie ${cookie} --cookie-jar ${cookie} --insecure "
unifi_login() {
# authenticate against unifi controller
${curl_cmd} --data "{\"username\":\"$username\", \"password\":\"$password\"}" $baseurl/api/login
}
unifi_logout() {
# logout
${curl_cmd} $baseurl/logout
}
unifi_api() {
if [ $# -lt 1 ] ; then
echo "Usage: $0 <uri> [json]"
echo " uri example /stat/sta "
return
fi
uri=$1
shift
[ "${uri:0:1}" != "/" ] && uri="/$uri"
json="$@"
[ "$json" = "" ] && json="{}"
${curl_cmd} --data "$json" $baseurl/api/s/$site$uri
}
#Trigger a provision
unifi_login
unifi_api /cmd/devmgr {\"mac\": \"$gateway_mac\", \"cmd\": \"force-provision\"}
unifi_logout
No more manually clicking provision after manually editing the config file on the controller!