-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FIrst upload of the set of files to github
- Loading branch information
Showing
9 changed files
with
2,397 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# vim: sw=8 ts=8: | ||
# A sample configuration file | ||
# | ||
# Put the remainder of IP address on the left, some white space (TAB or | ||
# spaces), and then the host name. | ||
# | ||
# For example, if this file is named 192.168 then you can define a /16 subnet | ||
# by putting the remaining two octets for each entry, such as: | ||
1.1 wifi | ||
1.10 ns1 | ||
1.20 printer | ||
2.10 phone1 | ||
3.2 phone2 | ||
|
||
# In the above example, 192.168.1.1 will be "wifi", 192.168.3.2 will be | ||
# "phone2", etc. The first two octets -- 192.168 -- are derived from the | ||
# file's name. | ||
|
||
|
||
# If this file is named 192.168.1 then are only dealing with the last octet of | ||
# a /24 subnet, so the inputs are simpler, e.g.: | ||
|
||
1 wifi | ||
10 ns1 | ||
20 printer | ||
30 phone1 | ||
31 phone2 | ||
|
||
# In this case all the names will start with 192.168.1 so phone2 is 192.168.1.31 | ||
|
||
|
||
# If this file is named 192 then you are defining a /8 subnet and would put | ||
# three octets for each entry, e.g.: | ||
|
||
168.1.1 wifi | ||
168.1.10 ns1 | ||
168.1.20 printer | ||
168.2.10 phone1 | ||
168.3.2 phone2 | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Stapler simple DNS management | ||
Angelo Babudro ispltd.com | ||
+1 (902) 600-0543 | ||
Documentation and latest version: https://ispltd.org/software:stapler | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Stapler Aliases file (A Babudro ISP Ltd. ispltd.org) | ||
# vim: ts=8:sw=8: | ||
# | ||
# CNAME aliases for server+domain combinations. | ||
# Use to establish a server alias in select domain(s). | ||
# For a name to exist in ALL domains, set it in the IP file instead. | ||
# | ||
# The domain indicates in which zone file the alias is to be placed. | ||
# Fields are separated with one or more spaces or TABs | ||
# Comment lines (beginning with #) and empty lines are ignored. | ||
# | ||
# Note: The mail server should NOT be aliased - sendmail doesn't like it. | ||
# So to have multiple names for your mail server, put all entries in | ||
# the IP file(s), not here. | ||
# | ||
# Alias RealServerName Domain | ||
# ---------- ----------------- -------------- | ||
webmail www yourdomain.ca |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,265 @@ | ||
<?php | ||
# vim: ts=3 sw=3: | ||
# Receive a check-in request from a dynamic-DNS host, check if its IP address | ||
# has changed, and if so, adjust Stapler's dynamic file, run Stapler to | ||
# regenerate DNS files, and then reload BIND. | ||
# | ||
# Angelo Babudro www.ispltd.org www.ispltd.com | ||
# | ||
# First releas: Stapler version 4.31 January 2018 | ||
# | ||
# For this to work you will need to allow Apache (or whatever web server you | ||
# use) to run two commands with 'sudo'. Put a line like this in a file in | ||
# /etc/sudoers.d/: | ||
# apache ALL=NOPASSWD: /usr/sbin/rndc, /usr/local/bin/stapler | ||
# If you use group such as 'httpd' for Apache and/or Nginx then use: | ||
# %httpd ALL=NOPASSWD: /usr/sbin/rndc, /usr/local/bin/stapler | ||
# | ||
# Of course, adjust the paths as required. | ||
# | ||
# ADJUST THESE VARIABLES------------------------------ | ||
|
||
$dynamic_file = "/var/www/dns/dynamic"; #|dynamic DNS file, writable by Apache or Nginx | ||
$mail_recipient = "tech.support@example.com"; #|Who gets e-mails when dynamic DNS changes or verbose flag is used? | ||
#_____[ CHANGE ABOVE ]________________________________ | ||
|
||
|
||
|
||
$verbose = (!empty($_GET["verbose"]) || !empty($_GET["debug"]) || !empty($_GET["v"])); | ||
$exists_msg = file_exists($dynamic_file) ? "[OK]" : "[Not found or no access]"; | ||
$title = "Server Check-in"; | ||
if(isset($_SERVER['X_FORWARDED_FOR'])) { | ||
$current_IP_address = $_SERVER['X_FORWARDED_FOR']; | ||
} else { | ||
$current_IP_address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "127.0.0.1"; | ||
} | ||
$user_node = (!empty($current_IP_address)) ? gethostbyaddr($current_IP_address) : "(unknown)"; | ||
if($verbose) { | ||
ini_set('display_errors', true); | ||
ini_set('html_errors', false); | ||
ini_set('track_errors', true); | ||
echo "This server\t".gethostname()."\nDynamic file\t$dynamic_file $exists_msg\nCheck-in from\t$current_IP_address $user_node\n"; | ||
} | ||
|
||
$msg ="<HTML> | ||
<HEAD> | ||
<STYLE> | ||
TH { text-align: right; } | ||
</style> | ||
<BODY> | ||
<H1>$title</h1> | ||
<TABLE border=0 cellspacing=2 cellpadding=3> | ||
<TR> | ||
<TH>Receiving host</th><TD>".system("hostname")."</td> | ||
</tr> | ||
<TR> | ||
<TH>Check-in from</th><TD>".$_GET["host"]."</td> | ||
</tr> | ||
<TR> | ||
<TH>IP address</th><TD>{$current_IP_address}</td> | ||
</tr> | ||
<TR> | ||
<TH>Node alias</th><TD>{$user_node}</td> | ||
</tr> | ||
<TR> | ||
<TH>Dynamic IP address file</th><TD>{$dynamic_file} $exists_msg</td> | ||
</tr> | ||
"; | ||
if(isset($_GET["user"])) { | ||
$msg .= "<TR><TH>Remote Cron run as user</th><TD>".$_GET["user"]."</td></tr>"; | ||
} | ||
$msg .= "\n</table>\n"; | ||
|
||
if(!$tmpf = tmpfile()) { | ||
$msg .= "Unable to create temporary file.<BR>Changes will need to be made manually.<BR>"; | ||
} | ||
$change = FALSE; | ||
if(file_exists($dynamic_file) && $tmpf) { | ||
$lines = file($dynamic_file); #|Read entire file into an array | ||
$change = check_dynamic($msg, $lines); | ||
if($change) { | ||
if($ec = rewrite_dynamic($msg, $tmpf, $lines)) { | ||
$msg .= "<SMALL>".__LINE__."</small> SUCCESS Writing of the new dynamic file.<BR>"; | ||
|
||
$cmd = "sudo stapler --batch"; | ||
$stapler_output = shell_exec($cmd); #|Save this for last | ||
|
||
$msg .= "<H3>BIND</b>"; | ||
$output = shell_exec("sudo rndc reload"); | ||
$msg .= "<PRE>$ sudo rndc reload\n".$output."</pre><BR>"; | ||
|
||
$output = shell_exec("sudo rndc refresh ixo.ca"); | ||
$msg .= "<PRE>$ sudo rndc refresh ixo.ca\n".$output."</pre><BR>"; | ||
|
||
$msg .= "<H3>Validate results</h3>"; | ||
$output = shell_exec("host ".$_GET["host"]); | ||
$msg .= "<PRE>$ host ".$_GET["host"]."\n".$output."</pre><BR>"; | ||
if(validateNewAddr($current_IP_address)) { | ||
$msg .= "(OK)"; | ||
} else { | ||
$msg .= "<B style='color:red; font-size:36pt;'>FAILURE</b> DNS is <b><i>not</i></b> working!"; | ||
} | ||
$msg .= "<BR><BR> | ||
<H3>Things that may need changing:</h3><BR> | ||
<UL> | ||
<LI>Firewalls</li> | ||
<LI>Public IP address alias | ||
<UL> | ||
<LI>Gentoo Linux: edit /etc/conf.d/net — change public IP address alias (e.g., eth0:1) so server recognizes public traffic coming in from the outside as belonging to it</li> | ||
<LI>Restart the affected interface, e.g., /etc/init.d/net.eth0 restart | ||
<LI>ip addr list (verify the proper address is shown) | ||
<LI>Edit /etc/hosts and change the IP address to $current_IP_address | ||
</ul> | ||
</li> | ||
<LI>Apache and Nginx | ||
<UL> | ||
<LI>Adjust trusted addresses for sensitive sites — these should be in a file, e.g., /etc/apache2/acl/trusted</li> | ||
<LI>Restart Apache (e.g., /etc/init.d/apache2 reload)</li> | ||
<LI>Nginx trusted addresses for sensitive sites — these should be in a file, e.g., /etc/nginx/acl/trusted</li> | ||
<LI>Restart Nginx (e.g., sudo systemctl restart nginx)</li> | ||
</ul> | ||
</li> | ||
<LI>MariaDB/MySQL GRANTs | ||
<UL> | ||
<LI>On master: grants-change.sh $change $current_IP_address slave (script can be found on ispltd.org)</li> | ||
<LI>On slaves: mysql -e 'stop slave; start slave; show slave status\G'</li> | ||
</ul> | ||
</li> | ||
<LI>Security settings in other applications, scripts, PHP code, etc.</li> | ||
<LI>Master DNS | ||
<UL> | ||
<LI>/etc/stapler/active/stapler.conf — change ournet entry for dynamic host(s) | ||
<LI>/etc/stapler/active/domains.primary — change any domains pointing to dynamic host(s) | ||
<LI>Run stapler to update master and push changes to slaves | ||
</ul> | ||
</li> | ||
<LI>Sendmail rules (e.g., allowed relays)</li> | ||
<LI>NTP servers | ||
<UL> | ||
<LI>Change $change to $current_IP_address in /etc/chrony/chrony.conf or /etc/ntp.conf</li> | ||
<LI>/etc/init.d/chronyd restart (or ntpd restart)</li> | ||
<LI>chronyc sources (to see if it is synchronised) (or use ntpq)</li> | ||
</ul> | ||
</li> | ||
</ul> | ||
<H3>Stapler output</h3> | ||
<PRE>$ ".$cmd."\n".$stapler_output."</pre><BR>"; | ||
} else { | ||
$msg .= "<SMALL>".__LINE__."</small> FAILURE writing the new dynamic file.<BR>"; | ||
} | ||
} | ||
} | ||
|
||
$msg .= " | ||
</body> | ||
</html> | ||
"; | ||
|
||
if($tmpf) fclose($tmpf); | ||
|
||
$msg64 = base64_encode($msg); | ||
$headers = "Content-Type: text/html"; | ||
|
||
$chg_msg = $change ? " DNS changed" : " check-in (no change)"; | ||
if($verbose || $change) { | ||
mail($mail_recipient, $_GET['host'].$chg_msg, $msg, $headers); | ||
} | ||
|
||
|
||
|
||
|
||
/* Find the element in an array that contains a string (i.e., a substring search). | ||
This is an enhancement of the array_search() function, which does an exact match. | ||
Pass $haystack array Data array | ||
$needle str Value to search for | ||
$strict bool Case-sensitive (TRUE) or not (FALSE) | ||
(default: TRUE if not specified) | ||
NB: I have kept haystack,needle order to be consistent with strpos(), although it is | ||
the opposite of how array_search() has them. | ||
Returns (fn) str Key to the element in the array, FALSE if not found. */ | ||
function array_find_element($haystack, $needle, $strict=TRUE) { | ||
global $msg; | ||
foreach($haystack as $key => $value) { | ||
$value = trim($value, "\n\r\0"); | ||
$is_match = ($strict) ? strpos($value, $needle) : stripos($value, $needle); | ||
if($is_match !== FALSE) return $key; #|Test for FALSE because zero is a valid result. | ||
} | ||
return FALSE; #|Not found | ||
} | ||
|
||
|
||
#__________________________________________ | ||
# Pass $msg str E-mail body being built above and below | ||
# $lines arr Lines of the 'dynamic' file | ||
# Returns (fn) bool FALSE if there was no change | ||
# str Old IP address if there was a change (which will evalute as TRUE) | ||
function check_dynamic(&$msg, &$lines) { | ||
global $dynamic_file, $current_IP_address; | ||
if(!file_exists($dynamic_file)) { | ||
$msg .= "<SMALL>".__LINE__."</small> File $dynamic_file does not exist.<BR>"; | ||
return FALSE; | ||
} | ||
foreach($lines as $key => $value) { | ||
$value = trim($value, "\n\r\0"); | ||
$lines[$key] = $value; | ||
} | ||
$ec = array_find_element($lines, $_GET["host"], FALSE); | ||
$change = FALSE; | ||
if($ec !== FALSE) { #|Key of zero is valid | ||
$components = explode("\t", $lines[$ec]); | ||
if($components[0] != $current_IP_address) { | ||
$new = sprintf("%s\t%s", $current_IP_address, $_GET["host"]); | ||
$msg .= "<SMALL>".__LINE__."</small> ".$_GET["host"]." changed from <U>".$components[0]."</u> to <U>".$current_IP_address."</u><BR><BR>"; | ||
$msg .= "Consider things that may need changing due to this:<BR><UL><LI>Firewalls</li><LI>Apache trusted address lists in /etc/apache2/vhosts.d/</li><LI>MariaDB/MySQL GRANTs (grants-change.sh ".$components[0]." ".$current_IP_address." <userName>)</li><LI>Security settings in other applications, scripts, PHP code, etc.</li><LI>ntp.conf or chrony.conf</li><LI>DNS named.conf</li><LI>Sendmail rules (e.g., allowed relays, access.db, sendmail.mc, sendmail.cf)</li></ul>"; | ||
$lines[$ec] = $new; | ||
$change = $components[0]; | ||
} else { | ||
$msg .= "No change.<BR>"; | ||
} | ||
} else { | ||
$msg .= "No line containing ".$_GET["host"]." was found in the $dynamic_file file.<BR><PRE>lines ".print_r($lines,true)."</pre>"; | ||
} | ||
return $change; | ||
} | ||
|
||
|
||
#__________________________________________ | ||
# Pass $msg str E-mail body being built above and below | ||
# $tmp res File handle of temporary file, or FALSE if unable to create it. | ||
# $lines arr Lines from the 'dynamic' file | ||
function rewrite_dynamic(&$msg, $tmpf, $lines) { | ||
global $dynamic_file, $current_IP_address; | ||
$bu = "/var/tmp/backup/".basename($dynamic_file); | ||
if(!copy($dynamic_file, $bu)) { | ||
$msg .= "<SMALL>".__LINE__."</small> Unable to create $bu. Will try /tmp/.<BR>"; | ||
$bu = "/tmp/".basename($dynamic_file); | ||
if(!copy($dynamic_file, $bu)) { | ||
$msg .= "<SMALL>".__LINE__."</small> Unable to create $bu. There will be no backup.<BR>"; | ||
} | ||
} | ||
rewind($tmpf); | ||
if(!$dynf = fopen($dynamic_file, "w")) { #|Overwrite the dynamic file | ||
$msg .= "<SMALL>".__LINE__."</small> Unable to open $dynamic_file for writing. Is it owned by Apache?<BR>"; | ||
return FALSE; | ||
} | ||
$msg .= "<SMALL>".__LINE__."</small> Opened $dyamic_file for writing.<BR>"; | ||
foreach($lines as $key => $value) { | ||
fwrite($dynf, $value."\n"); #|Write out a new temporary file, in case something changed | ||
$msg .= "<SMALL>".__LINE__."</small> Wrote $newline<BR>"; | ||
} | ||
fclose($dynf); | ||
return TRUE; | ||
} | ||
|
||
|
||
?> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# stapler.pl list of domain names (A Babudro) | ||
# vim:ts=8:sw=8: | ||
# Comments (#) and empty lines are ignored | ||
# | ||
# The only required field is the domain name; others are optional. | ||
# Place at least one TAB between fields. | ||
# Fields MUST be filled left to right. Key word 'none' is allowed. | ||
# e.g., to define 'Alt MX1' you MUST define 'Alt WebServer' first, | ||
# otherwise 'Alt MX1' will be interpreted as 'Alt WebServer'. | ||
# | ||
# Domain Name Alt WebServer Alt MX1 Alt MX2 Alt-whatever #1 Alt-whatever #2 | ||
# ----------------- ------------- ----------------------- ----------------------- ----------------------- ------------------ | ||
# normal.com | ||
# abnormal.com 100.200.1.2 mail 100.200.1.3 mail2 100.200.1.4 smtp 214.127.130.119 sql 1.2.3.4 | ||
# this-won't-work.ca mail 100.200.1.3 | ||
# this-will-work.ca none mail 100.200.1.3 none none ns1 100.101.102.103 | ||
# mydomain.com SPF "v=spf1 mx ip4:12.34.56.78 mx:mail.mydomain.com -all" | ||
# mydomain.com TXT "Some interesting comment. You can have Alt, SPF, TXT, and DKIM lines for a domain." | ||
# mydomain.com DKIM dkim._domainkey ( "v=DKIM1; k=rsa; " "whatever..." ) ; ----- DKIM key for whatever | ||
# --------------------------------------------------------------------------------- | ||
|
||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# stapler.pl list of secondary-hosted domain names (A Babudro) | ||
# vim: ts=8:sw=8: | ||
# Comments and empty lines are ignored | ||
# | ||
# The only required field is the domain name; others are optional. | ||
# Place at least one TAB between fields. | ||
# Fields MUST be filled left to right. Key word 'none' is allowed. | ||
# e.g., to define 'Alt MX1' you MUST define 'Alt WebServer' first, | ||
# otherwise 'Alt MX1' will be interpreted as 'Alt WebServer'. | ||
# | ||
# Domain Name Master NS Comment (optional) | ||
# ----------------- ------------- ------------------- | ||
# adomain.com 100.200.1.2 John Doe's domain (customer 12345) | ||
# --------------------------------------------------------------------------------- | ||
|
||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Nightly Cron definition to fetch the latest file of top-level DNS servers. | ||
|
||
#Mn Hr DoM Mo DoW command(s) | ||
#-- -- --- -- --- ---------------------------- | ||
00 00 * * Sun curl ftp://ftp.internic.net/domain/named.cache > /var/bind/root.cache | ||
|
Oops, something went wrong.