from flask import Flask, request, render_template_string import requests from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1) RIPESTAT_BASE = "https://stat.ripe.net/data" HTML_TEMPLATE = """ SolidData – IP & RIPE Lookup
{% if show_logo %} {% endif %}
IP & RIPE Lookup

Il tuo IP pubblico è:

{{ ip }}
{% if ripe %}
Informazioni RIPE
{% if ripe.holder %}
Provider: {{ ripe.holder }}
{% endif %} {% if ripe.prefix %}
Prefisso annunciato: {{ ripe.prefix }}
{% endif %} {% if ripe.asns %}
ASN: {{ ripe.asns | join(', ') }}
{% endif %} {% if ripe.routing_status %}
Routing Status: {{ ripe.routing_status }}
{% endif %} {% if ripe.reverse_dns %}
Reverse DNS: {{ ripe.reverse_dns }}
{% endif %} {% if ripe.geoloc %}
GeoLocation: {% if ripe.geoloc.code %} {{ ripe.geoloc.code }} {% endif %} {{ ripe.geoloc.country }}
{% endif %} {% if ripe.abuse %}
Abuse Contact: {{ ripe.abuse }}
{% endif %}
Dati ottenuti tramite RIPEstat Data API.
{% else %}
Informazioni RIPE
Non è stato possibile recuperare i dettagli RIPE per questo indirizzo.
{% endif %}
""" import ipaddress from flask import Flask, request, render_template_string # ... def _is_private_ip(ip: str) -> bool: try: return ipaddress.ip_address(ip).is_private except ValueError: # se non è un IP valido, lo consideriamo "non utilizzabile" return True def get_client_ip(): """ Prova a determinare l'IP pubblico del client: - prende la lista da X-Forwarded-For - sceglie il primo IP NON privato (non 10.x/192.168/172.16/127.x ecc.) - fallback su X-Real-IP - fallback su request.remote_addr """ # 1) X-Forwarded-For: "client, proxy1, proxy2..." xff = request.headers.get("X-Forwarded-For", "") if xff: parts = [p.strip() for p in xff.split(",") if p.strip()] # cerco il primo IP pubblico nella lista for ip in parts: if not _is_private_ip(ip): return ip # se proprio non trovo nulla di pubblico, prendo il primo if parts: return parts[0] # 2) X-Real-IP xri = request.headers.get("X-Real-IP") if xri and not _is_private_ip(xri): return xri.strip() # 3) Fallback: remote_addr così com'è return request.remote_addr or "Sconosciuto" def fetch_ripe_info(ip: str): """Recupera informazioni RIPEstat estese per l'IP.""" info = { "prefix": None, "asns": [], "holder": None, "routing_status": None, "reverse_dns": None, "geoloc": None, "abuse": None, } try: # 1. Network info (prefisso + ASN) ni = requests.get( f"{RIPESTAT_BASE}/network-info/data.json", params={"resource": ip}, timeout=2, ).json().get("data", {}) info["prefix"] = ni.get("prefix") asns = ni.get("asns") or [] info["asns"] = [f"AS{a}" for a in asns] # 2. AS overview (holder/provider) if asns: ao = requests.get( f"{RIPESTAT_BASE}/as-overview/data.json", params={"resource": asns[0]}, timeout=2, ).json().get("data", {}) info["holder"] = ao.get("holder") # 3. Routing status / visibility rs = requests.get( f"{RIPESTAT_BASE}/routing-status/data.json", params={"resource": ip}, timeout=2, ).json().get("data", {}) info["routing_status"] = rs.get("status") # 4. Reverse DNS rd = requests.get( f"{RIPESTAT_BASE}/reverse-dns/data.json", params={"resource": ip}, timeout=2, ).json().get("data", {}).get("result", []) info["reverse_dns"] = rd[0].get("name") if rd else None # 5. GeoLocation gl = requests.get( f"{RIPESTAT_BASE}/geoloc/data.json", params={"resource": ip}, timeout=2, ).json().get("data", {}) country = None if gl.get("locations"): country = gl["locations"][0].get("country", {}) if country: info["geoloc"] = { "country": country.get("name"), "code": country.get("code"), } # 6. Abuse Contact ac = requests.get( f"{RIPESTAT_BASE}/abuse-contact-finder/data.json", params={"resource": ip}, timeout=2, ).json().get("data", {}) emails = ac.get("emails") or [] info["abuse"] = emails[0] if emails else None except Exception: # In caso di errore lasciamo info parziali / vuote pass return info @app.route("/") def index(): ip = get_client_ip() ripe_info = fetch_ripe_info(ip) if ip != "Sconosciuto" else None return render_template_string( HTML_TEMPLATE, ip=ip, ripe=ripe_info, show_logo=True, ) if __name__ == "__main__": app.run(host="0.0.0.0", port=8000)