Files

87 lines
2.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Random port generator that skips common / lesssecure ports.
"""
import random
import socket
# ------------------------------------------------------------
# 1. Build a set of excluded ports
# ------------------------------------------------------------
EXCLUDED_PORTS = {
# 01023 (wellknown)
*range(0, 1024),
# Common web / admin
80, 443, 8080, 8000, 5000, 5001,
# Common database / cache
3306, 5432, 6379, 27017, 11211, 11212,
# Common mail / DNS / SNMP
25, 110, 143, 53, 162, 389, 636, 995, 993,
# Remoteshell & file transfer
22, 23, 21, 3389, 5900, 5901, 5902,
# SMB / NetBIOS
139, 445,
# Dynamic “ephemeral” ports that are often abused
*range(49152, 49163), # 4915249162
5000, 5001, 5002, 5003, 5004, 5005,
6000, 6001, 6002, 6003,
}
# ------------------------------------------------------------
# 2. Helper to check whether a port is free on the local machine
# ------------------------------------------------------------
def is_port_in_use(port: int, host: str = "0.0.0.0") -> bool:
"""Return True if any socket is listening on `port`."""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(0.1)
try:
s.bind((host, port))
return False
except (OSError, socket.error):
return True
# ------------------------------------------------------------
# 3. Randomport generator
# ------------------------------------------------------------
def random_secure_port(
*,
min_port: int = 1024,
max_port: int = 65535,
max_tries: int = 1000,
check_in_use: bool = True,
) -> int:
"""
Return a random port number that is:
* >= min_port and <= max_port
* not in EXCLUDED_PORTS
* optionally not currently in use (if check_in_use=True)
Raises RuntimeError if it cannot find a suitable port after `max_tries`.
"""
rng = random.SystemRandom() # cryptographically stronger RNG
for _ in range(max_tries):
candidate = rng.randint(min_port, max_port)
if candidate in EXCLUDED_PORTS:
continue
if check_in_use and is_port_in_use(candidate):
continue
return candidate
raise RuntimeError(
f"Could not find an unused port after {max_tries} attempts."
)
# ------------------------------------------------------------
# 4. Example usage
# ------------------------------------------------------------
if __name__ == "__main__":
port = random_secure_port()
print(f"Generated secure random port: {port}")