Improved version
This commit is contained in:
216
app.py
216
app.py
@@ -53,12 +53,6 @@ HTML_TEMPLATE = """<!doctype html>
|
||||
{% if ripe.holder %}
|
||||
<div class="ripe-item"><strong>Provider:</strong> {{ ripe.holder }}</div>
|
||||
{% endif %}
|
||||
{% if ripe.prefix %}
|
||||
<div class="ripe-item"><strong>Prefisso annunciato:</strong> {{ ripe.prefix }}</div>
|
||||
{% endif %}
|
||||
{% if ripe.asns %}
|
||||
<div class="ripe-item"><strong>ASN:</strong> {{ ripe.asns | join(', ') }}</div>
|
||||
{% endif %}
|
||||
{% if ripe.routing_status %}
|
||||
<div class="ripe-item"><strong>Routing Status:</strong> {{ ripe.routing_status }}</div>
|
||||
{% endif %}
|
||||
@@ -78,6 +72,26 @@ HTML_TEMPLATE = """<!doctype html>
|
||||
<div class="ripe-item"><strong>Abuse Contact:</strong> {{ ripe.abuse }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if ripe.netname %}
|
||||
<div class="ripe-item"><strong>Netname:</strong> {{ ripe.netname }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if ripe.org_name %}
|
||||
<div class="ripe-item"><strong>Organisation:</strong> {{ ripe.org_name }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if ripe.rir %}
|
||||
<div class="ripe-item"><strong>RIR:</strong> {{ ripe.rir }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if ripe.block %}
|
||||
<div class="ripe-item"><strong>IP Block:</strong> {{ ripe.block }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% if ripe.rir %}
|
||||
<div class="ripe-item"><strong>RIR:</strong> {{ ripe.rir }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="ripe-muted">Dati ottenuti tramite RIPEstat Data API.</div>
|
||||
{% else %}
|
||||
<div class="ripe-title">Informazioni RIPE</div>
|
||||
@@ -160,9 +174,9 @@ def get_client_ip():
|
||||
return request.remote_addr or "Sconosciuto"
|
||||
|
||||
|
||||
|
||||
def fetch_ripe_info(ip: str):
|
||||
"""Recupera informazioni RIPEstat estese per l'IP."""
|
||||
"""Recupera informazioni RIPEstat estese per l'IP, compatibili col template."""
|
||||
|
||||
info = {
|
||||
"prefix": None,
|
||||
"asns": [],
|
||||
@@ -171,76 +185,173 @@ def fetch_ripe_info(ip: str):
|
||||
"reverse_dns": None,
|
||||
"geoloc": None,
|
||||
"abuse": None,
|
||||
# campi extra che stai già usando in pagina
|
||||
"block": None,
|
||||
"rir": None,
|
||||
"country": None, # non usato ora in UI
|
||||
"country_whois": None, # usato in "Country (WHOIS)"
|
||||
"netname": None, # usato in "Netname"
|
||||
"org_name": None,
|
||||
"raw": {}, # solo per debug
|
||||
}
|
||||
|
||||
try:
|
||||
# 1. Network info (prefisso + ASN)
|
||||
ni = requests.get(
|
||||
# 0) PREFIX-OVERVIEW: blocco IP + RIR + stato announced/routed
|
||||
po_resp = requests.get(
|
||||
f"{RIPESTAT_BASE}/prefix-overview/data.json",
|
||||
params={"resource": ip},
|
||||
timeout=2,
|
||||
)
|
||||
po = po_resp.json().get("data", {})
|
||||
info["raw"]["prefix_overview"] = po
|
||||
|
||||
if po:
|
||||
# es: 77.43.64.0/18
|
||||
info["block"] = po.get("resource")
|
||||
# es: block.desc = "RIPE NCC (Status: ALLOCATED)"
|
||||
block = po.get("block") or {}
|
||||
desc = block.get("desc")
|
||||
if desc:
|
||||
# prendiamo la parte prima della parentesi
|
||||
info["rir"] = desc.split("(")[0].strip()
|
||||
|
||||
# announced / routed (bool)
|
||||
info["routing_status"] = None
|
||||
if po.get("announced") is not None:
|
||||
info["routing_status"] = "Announced" if po.get("announced") else "Not announced"
|
||||
|
||||
# prefix principale
|
||||
if not info["prefix"]:
|
||||
info["prefix"] = po.get("resource")
|
||||
|
||||
# 1) NETWORK-INFO: prefisso + ASNs
|
||||
ni_resp = requests.get(
|
||||
f"{RIPESTAT_BASE}/network-info/data.json",
|
||||
params={"resource": ip},
|
||||
timeout=2,
|
||||
).json().get("data", {})
|
||||
)
|
||||
ni = ni_resp.json().get("data", {})
|
||||
info["raw"]["network_info"] = ni
|
||||
|
||||
info["prefix"] = ni.get("prefix")
|
||||
asns = ni.get("asns") or []
|
||||
info["asns"] = [f"AS{a}" for a in asns]
|
||||
if ni:
|
||||
if not info["prefix"]:
|
||||
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(
|
||||
# 2) AS-OVERVIEW: holder/provider (es: "AS-IRIDEOS - Retelit Digital Services S.p.A.")
|
||||
if ni and ni.get("asns"):
|
||||
ao_resp = requests.get(
|
||||
f"{RIPESTAT_BASE}/as-overview/data.json",
|
||||
params={"resource": asns[0]},
|
||||
params={"resource": ni["asns"][0]},
|
||||
timeout=2,
|
||||
).json().get("data", {})
|
||||
info["holder"] = ao.get("holder")
|
||||
)
|
||||
ao = ao_resp.json().get("data", {})
|
||||
info["raw"]["as_overview"] = ao
|
||||
if ao:
|
||||
info["holder"] = ao.get("holder") or info["holder"]
|
||||
|
||||
# 3. Routing status / visibility
|
||||
rs = requests.get(
|
||||
# 3) ROUTING-STATUS: origin AS + visibilità
|
||||
rs_resp = requests.get(
|
||||
f"{RIPESTAT_BASE}/routing-status/data.json",
|
||||
params={"resource": ip},
|
||||
params={"resource": info["prefix"] or ip},
|
||||
timeout=2,
|
||||
).json().get("data", {})
|
||||
info["routing_status"] = rs.get("status")
|
||||
)
|
||||
rs = rs_resp.json().get("data", {})
|
||||
info["raw"]["routing_status"] = rs
|
||||
|
||||
# 4. Reverse DNS
|
||||
rd = requests.get(
|
||||
if rs:
|
||||
origins = rs.get("origins") or []
|
||||
origin_as = None
|
||||
if origins:
|
||||
origin_as = origins[0].get("origin")
|
||||
v4 = (rs.get("visibility") or {}).get("v4") or {}
|
||||
peers = v4.get("ris_peers_seeing")
|
||||
total = v4.get("total_ris_peers")
|
||||
|
||||
if origin_as and peers is not None and total is not None:
|
||||
info["routing_status"] = f"Origin AS{origin_as}, visibility {peers}/{total} peers"
|
||||
elif origin_as:
|
||||
info["routing_status"] = f"Origin AS{origin_as}"
|
||||
|
||||
# 4) REVERSE-DNS
|
||||
rd_resp = 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
|
||||
)
|
||||
rd = rd_resp.json().get("data", {}).get("result", [])
|
||||
info["raw"]["reverse_dns"] = rd
|
||||
if rd:
|
||||
info["reverse_dns"] = rd[0].get("name")
|
||||
|
||||
# 5. GeoLocation
|
||||
gl = requests.get(
|
||||
# 5) GEOLOC (usa located_resources → locations)
|
||||
gl_resp = 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"),
|
||||
}
|
||||
)
|
||||
gl = gl_resp.json().get("data", {})
|
||||
info["raw"]["geoloc"] = gl
|
||||
|
||||
# 6. Abuse Contact
|
||||
ac = requests.get(
|
||||
located_resources = gl.get("located_resources") or []
|
||||
if located_resources:
|
||||
first_res = located_resources[0]
|
||||
locs = first_res.get("locations") or []
|
||||
if locs:
|
||||
loc0 = locs[0]
|
||||
city = loc0.get("city")
|
||||
country_code = loc0.get("country")
|
||||
# flagsapi vuole il codice (es: IT)
|
||||
label = country_code
|
||||
if city and country_code:
|
||||
label = f"{city}, {country_code}"
|
||||
|
||||
info["geoloc"] = {
|
||||
"country": label,
|
||||
"code": country_code,
|
||||
}
|
||||
|
||||
# 6) ABUSE CONTACT (abuse_contacts, non emails)
|
||||
ac_resp = 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
|
||||
)
|
||||
ac = ac_resp.json().get("data", {})
|
||||
info["raw"]["abuse"] = ac
|
||||
|
||||
abuse_contacts = ac.get("abuse_contacts") or []
|
||||
if abuse_contacts:
|
||||
info["abuse"] = abuse_contacts[0]
|
||||
|
||||
# 7) WHOIS: netname, country (WHOIS), org / descr
|
||||
whois_resp = requests.get(
|
||||
f"{RIPESTAT_BASE}/whois/data.json",
|
||||
params={"resource": ip},
|
||||
timeout=3,
|
||||
)
|
||||
whois = whois_resp.json().get("data", {})
|
||||
info["raw"]["whois"] = whois
|
||||
|
||||
records = whois.get("records") or []
|
||||
for block in records:
|
||||
for entry in block:
|
||||
k = entry.get("key", "").lower()
|
||||
v = entry.get("value", "")
|
||||
|
||||
if k == "netname" and not info["netname"]:
|
||||
info["netname"] = v
|
||||
elif k == "country" and not info["country_whois"]:
|
||||
info["country_whois"] = v
|
||||
elif k in ("org-name", "organisation", "descr") and not info["org_name"]:
|
||||
info["org_name"] = v
|
||||
|
||||
except Exception:
|
||||
# In caso di errore lasciamo info parziali / vuote
|
||||
pass
|
||||
|
||||
return info
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
ip = get_client_ip()
|
||||
@@ -261,5 +372,16 @@ def debug():
|
||||
all_headers=dict(request.headers),
|
||||
)
|
||||
|
||||
@app.route("/ripe-debug")
|
||||
def ripe_debug():
|
||||
from flask import jsonify
|
||||
ip = get_client_ip()
|
||||
ripe_info = fetch_ripe_info(ip) if ip != "Sconosciuto" else None
|
||||
return jsonify({
|
||||
"ip": ip,
|
||||
"ripe": ripe_info,
|
||||
})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=8000)
|
||||
|
||||
Reference in New Issue
Block a user