Skip to content

Instantly share code, notes, and snippets.

@jpauli
Last active April 6, 2018 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpauli/0d339973c244fc83248f67dc3b8f9d2f to your computer and use it in GitHub Desktop.
Save jpauli/0d339973c244fc83248f67dc3b8f9d2f to your computer and use it in GitHub Desktop.
Update bind zones on public IP DHCP renew
#!/home/doc/php/bin/php
<?php
$exit = 0;
$exit_signal = 0;
function fork()
{
$pid = pcntl_fork();
if ($pid < 0) {
exit(1);
} else if ($pid) { // parent
exit;
} else { // child
$pid = pcntl_fork();
if ($pid < 0) { exit(1); }
if ($pid) {
exit;
} else {
$sid = posix_setsid();
if ($sid < 0) {
exit(1);
}
fclose(STDOUT);
fclose(STDIN);
fclose(STDERR);
}
}
}
function check_root()
{
if (posix_getuid()) {
echo "root needed\n";
exit(1);
}
}
function check_signals()
{
global $exit, $exit_signal;
if ($exit) {
syslog(LOG_INFO, "exiting by signal $exit_signal");
exit;
}
}
function signal_handler($sig_no)
{
global $exit, $exit_signal;
$exit = 1;
$exit_signal = $sig_no;
}
function setup_signals(array $signals)
{
pcntl_async_signals(true);
foreach ($signals as $signal) {
pcntl_signal($signal, 'signal_handler', false);
}
}
function check_php()
{
if (version_compare(PHP_VERSION, '7.1.0') <= 0) {
echo "PHP >=7.1 needed\n";
exit(1);
}
}
function setup()
{
openlog(__FILE__, LOG_NDELAY, LOG_LOCAL1);
ini_set('default_socket_timeout', 2);
setup_signals(SIGNALS);
}
/** ************ */
const BIND_FILES = [
"/etc/bind/zones/db.jpauli.tech",
"/etc/bind/zones/db.drarena.fr"
];
const SERVER_ADDR = '127.0.0.1:6464';
const IP_URL = 'http://ipv4.lafibre.info/ip.php';
const IP_REGEX = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)';
const SIGNALS = [SIGTERM, SIGINT, SIGHUP];
const NETWORK_SECRET = "ip\n";
check_php();
check_root();
fork();
setup();
$s = @stream_socket_server(SERVER_ADDR, $errno, $error);
if (!$s) {
syslog(LOG_ERR, "Can't create server : '$error'\n");
exit(1);
}
while(1) {
check_signals();
while ($c = @stream_socket_accept($s, -1)) {
check_signals();
$content = stream_get_contents($c, 3);
if ($content != NETWORK_SECRET) {
syslog(LOG_CRIT, "Got wrong challenge\n");
goto end;
}
$newip = @file_get_contents(IP_URL, null, null, null, 20);
if (!$newip || !preg_match('/'.IP_REGEX.'/', $newip)) {
syslog(LOG_ERR, "Could not retrieve ip from " .IP_URL. "\n");
goto end;
}
$reload = 0;
foreach (BIND_FILES as $zone) {
$m = [];
if (!preg_match('/\$IP\s('.IP_REGEX.')\n/', $content = file_get_contents($zone), $m)) {
syslog(LOG_ERR, "Bind zone file '$zone' seems wrong, no \$IP pattern found\n");
continue;
}
if ($newip == $m[1]) {
syslog(LOG_INFO, "no update needed\n");
goto end;
}
$content = str_replace($m[1], $newip, $content);
file_put_contents($zone, $content);
$reload = 1;
}
if ($reload) {
exec('rndc reload');
syslog(LOG_INFO, "Updated zones to public ip $newip\n");
fwrite($c, "ok");
}
end:
fclose($c);
check_signals();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment