-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathis-it-up.py
More file actions
executable file
·172 lines (139 loc) · 4.55 KB
/
is-it-up.py
File metadata and controls
executable file
·172 lines (139 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/env python
#
# is-it-up.py - verify the DNS entries for a wesite are still valid
# and as an added bonus, verify that the website is up
#
# Copyright (C) 2018 Michael Davies <michael@the-davies.net>
#
from __future__ import print_function
import csv
import dns.resolver
import getopt
import IPy
import os
import sys
import traceback
import urllib2
debug = False
def get_config_files():
return ["{}/.dns-hosts-to-check".format(os.path.expanduser(x))
for x in [".", "~"]]
def get_hosts_from_file(filename):
hosts = []
try:
with open(filename) as f:
# Hosts as in format <host1>,<host2>
csvfilereader = csv.reader(f, delimiter=',')
for row in csvfilereader:
hosts.append([row[0], row[1]])
return hosts
except IOError as err:
print("Error reading the file {0}: {1}".format(filename, err))
def get_hosts():
hosts = []
config_files = get_config_files()
for filename in config_files:
if os.path.isfile(filename):
hosts = get_hosts_from_file(filename)
if not hosts:
print("No hosts found")
return hosts
def get_ip_addresses(host, record_type):
answers = dns.resolver.query(host, record_type)
ips = []
for rdata in answers:
ips.append(str(rdata))
return sorted(ips)
def identify_host(host_or_ip):
result = None
try:
IPy.IP(host_or_ip)
result = [host_or_ip]
except ValueError:
result = get_ip_addresses(host_or_ip, 'A')
return result
def verify_ip_address_assignments(first, second):
if debug:
print("Verifying {} and {} point to the same servers: "
.format(first, second), end='')
# Everything is as it should be if all the IP addresses for 'first'
# are in the list of IP addresses for 'second'
first_answers = identify_host(first)
second_answers = identify_host(second)
failure = False
for ip in first_answers:
if ip not in second_answers:
failure = True
if failure:
if debug:
print("MISMATCH")
print("{:<40} IP addresses: {}".format(first, first_answers))
print("{:<40} IP addresses: {}".format(second, second_answers))
sys.exit(66)
else:
if debug:
print("AOK")
def get_url_nofollow(url):
try:
response = urllib2.urlopen(url)
code = response.getcode()
return code
except urllib2.HTTPError as e:
return e.code
except Exception:
print("*** Unexpected error")
print(traceback.format_exc())
return 0
def verify_website_up(url):
# Quick summary of HTTP return codes:
# 1xx Hold On
# 2xx Here you go
# 3xx Go Away
# 4xx You Stuffed Up
# 5xx I Stuffed Up
if debug:
print("Checking {} is up: ".format(url), end='')
code = get_url_nofollow(url)
if code in [200]:
interpretation = "AOK"
else:
interpretation = "ERROR"
if debug:
print("{} {}".format(code, interpretation))
else:
if interpretation == "ERROR":
print("Unexpected HTTP code retrieved from {}: {}"
.format(url, code))
valid_opts = ['help', 'verbose']
def exit_with_usage(code=1):
sys.stderr.write("Usage: {0} [{1}] public-hostname target-hostname\n"
.format(os.path.basename(sys.argv[0]),
'|'.join('--'+opt for opt in valid_opts)))
sys.exit(code)
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], '', valid_opts)
except getopt.error:
exit_with_usage()
opt_flags = [flag for (flag, val) in opts]
for opt in opt_flags:
if opt == '--verbose':
debug = True
elif opt == '--help':
exit_with_usage(code=0)
hosts = []
if len(sys.argv) < 3:
# Must have hosts defined in a file
hosts = get_hosts()
else:
# Must be command line options
hosts.append([args[0], args[1]])
for hostpair in hosts:
# First verify that the main website IP address matches
# the actual entry point website IP address
verify_ip_address_assignments(hostpair[0], hostpair[1])
# Now verify that we're getting a sensible HTTP return code
# Note: We don't want to test https connections, as we'll need
# to deal with self-signed certificates or Let's Encrypt, and we
# we just want basic connectivity, so we'll ignore this for now
verify_website_up("http://{}".format(hostpair[0]))