Skip to content

Instantly share code, notes, and snippets.

@arcticlinux
Last active June 9, 2023 15:03
Show Gist options
  • Save arcticlinux/ae3a1da2f30d106bdb17fcd9b02d424a to your computer and use it in GitHub Desktop.
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
#!/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