Check Whether an IP Address Is Private in Python
Learn how to determine whether an IP address is private or public using Python and the ipaddress module. Complete guide with practical examples.
InSkillCoach
Check Whether an IP Address Is Private in Python
Private IP addresses are used in local networks and are not routable on the internet. Being able to tell a private IP address from a public one is an essential skill for many system administration tasks, network configuration work, and network application development.
Private IP Address Ranges
According to the RFC 1918 standard, the private IP address ranges are:
- Class A: 10.0.0.0 - 10.255.255.255 (10.0.0.0/8)
- Class B: 172.16.0.0 - 172.31.255.255 (172.16.0.0/12)
- Class C: 192.168.0.0 - 192.168.255.255 (192.168.0.0/16)
Fortunately, Python gives us a simple way to check whether an IP address falls within these ranges, thanks to the ipaddress module.
Method 1: Using the ipaddress Module (Recommended)
The ipaddress module has been part of Python’s standard library since version 3.3, which makes it the recommended method.
import ipaddress
def is_private_ip(ip_string):
"""
Checks whether an IP address is private.
Args:
ip_string (str): The IP address to check, as a string (e.g., '192.168.1.1')
Returns:
bool: True if the IP address is private, False otherwise
"""
try:
ip = ipaddress.ip_address(ip_string)
return ip.is_private
except ValueError:
# Error handling if the input is not a valid IP address
print(f"Erreur: {ip_string} n'est pas une adresse IP valide")
return False
# Usage examples
test_ips = [
'192.168.1.1', # Private (Class C)
'10.0.0.1', # Private (Class A)
'172.16.0.1', # Private (Class B)
'8.8.8.8', # Public (Google DNS)
'127.0.0.1', # Loopback (special)
'172.32.0.1', # Public (just outside the private range)
'169.254.1.1', # Link-local (special)
]
for ip in test_ips:
result = "privée" if is_private_ip(ip) else "publique"
print(f"{ip} est une adresse IP {result}")
Output:
192.168.1.1 est une adresse IP privée
10.0.0.1 est une adresse IP privée
172.16.0.1 est une adresse IP privée
8.8.8.8 est une adresse IP publique
127.0.0.1 est une adresse IP publique # Note: although special (loopback), it is not classified as private
172.32.0.1 est une adresse IP publique
169.254.1.1 est une adresse IP publique # Note: although special (link-local), it is not classified as private
Method 2: Manual Implementation
If you can’t use the ipaddress module for some reason, you can implement the check manually:
def is_private_ip_manual(ip_string):
"""
Manually checks whether an IP address is private.
Args:
ip_string (str): The IP address to check
Returns:
bool: True if the IP address is private, False otherwise
"""
try:
# Convert the IP address to a list of integers
octets = list(map(int, ip_string.split('.')))
if len(octets) != 4 or any(octet < 0 or octet > 255 for octet in octets):
raise ValueError("Format d'adresse IP invalide")
# Check the private IP address ranges
# Class A: 10.0.0.0 - 10.255.255.255
if octets[0] == 10:
return True
# Class B: 172.16.0.0 - 172.31.255.255
if octets[0] == 172 and 16 <= octets[1] <= 31:
return True
# Class C: 192.168.0.0 - 192.168.255.255
if octets[0] == 192 and octets[1] == 168:
return True
return False
except (ValueError, IndexError):
print(f"Erreur: {ip_string} n'est pas une adresse IP valide")
return False
Handling Special IP Addresses
The ipaddress module can also identify other types of special addresses:
import ipaddress
def check_ip_type(ip_string):
"""
Checks the type of an IP address (private, loopback, link-local, etc.)
Args:
ip_string (str): The IP address to check
Returns:
str: Description of the IP address type
"""
try:
ip = ipaddress.ip_address(ip_string)
if ip.is_private:
return "Adresse IP privée"
elif ip.is_loopback:
return "Adresse de loopback"
elif ip.is_link_local:
return "Adresse link-local"
elif ip.is_multicast:
return "Adresse multicast"
elif ip.is_reserved:
return "Adresse réservée"
elif ip.is_global:
return "Adresse IP publique (globale)"
else:
return "Autre type d'adresse"
except ValueError:
return "Adresse IP invalide"
# Usage examples with different addresses
special_ips = [
'192.168.1.1', # Private
'10.0.0.1', # Private
'127.0.0.1', # Loopback
'169.254.1.1', # Link-local
'224.0.0.1', # Multicast
'8.8.8.8', # Public (Google DNS)
'2001:db8::1', # IPv6 documentation
'fe80::1', # IPv6 link-local
]
for ip in special_ips:
print(f"{ip}: {check_ip_type(ip)}")
IPv6 Compatibility
The ipaddress module also handles IPv6 addresses:
import ipaddress
def is_private_ipv6(ip_string):
"""
Checks whether an IPv6 address is private.
Args:
ip_string (str): The IPv6 address to check
Returns:
bool: True if the IPv6 address is private, False otherwise
"""
try:
ip = ipaddress.ip_address(ip_string)
return ip.is_private
except ValueError:
print(f"Erreur: {ip_string} n'est pas une adresse IP valide")
return False
# IPv6 address examples
ipv6_addresses = [
'2001:db8::1', # Documentation address (non-routed)
'fe80::1', # Link-local
'fd00::1', # Unique Local Address (ULA) - the "private" equivalent in IPv6
'2001:4860:4860::8888', # Public (Google DNS)
]
for ip in ipv6_addresses:
result = "privée" if is_private_ipv6(ip) else "publique"
print(f"{ip} est une adresse IPv6 {result}")
Practical Use Cases
Here are a few practical use cases for this functionality:
- Traffic filtering in an application:
def process_connection(ip_address, data):
if is_private_ip(ip_address):
# Handling for internal connections
process_internal_connection(ip_address, data)
else:
# Handling for external connections
# Apply additional security measures
apply_security_measures(ip_address)
process_external_connection(ip_address, data)
- Contextual logging:
def log_access(ip_address, resource, action):
ip_type = "interne" if is_private_ip(ip_address) else "externe"
log_entry = f"{datetime.now()} - Accès {ip_type} depuis {ip_address} - {action} sur {resource}"
logging.info(log_entry)
- Integration with network monitoring tools:
def analyze_traffic_patterns(traffic_data):
internal_traffic = {}
external_traffic = {}
for entry in traffic_data:
ip = entry['source_ip']
if is_private_ip(ip):
if ip not in internal_traffic:
internal_traffic[ip] = 0
internal_traffic[ip] += entry['bytes']
else:
if ip not in external_traffic:
external_traffic[ip] = 0
external_traffic[ip] += entry['bytes']
return {
'internal_summary': internal_traffic,
'external_summary': external_traffic
}
Conclusion
Checking for private IP addresses is a common task in network programming. Python’s ipaddress module greatly simplifies this operation with its is_private property. For more complex cases, the module also offers other useful properties such as is_loopback, is_link_local, and more.
This functionality is particularly useful for:
- Developing secure network applications
- Configuring firewall rules
- Analyzing traffic logs
- Handling internal and external connections differently
For more information, see the official ipaddress module documentation.
About InSkillCoach
Training and technology expert
Coach specializing in advanced technologies and AI, backed by GNeurone Inc.
Certifications:
- AWS Certified Solutions Architect – Professional
- Google Cloud certifications
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Comments
Comments are powered by GitHub Discussions
Sign in with GitHub to join the discussion