-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCheckStaticIP.py
172 lines (127 loc) · 6.53 KB
/
CheckStaticIP.py
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 python3
# Copyright (c) 2020 Stewart Loving-Gibbard
# https://github.com/StewLG/check_static_ip
# Version 1.2
'''
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import argparse
import sys
import string
import requests
import time
# The true/false result of every service checked. If True, the IP address matched the expected one.
AllResults = []
# Only error messages/problems retrieving values.
ErrorMessages = []
def SetupParser():
# Build parser for arguments
parser = argparse.ArgumentParser(description='Checks to make sure that external IP V4 address is still an expected IP address')
parser.add_argument('-eip', '--expectedip', required=True, type=str, help='Expected IPV4 address')
parser.add_argument('-d', '--debug', required=False, action='store_true', help='Display debugging information; run script this way and record result when asking for help.')
parser.add_argument('-t', '--timeout', required=False, type=int, help='Timeout in seconds. This is the maximum amount of time in seconds to wait for any particular IP address service. If set to 10 the check will wait up to 10 second per service. The default is an indefinite timeout.')
return parser;
def ExitIfNoArguments(parser):
# if no arguments, print out help
if len(sys.argv)==1:
parser.print_help(sys.stderr)
sys.exit(1)
# IP4Only
IPV4_CHECK_URL = "http://ip4only.me/api";
def GetIPAddress_IP4OnlyDotMe(timeoutInSeconds, shouldShowDebugInfo):
try:
if (shouldShowDebugInfo):
print (f"Fetching from {IPV4_CHECK_URL}")
response = requests.get(IPV4_CHECK_URL, timeout=timeoutInSeconds);
except:
# Site wasn't there, internet is totally down, etc.
return f"Error retrieving {IPV4_CHECK_URL}"
# Site isn't working properly, URL changed, etc.
if (response.status_code != requests.codes.ok):
return f"Error retrieving {IPV4_CHECK_URL}, status code: {response.status_code}"
ipAddressLine = response.text;
# We expect commas in the output from the web site
if ("," not in ipAddressLine):
return f"Got unparsable response {ipAddressLine} from {IPV4_CHECK_URL}"
ipAddress = ipAddressLine.split(',')[1];
return ipAddress;
# http://ipv4bot.whatismyipaddress.com/
WHAT_IS_MY_IP_ADDRESS_CHECK_URL = "http://ipv4bot.whatismyipaddress.com";
def GetIPAddress_WhatIsMyIPAddressDotCom(timeoutInSeconds, shouldShowDebugInfo):
try:
if (shouldShowDebugInfo):
print (f"Fetching from {WHAT_IS_MY_IP_ADDRESS_CHECK_URL}")
response = requests.get(WHAT_IS_MY_IP_ADDRESS_CHECK_URL, timeout=timeoutInSeconds);
except:
# Site wasn't there, internet is totally down, etc.
return f"Error retrieving {WHAT_IS_MY_IP_ADDRESS_CHECK_URL}"
# Site isn't working properly, URL changed, etc.
if (response.status_code != requests.codes.ok):
return f"Error retrieving {WHAT_IS_MY_IP_ADDRESS_CHECK_URL}, status code: {response.status_code}"
# This service is simple, no CSV or JSON - just the raw IP address
ipAddress = response.text;
return ipAddress;
# https://api.ipify.org
IPIFY_CHECK_URL = "https://api.ipify.org";
def GetIPAddress_IPify(timeoutInSeconds, shouldShowDebugInfo):
try:
if (shouldShowDebugInfo):
print (f"Fetching from {IPIFY_CHECK_URL}")
response = requests.get(IPIFY_CHECK_URL, timeout=timeoutInSeconds);
except:
# Site wasn't there, internet is totally down, etc.
return f"Error retrieving {IPIFY_CHECK_URL}"
# Site isn't working properly, URL changed, etc.
if (response.status_code != requests.codes.ok):
return f"Error retrieving {IPIFY_CHECK_URL}, status code: {response.status_code}"
# This service supports JSON etc, but the simple version with just the IP is fine.
ipAddress = response.text;
return ipAddress;
def AddResultsAndAnyErrors(expectedIP4Address, resultString):
currentResult = resultString == expectedIP4Address;
AllResults.append(currentResult);
if (not currentResult):
ErrorMessages.append(resultString);
def CheckAllExternalIPV4Providers(expectedIP4Address, timeoutInSeconds, shouldShowDebugInfo):
startTime = time.time()
AddResultsAndAnyErrors(expectedIP4Address, GetIPAddress_IP4OnlyDotMe(timeoutInSeconds, shouldShowDebugInfo))
AddResultsAndAnyErrors(expectedIP4Address, GetIPAddress_WhatIsMyIPAddressDotCom(timeoutInSeconds, shouldShowDebugInfo))
AddResultsAndAnyErrors(expectedIP4Address, GetIPAddress_IPify(timeoutInSeconds, shouldShowDebugInfo))
endTime = time.time();
elapsedTimeInSeconds = (endTime - startTime);
# Did at least one service match our expected IP address?
atLeastOnePositiveResult = any(AllResults);
# How many services did we check?
totalServicesChecked = len(AllResults);
# How many services succeeded?
totalServicesSucceeded = AllResults.count(True);
if (shouldShowDebugInfo):
print(f"AllResults: {AllResults}")
print(f"ErrorMessages: {ErrorMessages}")
if (atLeastOnePositiveResult):
print (f'OK - External IP address appears to be {expectedIP4Address} as expected, {totalServicesSucceeded}/{totalServicesChecked} IP address services succeeded. Elapsed time: {elapsedTimeInSeconds:.2f} seconds.')
sys.exit(0)
# No matching results? Indicate failure and print out errors for debugging.
if (not atLeastOnePositiveResult):
print (f'CRITICAL - Expected {expectedIP4Address}, but none matched. Got following mismatching addresses or errors from IP Address services: {ErrorMessages}. Elapsed time: {elapsedTimeInSeconds:.2f} seconds.');
sys.exit(2);
def main():
# Build parser for arguments
parser = SetupParser();
# Exit and show help if no arguments
ExitIfNoArguments(parser);
# Parse the arguments
args = parser.parse_args(sys.argv[1:])
# Check the static IPV4
CheckAllExternalIPV4Providers(args.expectedip, args.timeout, args.debug);
if __name__ == '__main__':
main()