Last active
June 9, 2023 15:03
-
-
Save arcticlinux/ae3a1da2f30d106bdb17fcd9b02d424a to your computer and use it in GitHub Desktop.
Match an IP address or hostname against a cidr or list of cidrs, that can be used in .ssh/config
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
#!/usr/bin/env python3 | |
import ipaddress | |
import socket | |
import sys | |
import getopt | |
import re | |
def check_cidr(cidr, ip): | |
try: | |
network = ipaddress.IPv4Network(cidr) | |
ip_address = ipaddress.IPv4Address(ip) | |
if ip_address in network: | |
return True | |
else: | |
return False | |
except ipaddress.AddressValueError: | |
return False | |
def print_usage(): | |
usage = """Usage: matchcidr [-v] <ip_or_hostname> <cidr1> [cidr2 ...] | |
Options: | |
-v Enable verbose mode | |
Examples: | |
matchcidr.py -v hostname 172.31.0.0/20 | |
matchcidr.py hostname 172.31.64.0/20 | |
matchcidr.py 172.31.74.141 172.31.0.0/20 | |
matchcidr.py 172.31.74.141 172.31.64.0/20 | |
.ssh/config: | |
Match exec "matchcidr %h 172.31.0.0/20 172.31.16.0/20" | |
StrictHostKeyChecking no | |
UserKnownHostsFile /dev/null | |
LogLevel QUIET | |
""" | |
print(usage) | |
def print_verbose(cidr, ip, result): | |
print(f"Checking CIDR: {cidr} against IP: {ip} - Result: {result}") | |
def main(): | |
ip_or_hostname = "" | |
cidrs = [] | |
verbose = False | |
# Parse command-line options | |
try: | |
opts, args = getopt.getopt(sys.argv[1:], "v") | |
except getopt.GetoptError as err: | |
print(str(err)) | |
print_usage() | |
sys.exit(2) | |
for opt, _ in opts: | |
if opt == "-v": | |
verbose = True | |
if len(args) < 2: | |
print("Invalid arguments.") | |
print_usage() | |
sys.exit(2) | |
ip_or_hostname = args[0] | |
cidrs = args[1:] | |
# Get the IP address if the argument is a hostname | |
if not ip_or_hostname.replace(".", "").isdigit(): | |
try: | |
ip_address = socket.gethostbyname(ip_or_hostname) | |
ip_or_hostname = ip_address | |
except socket.gaierror as err: | |
print(f"Error: {str(err)}") | |
sys.exit(1) | |
# Iterate over each CIDR and check if the IP address matches | |
for cidr in cidrs: | |
cidr = cidr.strip(' ,') | |
if check_cidr(cidr, ip_or_hostname): | |
if verbose: | |
print_verbose(cidr, ip_or_hostname, "Match") | |
sys.exit(0) | |
if verbose: | |
for cidr in cidrs: | |
print_verbose(cidr.strip(), ip_or_hostname, "No Match") | |
sys.exit(1) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment