Describes how to configure your Ubiquiti Controller to enable Cloudi-Fi’s captive portal.
Integration tested on
Uniti - 6.1.71 - 6.5.55 - 7.0.23
UAP-AC-Lite - 5.43.35.12698
Configuration time: 20 minutes
This setup consists of the main parts:
Step 1: Get Cloudi-Fi required URL
Step 2: Get Radius information
Step 3: Basic captive portal setup
Step 4: Add a new Radius Server Profile
Step 5: Assign Radius and set the white list
Step 6: Deploy customized portal pages
Step 7: (optional) Install a public certificate
Use case:
The following sections will provide step-by-step instructions to enable Cloudi-Fi cloud-based WiFi Captive portal service with your existing Ubiquiti architecture.
Prerequisites:
Before starting, ensure that you have the following prerequisites:
- A Ubiquiti access point.
- Access to the Ubiquiti Controller/dashboard.
- Knowledge of your network’s IP addressing scheme.
Step 1: Get Cloudi-Fi required URL
Location URL: this URL will be used to configure an External Captive Portal
- Access the Cloudi-Fi administration console
- Select the location
- Click on the menu button for the location
- Select "Copy Splash page URL"
Step 2: Get Radius information
You will need the Radius information (Server IPs, Secret, Ports) to proceed with the setup.
- IPs address of the Radius servers
- Ports: UDP 1812 (Authentication) & 1813 (Accounting)
- The Secret (provided by Cloudi-Fi Support)
You can get the Secret by asking in the Chatbot, Cloudi-Fi’s Support team will provide you with the necessary information.
- What shared secret is used for the Radius server with Ubiquiti? (Please save this confidential information securely, and do not share it publicly.)
Step 3: Basic captive portal setup
Go to Settings Guest Control Guest Policies:
-
Enable Guest Portal: checked
-
Authentication: Hotspot
-
Default Expiration: 8 hours
-
Landing Page Promotional URL: "https://login.cloudi-fi.net/success.php"
-
Redirection Use Secure Portal - checked
-
Redirection Redirect using hostname: "Hostname of your Ubiquiti Controller" (a valid certificate has to be installed if you don't have any certificate go to section 6)
Captive portal Customization:
-
Override templates with custom changes: checked.
Here is a screenshot of the described configuration
Step 4: Add a new Radius Server Profile
Settings Profiles Radius Create a new radius profile:
-
Name: Cloudi-FI Radius
-
The Cloudi-Fi Support team will provide IP Address, Port and Secret
-
Save
Step 5: Assign Radius and set the white list
Go back to Settings Guest Control Hotspot:
-
Disable All options except Radius
-
Radius: checked
Settings Guest Control Radius:
-
Profile: Cloudi-Fi Radius
-
Authentication type: CHAP
Settings Guest Control Access Control:
-
178.33.251.41/32
-
login.cloudi-fi.net
-
login-cn.cloudi-fi.net
Step 6: Deploy customized portal pages
To trigger the Cloudi-Fi portal, a custom web page has to replace the default Ubiquiti Hotspot Portal page for each site where Cloudi-Fi is enabled.
Please take note of the "ch" attribute value from the Splash Page URL retrieved on the first step from the Cloudi-Fi Administration Console.
Replace the "" markup by the "ch" attribute value in the following code and save the code to "index.html" file.
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Guest WiFi</title>
<script src="cloudifi_unifi.js"></script>
</head>
<body>
<script>
var redirectPortal=buildRedirect();
window.location.replace(redirectPortal);
</script>
</body>
</html>
Cloudifi_unifi.js
var portail="https://login.cloudi-fi.net/start/ch/
/sp/spubiquitiredirect.com";
var Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(e) {
var t = "";
var n, r, i, s, o, u, a;
var f = 0;
e = Base64._utf8_encode(e);
while (f <e.length) {="{">
n = e.charCodeAt(f++);
r = e.charCodeAt(f++);
i = e.charCodeAt(f++);
s = n 2;
o = (n & 3) <><4 |="|" r="r"> 4;
u = (r & 15) <><2 |="|" i="i"> 6;
a = i & 63;
if (isNaN(r)) {
u = a = 64
} else if (isNaN(i)) {
a = 64
}
t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) +
this._keyStr.charAt(u) + this._keyStr.charAt(a)
}
return t
},
decode: function(e) {
var t = "";
var n, r, i;
var s, o, u, a;
var f = 0;
e = e.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (f <e.length) {="{">
s = this._keyStr.indexOf(e.charAt(f++));
o = this._keyStr.indexOf(e.charAt(f++));
u = this._keyStr.indexOf(e.charAt(f++));
a = this._keyStr.indexOf(e.charAt(f++));
n = s <><2 |="|" o="o"> 4;
r = (o & 15) <><4 |="|" u="u"> 2;
i = (u & 3) <><6 |="|" a;="a;">
t = t + String.fromCharCode(n);
if (u != 64) {
t = t + String.fromCharCode(r)
}
if (a != 64) {
t = t + String.fromCharCode(i)
}
}
t = Base64._utf8_decode(t);
return t
},
_utf8_encode: function(e) {
e = e.replace(/\r\n/g, "\n");
var t = "";
for (var n = 0; n <e.length; n++)="n++)" {="{">
var r = e.charCodeAt(n);
if (r <128) {="{">
t += String.fromCharCode(r)
} else if (r 127 && r <2048) {="{">
t += String.fromCharCode(r 6 | 192);
t += String.fromCharCode(r & 63 | 128)
} else {
t += String.fromCharCode(r 12 | 224);
t += String.fromCharCode(r 6 & 63 | 128);
t += String.fromCharCode(r & 63 | 128)
}
}
return t
},
_utf8_decode: function(e) {
var t = "";
var n = 0;
var r = c1 = c2 = 0;
while (n <e.length) {="{">
r = e.charCodeAt(n);
if (r <128) {="{">
t += String.fromCharCode(r);
n++
} else if (r 191 && r <224) {="{">
c2 = e.charCodeAt(n + 1);
t += String.fromCharCode((r & 31) <><6 |="|" c2="c2" &="&" 63);="63);">
n += 2
} else {
c2 = e.charCodeAt(n + 1);
c3 = e.charCodeAt(n + 2);
t += String.fromCharCode((r & 15) <><12 |="|" (c2="(c2" &="&" 63)="63)"><><>
6 | c3 & 63);
n += 3
}
}
return t
}
}
function getQueryParams(parameterName) {
var result = null,
tmp = [];
var items = location.search.substr(1).split("&");
for (var index = 0; index <items.length; index++)="index++)" {="{">
tmp = items[index].split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
}
return result;
}
function buildRedirect(){
var ap_identifier=getQueryParams("ap");
var client_mac=getQueryParams("id");
var ssid=getQueryParams("ssid");
var url_post=getQueryParams("url");
var auth=window.location.protocol + '//' + window.location.host + window.location.pathname + 'signin.html';
var t=getQueryParams("t");
var redirect= portail + "?ap=" + ap_identifier + "&id=" + client_mac + "&login_url=" + auth + "&ssid=" + ssid + "&t=" + t;
return redirect;
}
function doSignin(){
var dataJson=Base64.decode(getQueryParams("params"));
var success_url=getQueryParams("next_url");
var failure_url=portail;
var xhr = new XMLHttpRequest();
xhr.open("POST", "login", true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.onload = function (e) {
if (xhr.readyState === 4 && xhr.status === 200) {
var res = JSON.parse(xhr.responseText);
if (res && res["meta"]) {
if (res["meta"]["rc"] && res["meta"]["rc"] == "ok") {
window.location.replace(success_url);
} else {
if (res["meta"]["msg"]) {
window.location.replace(failure_url + '&Error=' + res["meta"]["msg"]);
} else {
window.location.replace(failure_url + '&Error=Ubiquiti+Unknown+Error');
}
}
} else {
window.location.replace(failure_url);
}
}
};
try {
var resp = xhr.send(dataJson);
} catch(err){
console.log(err);
}
}
Signin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Guest WiFi</title>
<script src="cloudifi_unifi.js"></script>
</head>
<body>
<script>
doSignin();
</script>
</body>
</html>
Copy the files into
UniFi Cloud Key: /srv/unifi/data/sites//portal
Debian: /usr/lib/unifi/data/sites//app-unifi-hotspot-portal/
Mac: /Applications/UniFi.app/Contents/Resources/data/sites//portal
Windows: :\Users\\Ubiquiti UniFi\data\sites\\portal
Step 7: (optional) Install a public certificate
Cloudi-Fi provides a Keystore that can be deployed directly on your Unifi server; get in touch in our chat to get the Keystore.
To generate and install your certificate, follow the following guideline by clicking this link.
Troubleshooting:
If you still encounter any issues during the setup or operation, follow Cloudi-Fi's first-level troubleshooting guide. If you still face issues, we invite you to contact the Cloudi-Fi support team.
What’s Next?
Congratulations on configuring your Ubiquiti Controller with Cloudi-Fi!