UniFi Controller на CentOS7 (upd 2023)

Есть виртуальный сервер с CentOS7. Возникла необходимость настройки точек доступа Ubiquiti UniFi AP. Для этого нужен контроллер, работающий на JAVA. Для организации HotSpot нужно чтобы этот контроллер работал всегда, а не только для настройки.

Предварительно ставим нужные пакеты

yum install lsb -y
yum install wget -y
yum install unzip -y
yum install java -y

Скачиваем архив с контроллером, из наиболее актуального, что удалось найти под CentOS – версия 7.3.83

cd /usr/src
wget https://www.ubnt.com/downloads/unifi/7.3.83/UniFi.unix.zip

Создаем папки для установки

mkdir -p /opt/UniFi/data
mkdir -p /var/opt/UniFi/data
ln -s /var/opt/UniFi/data /opt/UniFi/data

Распаковываем контроллер

unzip UniFi.unix.zip -d /opt/

Настраиваем репозиторий и устанавливаем сервер баз данных

rpm --import https://www.mongodb.org/static/pgp/server-3.2.asc

mcedit /etc/yum.repos.d/mongodb-org-3.2.repo
[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1

yum install -y mongodb-org

Добавляем пользователя и настраиваем его права

useradd -M unifi
usermod -L unifi
usermod -s /bin/false unifi
chown -R unifi:unifi /opt/UniFi
chown -R unifi:unifi /var/opt/UniFi

Настраиваем сервис UniFi

mcedit /var/opt/UniFi/unifi.service

[Unit]
Description=UniFi
After=syslog.target
After=network.target
[Service]
Type=simple
User=unifi
Group=unifi
ExecStart=/usr/bin/java -jar /opt/UniFi/lib/ace.jar start
ExecStop=/usr/bin/java -jar /opt/UniFi/lib/ace.jar stop
# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300
[Install]
WantedBy=multi-user.target

ln -s /var/opt/UniFi/unifi.service /usr/lib/systemd/system/unifi.service

Запускам сервис UniFi и добавляем в автозагрузку. Сразу поверяем статус работы

systemctl enable /var/opt/UniFi/unifi.service
systemctl start unifi.service
systemctl status unifi.service

На этом всё, остальная настройка идет через браузер.

https://unifi.trakrd.local:8443/

Для работы UniFi контроллера должны быть открыты следующие порты:

TCP 8080
TCP 8443
TCP 8880
TCP 8843
TCP 22
UDP 3478

Дополнительно, установим самоподписанный сертификат. Для этого есть готовый скрипт, в котором в зависимости от операционной системы нужно задать свои настройки. После изменений копируем файлы сертификата на сервер, делаем скрипт исполняемым и запускаем. А вот и  сам скрипт:

#!/usr/bin/env bash

# CONFIGURATION OPTIONS
UNIFI_HOSTNAME=unifi.trakrd.local
UNIFI_SERVICE=unifi

# Uncomment following three lines for Fedora/RedHat/CentOS
UNIFI_DIR=/opt/UniFi
JAVA_DIR=${UNIFI_DIR}
KEYSTORE=${UNIFI_DIR}/data/keystore

# Uncomment following three lines for Debian/Ubuntu
#UNIFI_DIR=/var/lib/unifi
#JAVA_DIR=/usr/lib/unifi
#KEYSTORE=${UNIFI_DIR}/keystore

# Uncomment following three lines for CloudKey
#UNIFI_DIR=/var/lib/unifi
#JAVA_DIR=/usr/lib/unifi
#KEYSTORE=${JAVA_DIR}/data/keystore

# FOR LET'S ENCRYPT SSL CERTIFICATES ONLY
# Generate your Let's Encrtypt key & cert with certbot before running this script
LE_MODE=no
LE_LIVE_DIR=/etc/letsencrypt/live

# THE FOLLOWING OPTIONS NOT REQUIRED IF LE_MODE IS ENABLED
PRIV_KEY=/root/unifi.trakrd.local.pem
SIGNED_CRT=/root/unifi.trakrd.local.crt
CHAIN_FILE=/root/CA.TRAKRD.local.crt

# CONFIGURATION OPTIONS YOU PROBABLY SHOULDN'T CHANGE
ALIAS=unifi
PASSWORD=aircontrolenterprise

#### Остальное менять не нужно! ####

printf "\nStarting UniFi Controller SSL Import...\n"

# Check to see whether Let's Encrypt Mode (LE_MODE) is enabled

if [[ ${LE_MODE} == "YES" || ${LE_MODE} == "yes" || ${LE_MODE} == "Y" || ${LE_MODE} == "y" || ${LE_MODE} == "TRUE" || ${LE_MODE} == "true" || ${LE_MODE} == "ENABLED" || ${LE_MODE} == "enabled" || ${LE_MODE} == 1 ]] ; then
LE_MODE=true
printf "\nRunning in Let's Encrypt Mode...\n"
PRIV_KEY=${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/privkey.pem
CHAIN_FILE=${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/fullchain.pem
else
LE_MODE=false
printf "\nRunning in Standard Mode...\n"
fi

if [[ ${LE_MODE} == "true" ]]; then
# Check to see whether LE certificate has changed
printf "\nInspecting current SSL certificate...\n"
if md5sum -c "${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/privkey.pem.md5" &>/dev/null; then
# MD5 remains unchanged, exit the script
printf "\nCertificate is unchanged, no update is necessary.\n"
exit 0
else
# MD5 is different, so it's time to get busy!
printf "\nUpdated SSL certificate available. Proceeding with import...\n"
fi
fi

# Verify required files exist
if [[ ! -f ${PRIV_KEY} ]] || [[ ! -f ${CHAIN_FILE} ]]; then
printf "\nMissing one or more required files. Check your settings.\n"
exit 1
else
# Everything looks OK to proceed
printf "\nImporting the following files:\n"
printf "Private Key: %s\n" "$PRIV_KEY"
printf "CA File: %s\n" "$CHAIN_FILE"
fi

# Create temp files
P12_TEMP=$(mktemp)

# Stop the UniFi Controller
printf "\nStopping UniFi Controller...\n"
service "${UNIFI_SERVICE}" stop

if [[ ${LE_MODE} == "true" ]]; then

# Write a new MD5 checksum based on the updated certificate 
printf "\nUpdating certificate MD5 checksum...\n"

md5sum "${PRIV_KEY}" > "${LE_LIVE_DIR}/${UNIFI_HOSTNAME}/privkey.pem.md5"

fi

# Create double-safe keystore backup
if [[ -s "${KEYSTORE}.orig" ]]; then
printf "\nBackup of original keystore exists!\n"
printf "\nCreating non-destructive backup as keystore.bak...\n"
cp "${KEYSTORE}" "${KEYSTORE}.bak"
else
cp "${KEYSTORE}" "${KEYSTORE}.orig"
printf "\nNo original keystore backup found.\n"
printf "\nCreating backup as keystore.orig...\n"
fi

# Export your existing SSL key, cert, and CA data to a PKCS12 file
printf "\nExporting SSL certificate and key data into temporary PKCS12 file...\n"

#If there is a signed crt we should include this in the export
if [[ -f ${SIGNED_CRT} ]]; then
openssl pkcs12 -export \
-in "${CHAIN_FILE}" \
-in "${SIGNED_CRT}" \
-inkey "${PRIV_KEY}" \
-out "${P12_TEMP}" -passout pass:"${PASSWORD}" \
-name "${ALIAS}"
else
openssl pkcs12 -export \
-in "${CHAIN_FILE}" \
-inkey "${PRIV_KEY}" \
-out "${P12_TEMP}" -passout pass:"${PASSWORD}" \
-name "${ALIAS}"
fi

# Delete the previous certificate data from keystore to avoid "already exists" message
printf "\nRemoving previous certificate data from UniFi keystore...\n"
keytool -delete -alias "${ALIAS}" -keystore "${KEYSTORE}" -deststorepass "${PASSWORD}"

# Import the temp PKCS12 file into the UniFi keystore
printf "\nImporting SSL certificate into UniFi keystore...\n"
keytool -importkeystore \
-srckeystore "${P12_TEMP}" -srcstoretype PKCS12 \
-srcstorepass "${PASSWORD}" \
-destkeystore "${KEYSTORE}" \
-deststorepass "${PASSWORD}" \
-destkeypass "${PASSWORD}" \
-alias "${ALIAS}" -trustcacerts

# Clean up temp files
printf "\nRemoving temporary files...\n"
rm -f "${P12_TEMP}"

# Restart the UniFi Controller to pick up the updated keystore
printf "\nRestarting UniFi Controller to apply new Let's Encrypt SSL certificate...\n"
service "${UNIFI_SERVICE}" start

printf "\nDone!\n"
exit 0
Яндекс.Метрика