I did setup bind with dynamic updates via nsupdate (as CarbonLifeForm described), and combined this with a simple Perl-Script which gets called via encrypted HTTPS REST-Request, checks subdomain/password combination and then calls nsupdate with the IP of the request.
Example Update-Call from any client (which will automatically set the appropriate subdomain to the public IP of that client)
Just visit with any Browser (in this example https was made available via Port 12345):
https://ddns.YOURDOMAIN.net:12345/update-my-ip.pl?subdomain=***&password=***
or via the command-line (e.g. for updates every 15 minutes via cronjob):
www-browser -dump 'https://ddns.YOURDOMAIN.net:12345/update-my-ip.pl?subdomain=***&password=***'
Here is the perl-script update-my-ip.pl:
#!/usr/bin/perl
use strict;
use CGI;
use Digest::SHA1 qw(sha1_hex);
my %accounts = (
# create via: sha1sum, then type password, then press Ctrl-D to calculate checksum (echo with pipe gives wrong result!)
# update via: www-browser -dump 'https://ddns.YOURDOMAIN.net:12345/update-my-ip.pl? subdomain=***&password=***'
'YOURSUBDOMAIN1' => '93485720985720394853452345235-fake-sha1-checksum1',
'YOURSUBDOMAIN2' => '93485720985720394853452345235-fake-sha1-checksum2',
'YOURSUBDOMAIN3' => '93485720985720394853452345235-fake-sha1-checksum3',
);
my $cgi = new CGI;
print "Content-type: text/html\n\n";
my $subdomain = $cgi->param('subdomain');
my $password = $cgi->param('password');
if( !$password || !$subdomain || length($password) <= 3 || length($subdomain) <= 1)
{
print "ERROR\n";
exit 0;
}
my $sha1 = sha1_hex($password);
my $ip = $ENV{'REMOTE_ADDR'};
my $should_be_sha1 = $accounts{$subdomain};
if( $sha1 && length($sha1) > 10 && $sha1 eq $should_be_sha1)
{
print "START: ddns.YOURDOMAIN.net DNS updating <a href=\"http://$subdomain.YOURDOMAIN.net\">http://$subdomain.YOURDOMAIN.net</a> (<a href=\"https://$subdomain.YOURDOMAIN.net\">SSL</a>) to IP <a href=\"http://$ip\">$ip</a>.<br/>\n";
my $out = `echo "update delete $subdomain.YOURDOMAIN.net A\n\n" | nsupdate 2>&1`;
print "STEP1 $out<br/>\n";
$out = `echo "update add $subdomain.YOURDOMAIN.net 60 A $ip\n\n" | nsupdate 2>&1`;
print "STEP2 $out<br/>\n";
print "DONE<br/>\n";
}
else
{
print "ERROR\n";
}