leamas / ddupdate

Update DNS Data for Dynamic IP Addresses
MIT License
40 stars 28 forks source link

[question] configuring 2 domains on same service, and other quirks #73

Open atesin opened 1 year ago

atesin commented 1 year ago

hi...

currently my openwrt router manages all my ddns domain updates, but i like to migrate them to my home server, on one hand to release the work load on my router and move it to my more powerful server, and on the other hand because it sounds logical to me that the server will manage the same domains that SERVES (like http or any other service), that way i could take it to anywhere and run the services with minimal configurations

between my ddns configurations i have a service with 2 different domains... i had read ddupdate documentation but i couldn't think a way to configure this accordingly

... now a little of brainstorming and spitting ideas...

since a single domain running with 2 different services can't be setted up, i feel more logical to use the DOMAIN NAME as the unique identifier that ties configurations between all files and storages (ok, maybe a single domain with 2 different services could be set, but is maybe hard, unlikely, and silly)... so this way for example, a ddupdate.conf file theoretically would look like this:

[www.freeserv.example]
# "hostname" option pointless this way
service-plugin = freeserv_basic
auth-plugin = netrc  # can't put comments in the middle of the line, this will be consireded part of the value and invalid
address-plugin = default-if

[www2.freeserv.example]
service-plugin = freeserv_basic
auth-plugin = netrc
address-plugin = hardcoded-if
# this website served through another nic (how to write this options?, and multiple options?)
address-options = if=eth2

[minecraft.freeserv.example]
service-plugin = freeserv_basic
auth-plugin = netrc
address-plugin = hardcoded-if
# vpn
address-options = if=tun0

[backup.cooldomains.example]
service-plugin = cooldomain_token
auth-plugin = netrc
address-plugin = default-if

(additionally, this way ddupdate.conf could be just appended instead of overwritten by ddupdate-config)

... and suppose the corresponding .netrc file would be like:

machine  www.freeserv.example        login johnDoe  password cafebabe
machine  www2.freeserv.example       login johnDoe  password cafebabe
machine  minecraft.freeserv.example  login steve    password deadbeef
machine  backup.cooldomains.example                 password b16b00b5

so looking this file we could reach some conclussions:

now the main question, and supposing i won't create multiple linux user accounts just for this... how the heck could configurations like these being run in current ddupdate release?

p.s. another quirk: command line options --service-option and other ones finished with '-option', together with ddupdate.conf options service-options and others, are written differently (note the trailing "S"), supposedly they are interchangeable... it catched my attention but is not clarified anywhere, is that ok or is a typo?... and how to use them?

ruedigerkupper commented 1 year ago

Hi @atesin, the feature you aks for has already been implemented to resolve #43. (It is just not documented yet.) Please see in #43!

atesin commented 1 year ago

hi... thanks for your interest.... however i don't get clear what is the feature you mean, i admit in my previous post i asked for many features in a little messy way

so my central point is... imagine you are subscribed to an online ddns service, with 2 different user accounts, to update 2 different domains each.... the .netrc file currently supports only ONE account/credetials/token for each online service (i.e. just a single machine line per service)

.... so imagine a .netrc file like this... being aware that .netrc file only manages auth credentials

machine freeserv_basic login www1.freeserv.example password xXxToken
machine freeserv_basic login www2.freeserv.example password zZzToken

another (non standard?) way i use in my freedns v2 plugin i sent the pull request #74 is

machine www1.freeserv.example@freeserv_basic password xXxToken
machine www2.freeserv.example@freeserv_basic password zZzToken

you will see the same service (machine freeserv_basic) with 2 different accounts/domains/tokens .... how can something like this currently be done natively?

ruedigerkupper commented 1 year ago

I see. I was referring to your request for having more than one section in the ddupdate config file for having ddupdate update several addresses (or address types) at once.

Regarding .netrc I can't be of much help. But I believe it's out of scope of the ddupdate software and its developer to change how .netrc works. One workaround for your problem should be having different dedicated system users for ddupdate, with different configurations and .netrc files. That's how I solved my problem before @leamas implemented the multi-section config. Hope you can get it working for you!

leamas commented 1 year ago

Hi Atesin,

sorry for late reply. ENOTIME...

There are some interesting ideas here. However, we cannot change the netrc format, this is a system service used not only by ddupdate with it's own manual page. See man netrc. . Added to that, I don't really want to make such big changes to the data model. Going this path would probably break our API stability promise that nothing incompatible should happen before 1.0.0.

So, back to the drawing board: How could you have two different domains using a single service? Looking at man ddupdate.conf we see (excerpt):

EXTENDED FORMAT FOR MULTIPLE HOSTS
       File  has  experimental  support for updating multiple services. This is done using multiple [hostname] sections. The hostname is an arbitrary string without white‐
       space. Each section has the same syntax as the BASIC FILE FORMAT [update] section.

You might want to read more in that manpage. But the short story seems to be that you can do exactly what you described as theoretical, besides that you need to specify host.

atesin commented 1 year ago

hi @leamas , thanks for your kind response

you see i (tried to) write a plugin and made a pull request... you will see the new afraid.org api v2 is really powerful and simple

support for different domains with single service is nice... but i was really thinking, what about multiple accounts with same service?... for example, imagine you offer webhosting for 2 different friends, each one with its own domain and dyndns account, and you have to configure both account+domain in same ddns service

multiple [update] sections in ddupdate.conf could work for multiple domains in same ddns service, but under the same account... how can we make it work different domains in same ddns service but with different accounts (or tokens)?

leamas commented 1 year ago

I might be missing something here, but what is the problem? Why is it not possible to define two different sections using the same service?

atesin commented 1 year ago

yes 2 domains in same ddns service with same user account... but not in the same service with 2 DIFFERENT USER ACCOUNTS

surely in ddupdate.conf you can set 2 sections with 2 different domains for a single service, as long as be with the same user account, because user acounts are managed in another file (.netrc) not in ddupdate.conf itself

i think that is because .netrc structure.... there you can't add 2 lines with duplicate machine names one for each user credentials... i see .netrc is an ancient format intended to store remote ftp credentials for a single unix user, but actually today a single PERSON can have multiple user accounts everywhere for many exotic services

for example, imagine i give webhosting to 2 or more friends, and they have their own domain and ddns account in same service, how can i currently configure ddupdate with all accounts in same ddns service?

a dirty workaround could be to create multiple linux user accounts, with one .netrc file each to store each credentials, and configure one ddupdate systemd service for each.... not practical at all, complicated, error prone and hard to maintain

i did't knew it before i wrote afraid.org v2 plugin (pull request here -> #74) so i tried to surpass these limitations as i thought

i can't get to understand, why did you choose to use .netrc file feature considering its age and limitations (i.e. i never heard before), instead of create a custom and ad-hoc (file) solution to manage remote ddns accounts when can easily be done

leamas commented 1 year ago

Today, ddupdate is also able to use the keyring to handle credentials. However, the keyring is based on the same idea: It maps a key to a single value, so it's no difference. I think the keyring could be considered "modern", so this issue is not about a that.

That said. I see your problem. I need some time I don't have to think about it. I'm open to ideas, as long as they don't break compatibility with current code.

atesin commented 1 year ago

thanks... chances are i am not the only one that will have to face this difficulty

try to think a simple solution, to program and to use it... i found the keyring one also complicated, i never use it and always disable and uninstall because i am the only user of my home server, same with those cloud based virtual machines (and same with selinux that brings me more problems than solutions)... if i have to create system accounts they are mainly used by processes

imagine what will happen to someone that, rarely, still today uses ftp with .netrc file (for example to upload html files to his webhosting, or to upload big files to some remote storage) and now have to modify by adding some "foreign" configurations

there are countless posibilities to do this... for example ddupdate could have a custom and dedicated ini/conf/json, etc. i saw is easy to do with python (even ddupdate DOES with ddupdate.conf)... or could add support to mariadb/mysql or sqlite, or store credenials [g]zipped, or write a little service to manage them, who knows...

whatever custom mechanism could also store credentials encrypted some way (.netrc doesn't)... though i see no urgent need to be encrypted anyway, python sources are available so anyone can see how to decrypt, and even many ddns services updates trough plain http.... additionally for multi-user shared environments i think the keyring option is already present (but does it support services with multiple user accounts?)

i think the simplest and faster solution could be to add all auth info in same ddupdate.conf file, or if want to keep splitted write another custom-made .conf file, encrypted or not ... and the coolest solution an sqlite local database 8)

that system could reference auth credentials by a given name, unlike now that is reference by "machine name" (what prevents multi-user services)... and in ddupdate.conf auth credentials could be referenced by that name instead machine name .... aside auth-plugin, imagine an additional configuration auth-credentials or auth-entry auth-name that tells what named user-pass pair credentials to use (could store more account related info)

i am full of ideas but lacked of knowledge.... i will sort some ideas and come back to tell you, if you like

leamas commented 1 year ago

for example ddupdate could have a custom and dedicated ini/conf/json,

will not happen. Storing secrets in plain text files should be avoided. For those who needs it netrc makes the job, is reasonable well known and documented. Anything else has to to protected/encrypted. Says who?

I do.

This is not a question about how data is stored, it's a question about the actual key used to look up the secret. Neither netrc nor the keyring knows or cares about multiple user accounts, they are just a key->value mapping. Which of course could be used in all sorts of scenarios including yours.

atesin commented 1 year ago

why don't just give an option to store service password in same ddupdate.conf file?... it is stored inside user home directory, that means nobody else could access it (but root of course)... i agree with you about security, for those exists keyring plugin, but think about single user servers, there are many of those... i worked in a big company with 2500 employes and i was the ONLY sysadmin, that managed ~50 servers... i think this conversation is not about security but about single ddns services with many user accounts

why not simply give an arbitrary a name to [service,user,passord] auth configs? in csv format will be some like cf-jondoe, cloudflare, johndoe, mySecret, someToke, moreConfigs

the question i really think is find a way to prevent same ddns credentials set by different linux users will collide when different ddupdate threads run (topic for another conversation)

leamas commented 1 year ago

Again: this is not a question where passwords are. Let's just state that we will use also netrc and the keyring also in the future.

If you have read up anything at all on security you would know that statements like . it is stored inside user home directory, that means nobody else could access it (but root of course)... are unacceptable and sort of disqualifies you.

So, come back with a concrete suggestion based on using netrc or the keyring which also is compatible with existing installations and plugins. This is what his is about

atesin commented 1 year ago

i agree with you... is not a question about paswords, where to store them and if should be encrypted or not.. but about single ddns services with multiple user accounts (or tokens) like title says... for example, in my case i have 4 domains in afraid.org, 2 mine and 2 of friends (that i am also technical contact)

i.e. for shared linux environments there is keyring plugin, but anyway i don't know if in ddupdate with keyring mechanism, a single ddns service with many user accounts will be supported, with keyring, netrc, conf, database or whatever

for example, i was reading about .netrc file and seem logical to me to link machine and login someway to get password, but as i saw ddupdate just look .netrc entries by machine value (as i saw in get_netrc_auth() function that accepts only one parameter: machine)... and as hosts can sometimes be written as user@host, i took the chance and did this way

// ddupdate.conf example entry
[my.dyn.domain]  // can this title section replace the "hostname" line?
service-plugin = sync.afraid.org
hostname = my.dyn.domain

// plugin source code, being "hostname" the full user@host name taken from .netrc
 password = get_netrc_auth(hostname + '@sync.afraid.org')[1]

// .netrc entry
machine my.dyn.domain@sync.afraid.org password tokenXxXxXx
machine my.dyn.domain2@sync.afraid.org password tokenYyYyYy
machine other.svc login theUser password hisPasswd

// ddplugin.py:129
def get_netrc_auth(machine):

would be fantastic if the function would also be def get_netrc_auth(machine, login):, so in .netrc you could match same machine with many logins to get each password/token =D