unifi-utilities / unifios-utilities

A collection of enhancements for UnifiOS based devices
GNU General Public License v3.0
3.91k stars 420 forks source link

[Feature request] Read ssh keys from UniFi configuration #140

Open buzz-tee opened 3 years ago

buzz-tee commented 3 years ago

Is your feature request related to a problem? Please describe. I'd like to suggest an update to 15-add-root-ssh-key.sh to read the ssh keys from the UniFi config instead of hard coding the key data to the on_boot.d script. That would be more user friendly.

Describe the solution you'd like A way to do this could be as follows, works nicely on my box:

#!/bin/sh

AUTHORIZED_KEYS=/root/.ssh/authorized_keys

KEYS_RC=-1
COUNT=0
while [ ${KEYS_RC} -ne 0 ] && [ ${COUNT} -lt 60 ]
do
    KEYS_DATA=$(podman exec unifi-os mongo --port 27117 --eval 'db.setting.find({key: {$eq: "mgmt"}}, {x_ssh_keys: 1, _id: 0});' --quiet ace)
    KEYS_RC=$?
    COUNT=$(( COUNT+1 ))
    [ ${KEYS_RC} -ne 0 ] && [ ${COUNT} -lt 60 ] && sleep 10
done

if [ ${KEYS_RC} -ne 0 ]
then
    echo "Failed to load keys from config"
    exit 1
fi

echo "${KEYS_DATA}" \
    | jq -r '.x_ssh_keys | map([.type, .key, .comment] | join(" ")) | join("\n")' \
    | while IFS= read -r KEY
do
    if ! grep -Fxq "${KEY}" "${AUTHORIZED_KEYS}"
    then
        echo "${KEY}" >> "${AUTHORIZED_KEYS}"
    fi
done

Describe alternatives you've considered I was working with the example script previously, but I wanted to manage the SSH keys via UniFi OS and don't have to think about keeping the script updated.

Additional context Should be self-explanatory.

Tntdruid commented 3 years ago

Works great, thanks :)

buzz-tee commented 3 years ago

I found for myself it's working - except when the device is booting. Seems there is a race condition and the MongoDB is not ready when the script is run. I updated the snippet to wait until it gets a valid response (max. 10 minutes) but it feels rather hacky and while it is waiting it is also blocking the execution of other scripts. It works well enough for my purposes so I might leave it as is, but maybe somebody finds the time to tweak it a bit further or - ideally - have the script fork itself :)

mabunixda commented 3 years ago

It seems there is another json item date at the release of 1.9.0, which cannot be handled by jq. I updated the script to work with 1.9.0 release.

#!/bin/sh

AUTHORIZED_KEYS=/root/.ssh/authorized_keys

KEYS_RC=-1
COUNT=0
while [ ${KEYS_RC} -ne 0 ] && [ ${COUNT} -lt 60 ]
do
    KEYS_DATA=$(podman exec unifi-os mongo --port 27117 --eval 'db.setting.find({key: {$eq: "mgmt"}}, {x_ssh_keys: 1, _id: 0});' --quiet ace)
    KEYS_RC=$?
    COUNT=$(( COUNT+1 ))
    [ ${KEYS_RC} -ne 0 ] && [ ${COUNT} -lt 60 ] && sleep 10
done

if [ ${KEYS_RC} -ne 0 ]
then
    echo "Failed to load keys from config"
    exit 1
fi

echo "${KEYS_DATA}" \
    | sed 's/\"date\" : ISODate\(.*\),//' \
    | jq -r '.x_ssh_keys | map([.type, .key, .comment] | join(" ")) | join("\n")' \
    | while IFS= read -r KEY
do
    if ! grep -Fxq "${KEY}" "${AUTHORIZED_KEYS}"
    then
        echo "${KEY}" >> "${AUTHORIZED_KEYS}"
    fi
done