Last active
April 6, 2018 09:24
-
-
Save jpauli/0d339973c244fc83248f67dc3b8f9d2f to your computer and use it in GitHub Desktop.
Update bind zones on public IP DHCP renew
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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