Fixing a UniFi controller where the admin user cannot log in

A friend has a UniFi network setup, with the UniFi controller running on a CloudKey.

Their username and password for the controller admin account did not work, even though they were sure they were using the correct credentials.

They asked if I could help fix it.

I could, and I did.

But it did not go as well as I had hoped.

tl;dr

I got back in without wiping the controller config but, in doing so, I needed to re-adopt the devices, and re-add their settings, so I might have well have wiped the config and saved myself hours. I don’t know which bit caused the config loss / required the re-adoption.

Restoring from a backup

First, I tried restoring from a backup.

Trouble was, the controller autobackups were all very old - months ago, and from previous, historic, versions of the controller software.

That gave me a clue as to roughly when things started going wrong.

I tried restoring the most modern of the old backups from the CloudKey’s interface, and it seemed to work.

But no luck letting me log in.

SSH worked

Using ssh, I was able to access the CloudKey, on which the controller runs.

There are backups in multiple places - for the CloudKey, and for the controller - and my notes say that I got the backup I needed from /usr/lib/unifi/data. However, that feels a bit suspect - I think it was probably in /data (and some subdirectories under that) for the controller.

But I was able to locate a backup - named something like autobackup_6.2.26_20211201_0000_1638316800080.unf - (as you can see, very old!), and copy it to my local machine via scp.

Decoding the UniFi binary backup file

UniFi backups are in BSON - binary JSON - format.

I reviewed then ran this script to decode it.

It failed silently, so I removed the final > /dev/null 2>&1, so I could see what I was doing wrong.

And it was me - I had thought I had zip installed on the local machine I was using, but I did not (and that teaches me not to check that I satisfied the dependencies first…).

I installed zip.

I could see the username was correct, and the x_shadow of a password.

Checking the password in the config

UniFi does not store the password in plaintext, which is good.

Since I had the password’s x_shadow, and I knew what I thought the password was, I used hashcat to test it.

I put the x_shadow into a file called “hash”, put the password I wanted to test into a file called “wordlist”, and then ran:

hashcat -m 1800 -a 3 hash wordlist -o pass

And it confirmed I had the right password.

So why wasn’t it working?

Into the database…

Since I had ssh access, I look at the mongo database on which the controller relies.

It’s unauthenticated, so I got in with:

mongo --port 27117 ace

From there, I showed the available databases, and there was one called admin.

But db.admin.find() returned nothing.

Odd.

Some online suggestions show use of db.admin.update, but there was nothing to update.

I saw online that it should have had a schema, in the form:

{
        "_id" : ObjectId("5c390d18556c18121847c8d4"),
        "email" : "admin@example.com",
        "last_site_name" : "default",
        "name" : "admin",
        "time_created" : NumberLong(1547242776),
        "ui_settings" : {
                "dashboardConfig" : {
                        "dashboards" : {
                                "5c3908cf556c18121847c8bd" : {
                                        "order" : 1
                                }
                        },
                        "lastActiveDashboardId" : "5c3908cf556c18121847c8bd"
                },
                "statisticsPrefferedTZ" : "LOCAL"
        },
        "x_shadow" : "$6$9Ter1EZ9$lSt6/tkoPguHqsDK0mXmUsZ1WE2qCM4m9AQ.x9/eVNJxws.hAxt2Pe8oA9TFB7LPBgzaHBcAfKFoLpRQlpBiX1"
}

So I made some tweaks, and inserted it:

db.admin.insert(
{
        "_id" : ObjectId("5c390d18556c18121847c8d4"),
        "email" : "TheEmailAddressIWanted@example.com",
        "last_site_name" : "default",
        "name" : "admin",
        "time_created" : NumberLong(1547242776),
        "ui_settings" : {
                "dashboardConfig" : {
                        "dashboards" : {
                                "5c3908cf556c18121847c8bd" : {
                                        "order" : 1
                                }
                        },
                        "lastActiveDashboardId" : "5c3908cf556c18121847c8bd"
                },
                "statisticsPrefferedTZ" : "LOCAL"
        },
        "x_shadow" : "$6$9Ter1EZ9$lSt6/tkoPguHqsDK0mXmUsZ1WE2qCM4m9AQ.x9/eVNJxws.hAxt2Pe8oA9TFB7LPBgzaHBcAfKFoLpRQlpBiX1"
}
)

I found out from here that I also needed to update permissions.

And, after I restarted the UniFi controller via the CloudKey, I was able to log in with admin/password, and change the password back to what it should have been.

But I had to adopt the APs/switch, and reconfigure it

I am not sure what I did wrong, or if this was just inevitable, but I had to re-adopt (using the Advanced Adoption tool) all the APs and the switch, and re-configure it from scratch.

It was pretty simple - a few SSIDs and a few VLANs - but it was what I was trying to avoid.

I think it would have been much faster to reset the controller, and start afresh.