mirror of
https://github.com/wahyd4/links.git
synced 2026-08-08 21:04:53 +10:00
59 lines
2.3 KiB
Python
59 lines
2.3 KiB
Python
import socket
|
|
import logging
|
|
from .base import Finding
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
CHECK_NAME = 'public_ports'
|
|
TIMEOUT = 3
|
|
|
|
PORT_INFO = {
|
|
22: ('warning', 'SSH', 'SSH exposed to the internet. Ensure key-only auth and restrict access.'),
|
|
23: ('critical', 'Telnet', 'Telnet (cleartext) is exposed to the internet. Disable immediately.'),
|
|
25: ('warning', 'SMTP', 'SMTP port exposed. Could be used for spam relay if misconfigured.'),
|
|
53: ('warning', 'DNS', 'DNS port open. Run the DNS resolver check to confirm if recursive queries are allowed.'),
|
|
80: ('info', 'HTTP', 'HTTP port open. Expected for public web services.'),
|
|
443: ('info', 'HTTPS', 'HTTPS port open. Expected for public web services.'),
|
|
3306: ('critical', 'MySQL', 'MySQL database port exposed to the internet. Restrict access immediately.'),
|
|
5432: ('critical', 'Postgres','PostgreSQL database port exposed to the internet. Restrict access immediately.'),
|
|
6379: ('critical', 'Redis', 'Redis port exposed to the internet. Redis has no auth by default — critical risk.'),
|
|
8080: ('warning', 'HTTP-alt','Alternate HTTP port 8080 is open. Verify this is intentional.'),
|
|
8443: ('warning', 'HTTPS-alt','Alternate HTTPS port 8443 is open. Verify this is intentional.'),
|
|
}
|
|
|
|
|
|
def _tcp_open(host: str, port: int) -> bool:
|
|
try:
|
|
with socket.create_connection((host, port), timeout=TIMEOUT):
|
|
return True
|
|
except (OSError, socket.timeout):
|
|
return False
|
|
|
|
|
|
def run(profile) -> list:
|
|
findings = []
|
|
host = profile.public_ip
|
|
raw = {'public_ip': host, 'open_ports': []}
|
|
|
|
for port, (severity, label, detail) in PORT_INFO.items():
|
|
if _tcp_open(host, port):
|
|
raw['open_ports'].append(port)
|
|
findings.append(Finding(
|
|
check_name=CHECK_NAME,
|
|
severity=severity,
|
|
title=f'Port {port} ({label}) open on public IP {host}',
|
|
detail=detail,
|
|
raw={'public_ip': host, 'port': port},
|
|
))
|
|
|
|
if not findings:
|
|
findings.append(Finding(
|
|
check_name=CHECK_NAME,
|
|
severity='ok',
|
|
title=f'No high-risk ports open on public IP {host}',
|
|
detail='All probed ports are closed or filtered.',
|
|
raw=raw,
|
|
))
|
|
|
|
return findings
|