Hi. I just upgraded my box to 0.51, with the extremely nice addition of the TOTP support.
However, I use the API to automatically create accounts, and this API now requires my TOTP. Obviously, I want this to be fully automated (it’s in an ansible playbook), so I can’t enter my TOTP multiple times in the play. Not enforcing TOTP in the API would clearly be a security leak, but could there be a way to call it privately without TOTP, maybe on localhost only?
If you are on machine itself, you can pass the api key located in /var/lib/mailinabox/api.key as Authorization header in which case no totp code should be required.
Hope this helps!
Edit: value for Authorization header should look like Basic ${apiKey}. Note that the apiKey changes after a restart
Just finding out that this also seems to be the need for the curl DNS api… which means we can’t use it remotely the same way it is described in the otherwise very helpful docs on the admin page for Custom DNS.
So to do Dynamic DNS from a remote machine, seems I’ll have to figure out some workaround… is there a way to generate valid apiKey per application/use/machine etc… that I could install on my local machine and send via curl to the MiaB machine?
Looking at the code that @fspoettel linked above, it seems the python code does this to run internally on initial user validation, but since the master apiKey is generated on restart there wouldn’t be a solution that works for a remote host.
If that sounds right, I can file an enhancement request/bug in GitHub
Yeah that is correct and the biggest caveat of the current solution. There is an open feature request for api keys already here. Feel free to add a +1 to it and describe your use case to help scope out the feature.
I got around to learning about the api_key. For those that don’t have much experience with HTTP (me included), here is what I hacked up to do dyn-DNS using the long-lived API key. $file follows the curl netrc file format with the TOTP secret appended to the end.
#!/bin/bash
# initialize list of API keys
declare -A APIkeylist
# get userid, password, and public name for server
# multiple names can map to the same server
for file in /etc/rc.local.d/*
do
read -r machine server logincmd username passwordcmd password secret<"$file"
sitename=`basename $file`
#make sure that we have not already authenticated to target MIAB userid
if [ -z ${APIkeylist[$username]} ]; then
# Set 2FA authentication token. Fix in future to not expose secret in "ps".
TOTP="X-Auth-Token: $(oathtool --totp -b -d 6 $secret)"
# authenticate to MIAB server. Get long lived API key.
APIkeylist[$username]="$(curl -s -X GET --netrc-file $file -H "$TOTP" "https://$server/admin/me" | jq -r '.api_key')"
fi
# set IPv4 and IPV6 names
curl -4 -X PUT -u "$username:${APIkeylist[$username]}" "https://$server/admin/dns/custom/$sitename/A"
curl -6 -X PUT -u "$username:${APIkeylist[$username]}" "https://$server/admin/dns/custom/$sitename/AAAA"
done
This will then return your API key, which can be used in place of the $Password in other API calls. For security reasons, I would not recommend using this key publicly, but from within your box, it should be fine. (use at your own risk)