
ioc2rpz è un luogo dove l'intelligence sulle minacce incontra il DNS.
ioc2rpz™: La soluzione di sicurezza DNS - ioc2rpz™ è un potente server DNS che trasforma gli indicatori di minaccia in feed Response Policy Zone (RPZ) utilizzabili. Automatizza il processo di aggiornamento, garantendo che la tua rete sia protetta dalle minacce più recenti, inclusi domini e indirizzi IP dannosi. Convertendo i feed degli IoC in RPZ, ioc2rpz™ funge da collegamento cruciale tra l'intelligence sulle minacce e la sicurezza DNS, compatibile con server DNS che supportano RPZ come ISC Bind o PowerDNS.
Il DNS è il piano di controllo di Internet. Di solito il DNS viene usato per il bene, ma:

ISC Bind è di fatto uno standard per i nameserver. Con l'introduzione delle Response Policy Zones in ISC BIND 9.8 è diventato un compito semplice monitorare e contenere il malware a livello DNS. RPZ è supportato su PowerDNS recursor 4.0.0 e versioni successive. Knot DNS supporta parzialmente RPZ.
Rispetto alle soluzioni di protezione di rete tradizionali, un server DNS può gestire milioni di indicatori senza impatto sulle prestazioni, ma non esisteva un modo automatizzato ed efficiente per mantenere le zone di policy di risposta sui server DNS primari.
Di solito gli indicatori di compromissione sono distribuiti in testo semplice ma in formati diversi e solo pochi fornitori di IoC li rendono disponibili tramite RPZ.
ioc2rpz™ è un server DNS personalizzato che converte automaticamente gli indicatori (es. FQDN dannosi, IP) da varie fonti in feed RPZ e li mantiene/aggiorna automaticamente. I feed possono essere distribuiti a qualsiasi server DNS open source e/o commerciale che supporti RPZ, es. ISC Bind, PowerDNS. Puoi eseguire il tuo server DNS con filtraggio RPZ su un router, desktop, server e persino Raspberry Pi. La memoria di sistema è l'unico limite.
Con ioc2rpz™ puoi definire i tuoi feed, azioni e prevenire comunicazioni indesiderate.
ioc2rpz™ trasforma i feed degli IoC in zone di policy di risposta (RPZ). Puoi mescolare i feed per generare un singolo RPZ o più RPZ. Domini e IP fidati possono essere inseriti nella whitelist. ioc2rpz™ supporta la scadenza degli indicatori e ricostruisce le zone di conseguenza.
La versione corrente supporta: file locali, file/richieste tramite http/https/ftp e script shell per accedere ad altri tipi di risorse. Puoi usare qualsiasi formato di file se riesci a scrivere una REGEX per estrarre gli indicatori e gli indicatori sono separati da newline o/and carriage return (/n, /r, /r/n).
ioc2rpz è costruito su Erlang/OTP con un albero di supervisione che garantisce tolleranza ai guasti e recupero automatico. Vedi docs/architecture.md per i dettagli completi.``` ioc2rpz_app (application) └── ioc2rpz_sup (supervisor) ├── ioc2rpz_db_sup — ETS table heir process ├── ioc2rpz_tcp_sup — TCP listener pool (5 workers) ├── ioc2rpz_udp_sup — UDP listener ├── ioc2rpz_tls_sup — TLS/DoT listener pool (5 workers) [if cert configured] └── ioc2rpz_rest_sup — Cowboy HTTPS (REST API + DoH) [if cert configured]
Moduli principali:
| Modulo | Responsabilità |
|--------|---------------|
| `ioc2rpz.erl` | Worker DNS TCP/TLS — accetta, analizza, convalida, risponde |
| `ioc2rpz_udp.erl` | Listener DNS UDP — query SOA |
| `ioc2rpz_conn.erl` | Recupero fonti IOC (HTTP/HTTPS/file/shell) |
| `ioc2rpz_db.erl` | Cache di zona e pacchetti basata su ETS |
| `ioc2rpz_sup.erl` | Supervisore principale, caricamento configurazione, scheduling zone |
| `ioc2rpz_rest.erl` | API REST di gestione (Cowboy) |
| `ioc2rpz_doh.erl` | Gestore DNS-over-HTTPS |
## Come usare ioc2rpz™
Puoi usare ioc2rpz™ con qualsiasi server DNS che supporti le Response Policy Zones, ad esempio versioni recenti di ISC BIND, PowerDNS e qualsiasi server DNS commerciale basato su questi prodotti (es. Infoblox, Blue Cat, Efficient IP). Un file di configurazione di esempio per BIND (named.conf) è fornito nella cartella cfg.
<p align="center"><a href="http://www.youtube.com/watch?feature=player_embedded&v=bvhyMFa_mBM" target="_blank"><img src="https://raw.githubusercontent.com/Homas/ioc2rpz/master/ioc2rpz_demo.png"></a></p>
## Interfaccia web di ioc2rpz™
[ioc2rpz.gui](https://github.com/Homas/ioc2rpz.gui) è un'interfaccia web di gestione sviluppata come progetto separato. Non è necessaria per eseguire ioc2rpz™.
## Supporto dei protocolli
ioc2rpz™ ascolta su più protocolli di trasporto. Tutti i trasporti condividono la stessa pipeline di elaborazione delle query: limitazione della frequenza, validazione TSIG, ricerca in zona e generazione della risposta. Consulta [docs/protocols.md](https://github.com/homas/ioc2rpz/blob/master/docs/protocols.md) per la documentazione completa dei protocolli.
### Riepilogo porte
| Porta | Protocollo | Servizio | Condizione |
|------|----------|---------|-----------|
| 53 | UDP | Query DNS (solo SOA) | Sempre |
| 53 | TCP | Query DNS, trasferimenti di zona AXFR/IXFR, gestione | Sempre |
| 853 | TCP+TLS | DoT — come TCP ma crittografato | Richiede configurazione `cert` |
| 443/8443 | TCP+TLS | DoH (`/dns-query`) e API REST | Richiede configurazione `cert` |
### UDP (Porta 53)
UDP viene utilizzato per query DNS leggere, principalmente ricerche SOA. Le risposte superiori a 512 byte (o alla dimensione del buffer annunciata da EDNS0) impostano il bit TC (troncamento) secondo RFC 1035 §4.2.1, spingendo i client a riprovare su TCP. I comandi di gestione non sono supportati su UDP.```bash
dig @127.0.0.1 zone.ioc2rpz SOA -y hmac-sha256:keyname:base64key
TCP gestisce i trasferimenti di zona (AXFR/IXFR), le query SOA e i comandi di gestione. Un pool di 5 worker di accettazione pre-generati gestisce le connessioni in arrivo.```bash
dig @127.0.0.1 zone.ioc2rpz AXFR +tcp -y hmac-sha256:keyname:base64key
dig @127.0.0.1 zone.ioc2rpz IXFR=12345 +tcp -y hmac-sha256:keyname:base64key
### DNS over TLS / DoT (Porta 853)
ioc2rpz™ supporta la distribuzione RPZ su DoT. Il listener TLS si avvia automaticamente sulla porta 853 quando un record `cert` è presente nella configurazione. DoT supporta le stesse operazioni di TCP (AXFR, IXFR, SOA, gestione).
- Versioni TLS supportate: 1.2 e 1.3 (`?TLSVersion = 'tlsv1.2-1.3'`)
- Riutilizzo della connessione supportato secondo RFC 7858 §3.4 (più query per sessione TLS, timeout di inattività di 30 secondi)
- Il PIN TLS non è supportato
- I messaggi DNS NOTIFY vengono inviati non crittografati (UDP in chiaro)
- I certificati si aggiornano automaticamente quando i file vengono sostituiti su disco (fino a ~2 minuti di ritardo a causa della cache SSL di Erlang)
Per la configurazione dei certificati, vedere [Certificati](#certificate-setup).```bash
# SOA query over DoT
kdig @127.0.0.1 -p 853 zone.ioc2rpz SOA +tls -y hmac-sha256:keyname:base64key
# AXFR over DoT
dig @127.0.0.1 -p 853 zone.ioc2rpz AXFR +tls +tcp -y hmac-sha256:keyname:base64key
DoH fornisce risoluzione DNS su HTTPS tramite l'endpoint /dns-query. Metodi supportati:
?dns=Content-Type: application/dns-message (max 4096 byte; payload più grandi ricevono HTTP 413)Le risposte usano Content-Type: application/dns-message. DoH trasporta il messaggio DNS completo in formato wire e viene elaborato attraverso lo stesso percorso di Do53/DoT, quindi eredita la stessa autenticazione TSIG; i trasferimenti di zona (AXFR/IXFR) rimangono solo TCP e non sono serviti su DoH.```bash
curl -H "Accept: application/dns-message"
"https://127.0.0.1:443/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB" -k
curl -X POST -H "Content-Type: application/dns-message"
--data-binary @dns_query.bin "https://127.0.0.1:443/dns-query" -k
### Limitazione del tasso
Le query DNS sono limitate nel tasso utilizzando una chiave intelligente (ibrida) in modo che i client legittimi multi-zona non vengano penalizzati mentre viene bloccato l'abuso di variazione del nome della query:
- **Zona provisionata + QTYPE supportato** (`SOA`/`AXFR`/`IXFR`, classe `IN`) e **comandi di gestione riconosciuti** (classe `CHAOS`/`TXT`) sono tracciati per `{client_IP, query_name, query_type}` — quindi un secondario che interroga/trasferisce diverse zone (ad es. `rpz1`, `rpz2`, `rpz3`) più la gestione da un singolo IP viene contato indipendentemente per zona+tipo.
- **Tutto il resto** (zona sconosciuta/non provisionata, tipo di query non supportato, classe errata o nome di gestione non riconosciuto) viene aggregato per `{client_IP}`, così un attaccante non può bypassare il limite variando il nome della query.
Quando il limite viene superato, il server restituisce una risposta DNS `REFUSED`.
| Parametro | Default | Macro |
|-----------|---------|-------|
| Finestra | 10 secondi | `?RATE_LIMIT_WINDOW` (10000 ms) |
| Massimo richieste per finestra (granulare: zona+tipo noto / gestione) | 1 | `?MAX_REQUESTS_PER_WINDOW` |
| Massimo richieste per finestra (aggregato: zona sconosciuta / tipo non supportato) | 1 | `?MAX_UNKNOWN_REQUESTS_PER_WINDOW` |
La limitazione del tasso si applica a tutti i trasporti delle query DNS (UDP, TCP, TLS, DoH). La finestra e la soglia sono configurabili tramite macro in `include/ioc2rpz.hrl`.
### NOTIFICA DNS
Dopo un aggiornamento di zona (AXFR o IXFR), ioc2rpz™ invia messaggi di NOTIFICA DNS ([RFC 1996](https://tools.ietf.org/html/rfc1996)) su UDP agli indirizzi IP configurati in `NotifyList` della RPZ. Questo induce i server DNS secondari a controllare il seriale SOA della zona e ad avviare un trasferimento se il seriale è cambiato.```erlang
%% NotifyList in RPZ config — last field before whitelists
{rpz, {"zone.ioc2rpz", ..., ["source1"], ["10.0.0.1", "10.0.0.2"], []}}.
Il modo più semplice per implementare il servizio è utilizzare i container Docker sul Docker Hub. Guida alla distribuzione su Docker la puoi trovare nel wiki di ioc2rpz™.
ioc2rpz™ è disponibile sul Docker Hub. Basta cercare ioc2rpz™. Prerequisiti:
where /home/ioc2rpz/cfg, /home/ioc2rpz/db directories on a host system.
You can pass a custom configuration file name via``-e`` parameter. E.g. ``-e CONF=./cfg/ioc2rpz2.conf``
## Variabili d'Ambiente
Le seguenti variabili d'ambiente sono utilizzate da ioc2rpz™, principalmente rilevanti per distribuzioni Docker. Sono definite in `config/sys.config.src` e `config/vm.args`.
| Variabile | Default | Descrizione |
|----------|---------|-------------|
| `IPv4` | — | Indirizzo di bind IPv4 |
| `IPv6` | — | Indirizzo di bind IPv6 |
| `CONF` | — | Percorso del file di configurazione (ad es. `./cfg/ioc2rpz.conf`) |
| `DB` | `/opt/ioc2rpz/db` | Directory del database per la persistenza ETS |
| `CD` | `/opt/ioc2rpz` | Directory di lavoro |
| `NODE_NAME` | `ioc2rpz` | Nome breve del nodo Erlang |
| `IO2Cookie` | `ioc2rpz` | Cookie distribuito di Erlang |
Passa le variabili d'ambiente a Docker con `-e`:```bash
docker run -d --name ioc2rpz -e CONF=./cfg/custom.conf -e NODE_NAME=mynode ...
Puoi distribuire ioc2rpz™ e ioc2rpz.gui usando docker compose. Il file canonico docker-compose.yml si trova nel repository ioc2rpz.dc.
Di seguito è riportato un esempio di docker-compose.yml che mostra ioc2rpz con l'interfaccia web e un sidecar certbot di Let's Encrypt:```yaml
version: "3.8"
services:
ioc2rpz:
image: pvmdel/ioc2rpz
container_name: ioc2rpz
restart: always
logging:
driver: syslog
ports:
- "53:53/tcp"
- "53:53/udp"
- "853:853/tcp"
- "8443:8443/tcp"
volumes:
- ./cfg:/opt/ioc2rpz/cfg
- ./db:/opt/ioc2rpz/db
- letsencrypt-certs:/opt/ioc2rpz/ssl:ro
ioc2rpz-gui: image: pvmdel/ioc2rpz.gui container_name: ioc2rpz-gui restart: always ports: - "443:443" depends_on: - ioc2rpz
certbot: image: certbot/certbot container_name: certbot volumes: - letsencrypt-certs:/etc/letsencrypt - letsencrypt-www:/var/www/certbot entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --quiet; sleep 12h; done'"
volumes: letsencrypt-certs: letsencrypt-www:
Aggiorna il tuo `ioc2rpz.conf` per fare riferimento al percorso del certificato montato:```erlang
{cert, {"ssl/live/ns1.rpz-proxy.com/fullchain.pem", "ssl/live/ns1.rpz-proxy.com/privkey.pem", ""}}.
Puoi eseguire ioc2rpz™ e ioc2rpz.gui su AWS. Per implementazioni relativamente piccole (diverse centinaia di migliaia di indicatori) anche il livello gratuito è sufficiente. Il video seguente mostra come configurare ioc2rpz™ e ioc2rpz.gui su AWS utilizzando ECS.
I certificati TLS sono necessari per DoT (porta 853), REST API (porta 8443) e DoH. Lo stesso certificato viene utilizzato per tutti i servizi TLS. Vedi docs/deployment.md per tutti i dettagli.
openssl req -x509 -newkey rsa:2048 -keyout cfg/ioc2rpz_dot.key
-out cfg/ioc2rpz_dot.crt -days 365 -nodes -subj "/CN=ioc2rpz"
### Let's Encrypt (Produzione)```bash
# Obtain certificate
sudo certbot certonly --standalone -d ns1.rpz-proxy.com
# Copy to ioc2rpz cfg directory
cp /etc/letsencrypt/live/ns1.rpz-proxy.com/fullchain.pem cfg/ioc2rpz_dot.crt
cp /etc/letsencrypt/live/ns1.rpz-proxy.com/privkey.pem cfg/ioc2rpz_dot.key
0 3 * * * root certbot renew --quiet --deploy-hook "cp /etc/letsencrypt/live/ns1.rpz-proxy.com/fullchain.pem /opt/ioc2rpz/cfg/ioc2rpz_dot.crt && cp /etc/letsencrypt/live/ns1.rpz-proxy.com/privkey.pem /opt/ioc2rpz/cfg/ioc2rpz_dot.key"
I certificati vengono anche ricaricati esplicitamente durante un ricaricamento della configurazione (`ioc2rpz-reload-cfg`): quando ioc2rpz rileva che i file dei certificati sono cambiati, riavvia immediatamente i listener TLS con il nuovo certificato, invece di attendere circa 2 minuti dalla cache SSL di Erlang. Aggiungi un passaggio `ioc2rpz-reload-cfg` al tuo hook di rinnovo per applicare i nuovi certificati senza tempi di inattività.
### Montaggio dei Volumi Docker
Quando si esegue in Docker, monta la directory dei certificati dall'host:```bash
docker run -d --name ioc2rpz \
--mount type=bind,source=/etc/letsencrypt/live/ns1.rpz-proxy.com,target=/opt/ioc2rpz/ssl,readonly \
...
Riferimento in ioc2rpz.conf:```erlang
{cert, {"ssl/fullchain.pem", "ssl/privkey.pem", ""}}.
Erlang rileva automaticamente i file dei certificati sostituiti entro ~2 minuti. I certificati vengono anche ricaricati esplicitamente durante il ricaricamento della configurazione (`ioc2rpz-reload-cfg`). Non lasciare che i certificati scadano — rinnovali prima della scadenza per un servizio ininterrotto.
## Compilare dai Sorgenti
> **Nota:** La compilazione dai sorgenti è intesa per **sviluppo e test**. Per la produzione, **Docker è il metodo di distribuzione consigliato** — vedere [Docker Compose](#docker-compose) e il repository [ioc2rpz.dc](https://github.com/Homas/ioc2rpz.dc).
### Prerequisiti
- **Erlang/OTP 24 o successivo** (`erl -version` per verificare) e un [rebar3](https://www.rebar3.org) corrispondente.
- Una toolchain C (per compilare le dipendenze) e `git`.
### Compilare ed Eseguire```bash
# 1. Clone the repository
git clone https://github.com/Homas/ioc2rpz.git
cd ioc2rpz
# 2. Build a release
rebar3 release
# 3. Edit the configuration (see the minimal example below)
$EDITOR cfg/ioc2rpz.conf
# 4. Start the server (foreground console, or 'start' for background)
_build/default/rel/ioc2rpz/bin/ioc2rpz console
# or: _build/default/rel/ioc2rpz/bin/ioc2rpz start
Per impostazione predefinita ioc2rpz™ legge la sua configurazione da ./cfg/ioc2rpz.conf, ascolta su tutte le interfacce di rete e scrive il backup del suo database in ./db. Le impostazioni predefinite in fase di compilazione (porte, percorsi, timer) si trovano in include/ioc2rpz.hrl.
Una configurazione minima cfg/ioc2rpz.conf con una chiave TSIG, un'origine file e una zona RPZ:```erlang
%% Server NS record, admin mailbox, management key(s), and management ACL
{srv,{"ns1.example.com","hostmaster.example.com",["mgmtkey"],["127.0.0.1","::1"]}}.
%% A TSIG key (name, algorithm, base64 secret) used for management / zone transfers {key,{"mgmtkey","sha256","5Yvt70eJnf95+LJeI8H3TgKGeVparmMB7udA0pv/JRE="}}.
%% An IOC source: a local file parsed as a full (AXFR) feed of domains {source,{"sample","file:cfg/small_ioc.txt","[:AXFR:]","^([0-9A-Za-z.-]+\.[0-9A-Za-z.-]+)$","",0,0,0,"mixed",true}}.
%% An RPZ zone built from the source, served with the nxdomain action {rpz,{"rpz.example.com",86400,3600,2592000,7200,"true","true","nxdomain",["mgmtkey"],"mixed",604800,86400,["sample"],[],[]}}.
Vedi [docs/configuration.md](https://github.com/homas/ioc2rpz/blob/master/docs/configuration.md) per il riferimento autorevole campo per campo (layout della tupla source/RPZ, timer SOA, gruppi di chiavi, certificati, ecc.). Per abilitare DoT (porta 853), DoH e l'API REST HTTPS, aggiungi una voce `{cert,{...}}` — vedi [Impostazione del certificato](#certificate-setup).
### Shell di sviluppo (solo sviluppo/test)
I seguenti comandi sono per lo sviluppo e il test locali — non per uso in produzione:```bash
# Compile only (no release)
rebar3 compile
# Run the EUnit test suite
rebar3 eunit
# Run tests for a single module
rebar3 eunit --module=ioc2rpz_fun
# Start an interactive shell with the application and all deps loaded
rebar3 shell
In rebar3 shell puoi esercitare il sistema in esecuzione direttamente, per esempio:```erlang
%% Inspect the listener pools and ETS tables
supervisor:which_children(ioc2rpz_sup).
ets:info(cfg_table, size).
ets:info(rpz_hotcache_table, size).
%% Trigger a configuration reload / forced zone update ioc2rpz_sup:reload_config3(reload). ioc2rpz_sup:update_all_zones(true).
## Gestione di ioc2rpz™
### tramite DNS
ioc2rpz™ supporta la gestione tramite DNS/TCP o DoT. Si consiglia di utilizzare DoT o l'API REST su DNS/TCP. La versione attuale di ioc2rpz™ non supporta un IP/interfaccia di gestione separato. In ogni caso, è altamente consigliato creare una chiave TSIG designata (o più chiavi) che verrà utilizzata solo per la gestione. È possibile disattivare la gestione tramite DNS.
Azioni supportate:
- Stato corrente di ioc2rpz™. Richiesta ``ioc2rpz-status``, classe ``CHAOS``, record ``TXT``. Ad esempio:```
dig +tcp -y dnsmkey_1:ayVnL+h2QKMszRVohrngagcEuIpN3RkecXKdwSa5WsHD5N4Y5R3NUMGM W8sIGv36gPkAtWtgarqKzN9tmHqEnA== @127.0.0.1 ioc2rpz-status TXT -c CHAOS
ioc2rpz-reload-cfg, RR Class CHAOS, RR Type TXTioc2rpz-update-tkeys, RR Class CHAOS, RR Type TXTioc2rpz-update-all-rpz, RR Class CHAOS, RR Type TXTzone_name, RR Class CHAOS, RR Type TXT. Ad es. l'aggiornamento completo di dga.ioc2rpz può essere invocato da:```
dig +tcp -y dnsmkey_1:ayVnL+h2QKMszRVohrngagcEuIpN3RkecXKdwSa5WsHD5N4Y5R3NUMGM W8sIGv36gPkAtWtgarqKzN9tmHqEnA== @127.0.0.1 dga.ioc2rpz TXT -c CHAOS- Arresta ioc2rpz™. Nome RR ``ioc2rpz-terminate``, Classe RR ``CHAOS``, Tipo RR ``TXT``
- Richiedi una zona di esempio. Nome RR ``sample-zone.ioc2rpz``, Classe RR ``IN``, Tipo RR ``AXFR``
### tramite REST
L'API REST (porta 8443/tcp) è l'interfaccia di gestione preferita. Per motivi di sicurezza tutto il traffico di gestione deve essere criptato e l'API REST non viene avviata se non è presente un certificato SSL. Tutti gli endpoint accettano sia il metodo GET che POST.
L'autenticazione HTTP di base viene utilizzata per autenticare le richieste. Le chiavi TSIG di gestione vengono utilizzate per l'autenticazione delle richieste. Il nome di una chiave TSIG viene utilizzato come nome utente HTTP e la chiave TSIG come password. L'accesso all'API REST è limitato con l'ACL definito nel record `srv`.
Il segmento della versione dell'API supporta sia `v1` che `v1.0` (ad es., `/api/v1/stats/serv` o `/api/v1.0/stats/serv`).
L'API REST supporta l'output JSON (predefinito) e testo semplice in base all'intestazione `Accept`:
- `application/json` — output JSON (predefinito)
- `text/plain` — output in testo semplice```bash
# Example: plain text output
curl -u "keyname:base64key==" -k -H "Accept: text/plain" https://127.0.0.1:8443/api/v1/mgmt/update_tkeys
Le risposte testuali utilizzano il formato:``` status: ok msg: TSIG keys were updated
#### Parametri del percorso
| Parameter | Description |
|-----------|-------------|
| `:rpz_name` | nome della zona RPZ (es. `dga.ioc2rpz`) |
| `:source_name` | nome della sorgente IOC (es. `sample_fqdn`) |
| `:ioc` | Indicatore da cercare (FQDN o IP, es. `baddomain.com`) |
#### Endpoint delle statistiche
`/api/v1/stats/serv` — Statistiche del server (nome del nodo, regole totali, utilizzo memoria)```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/stats/serv
{
"srv": {
"node_name": "ioc2rpz@hostname",
"srv_total_rules": 15000,
"hot_cache_mem": "12.5 Mb",
"axfr_table_mem": "45.2 Mb",
"ixfr_table_mem": "8.1 Mb"
},
"rpz": [...],
"sources": [...]
}
/api/v1/stats/rpz — Statistiche della zona RPZ```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/stats/rpz
```json
{
"rpz": [
{
"name": "malware.ioc2rpz",
"status": "ready",
"rule_count": 5000,
"ioc_count": 4500,
"serial": 1709000000,
"serial_ixfr": 1708990000,
"update_time": 1709000000,
"ixfr_update_time": 1708995000,
"ixfr_nz_update_time": 1708995000
}
]
}
Il campo status (ready, updating, forceAXFR, notready) indica se i conteggi/seriali riportati sono correnti; quando updating o forceAXFR riflettono l'ultimo aggiornamento completato. I conteggi e i seriali vengono preservati attraverso un ricaricamento della configurazione anziché essere azzerati.
/api/v1/stats/source — Statistiche della sorgente```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/stats/source
```json
{
"sources": [
{"name": "sample_fqdn", "ioc_count": 150}
]
}
/api/v1/mgmt/reload_cfg — Ricarica il file di configurazione```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/mgmt/reload_cfg
Successo: `{"status":"ok","msg":"Configuration reloaded"}`
Errore (HTTP 520): `{"status":"error","msg":"Configuration reload error"}`
`/api/v1/mgmt/update_tkeys` — Ricarica le chiavi TSIG dalla configurazione```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/mgmt/update_tkeys
Success: {"status":"ok","msg":"TSIG keys were updated"}
Error (HTTP 520): {"status":"error","msg":"TSIG keys update error"}
/api/v1/mgmt/terminate — Arresto graduale del server```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/mgmt/terminate
Successo: `{"status":"ok","msg":"Terminating"}`
#### Endpoint di aggiornamento delle zone
`/api/v1/update/all_rpz` — Forza il refresh completo di tutte le zone RPZ```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/update/all_rpz
Success: {"status":"ok","msg":"All RPZ zones will be updated"}
/api/v1/update/:rpz_name — Forza l'aggiornamento completo di una zona specifica```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/update/dga.ioc2rpz
Successo: `{"status":"ok","msg":"RPZ dga.ioc2rpz will be updated"}`
Errore (HTTP 520): `{"status":"error","msg":"RPZ dga.ioc2rpz not found"}`
#### Endpoint di Gestione Cache
`/api/v1/cache/sources/clear/all` — Rimuovere tutte le sorgenti dalla hot cache```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/cache/sources/clear/all
Success: {"status":"ok","msg":"All sources were removed from the hotcache"}
/api/v1/cache/sources/clear/:source_name — Rimuovi una sorgente specifica dalla hot cache```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/cache/sources/clear/sample_fqdn
Successo: `{"status":"ok","msg":"sample_fqdn source was removed from the hot cache"}`
`/api/v1/cache/sources/load/all` — Ricarica tutte le sorgenti nella cache calda```bash
curl -u "keyname:base64key==" -k https://127.0.0.1:8443/api/v1/cache/sources/load/all
Success: {"status":"ok","msg":"All sources will loaded to the hot cache"}
/api/v1/feed/:rpz_name — Ottieni indicatori da un feed RPZ
Parametro query: ?type=fqdn|ip|both (default: both)```bash
curl -u "keyname:base64key==" -k "https://127.0.0.1:8443/api/v1/feed/malware.ioc2rpz?type=fqdn"
Successo:```json
{
"status": "ok",
"rpz": "malware.ioc2rpz",
"iocs": ["baddomain.com", "evil.example.org"]
}
Errore (HTTP 520): {"status":"error","msg":"RPZ malware.ioc2rpz not found"}
/api/v1/ioc/:ioc — Controlla se un indicatore è bloccato da qualsiasi feed RPZ
Parametro della query: ?tkey=keyname — limita la ricerca alle zone accessibili da quella chiave (opzionale)```bash
curl -u "keyname:base64key==" -k "https://127.0.0.1:8443/api/v1/ioc/baddomain.com?tkey=dnsproxykey_1"
Successo:```json
{
"ioc": "baddomain.com",
"tkey": "dnsproxykey_1",
"data": [
{
"ioc": "baddomain.com",
"feeds": [
{
"feed": "malware.ioc2rpz",
"wildcard": "true",
"type": "fqdn",
"rpz_serial": 1709000000,
"ioc_expiration": 0,
"sources": ["abuse-ch", "internal-list"]
}
]
}
]
}
Errore: {"status":"error", "ioc": "nonexistent.com"}
Il campo additivo sources elenca i nomi delle fonti contribuenti per ogni feed quando il tracciamento delle fonti è abilitato; è null quando il tracciamento è disabilitato o l'attribuzione è sconosciuta. Vedi Attribuzione delle fonti IOC per configurazione e semantica.
Qualsiasi percorso non riconosciuto restituisce HTTP 200 con:```json {"status":"error","msg":"Unsupported request"}
## Monitoraggio e Controlli di Integrità
### Statistiche API REST```bash
# Server statistics
curl -u "keyname:key==" -k https://127.0.0.1:8443/api/v1/stats/serv
# RPZ zone statistics (indicator counts, serials, update times)
curl -u "keyname:key==" -k https://127.0.0.1:8443/api/v1/stats/rpz
# Source statistics
curl -u "keyname:key==" -k https://127.0.0.1:8443/api/v1/stats/source
Se si esegue in una shell interattiva o si è collegati a un nodo in esecuzione:```erlang %% Check supervisor children supervisor:which_children(ioc2rpz_sup). supervisor:count_children(ioc2rpz_tls_sup_v6). supervisor:count_children(ioc2rpz_tcp_sup_v6).
%% Check ETS table sizes (memory usage) ets:info(cfg_table, size). ets:info(rpz_hotcache_table, size). ets:info(rate_limits, size).
### Controlli di integrità DNS```bash
# SOA query over UDP
dig @localhost -p 53 your-zone.rpz SOA +short
# Zone transfer over TCP
dig @localhost -p 53 your-zone.rpz AXFR +tcp -y hmac-sha256:keyname:base64key
# DoT query
dig @localhost -p 853 +tls your-zone.rpz SOA
# Sample zone (built-in test zone)
dig @localhost sample-zone.ioc2rpz AXFR +tcp
Vedi docs/deployment.md per il monitoraggio completo e il riferimento ai log.
| Problema | Soluzione |
|---|---|
| Porta già in uso | Controlla con lsof -i :53 / lsof -i :853. {reuseaddr, true} è impostato sui socket di ascolto per riavvii rapidi. |
| DoT non accetta connessioni | Verifica che {cert, ...} sia configurato. Controlla i worker TLS: supervisor:count_children(ioc2rpz_tls_sup_v6). Verifica che la porta 853 non sia bloccata dal firewall. |
| Il trasferimento di zona fallisce (discrepanza TSIG) | Verifica che il nome della chiave e il segreto corrispondano tra client e server. Cerca eventi CEF 104/105 nei log. |
| Errori di download delle sorgenti | Controlla la connettività di rete. Cerca Error downloading feed nei log. Il server riprova 3 volte con ritardo di 3 secondi. Per sorgenti HTTPS, assicurati di avere un certificato TLS valido. |
| Elevato utilizzo di memoria | Controlla le dimensioni delle tabelle ETS nella shell Erlang. rate_limits e rpz_hotcache_table vengono pulite periodicamente. Considera di ridurre ?HotCacheTime. |
Vedi docs/deployment.md per una risoluzione dei problemi dettagliata.
La configurazione è un file Erlang. Ogni opzione di configurazione è un termine Erlang, quindi la configurazione deve rispettare la sintassi Erlang. Il server convalida le voci di configurazione al caricamento/ricaricamento: codifica delle chiavi TSIG, esistenza dei file dei certificati, compilazione delle regex e sintassi degli URL. Le voci non valide vengono registrate e saltate. Vedi docs/configuration.md per il riferimento completo alla configurazione.
ioc2rpz™ supporta i seguenti parametri di configurazione:
Il record srv viene utilizzato per definire i valori predefiniti del server. Consiste in:
TrackSources — il default globale a livello di server per l'attribuzione della sorgente: off | auto | on (default off). Applicato a qualsiasi feed il cui proprio track_sources non è impostato. Vedi Attribuzione delle sorgenti IOC.Esempio di record srv:``` {srv,{"ns1.example.com","support.email.example.com",["dnsmkey_1","dnsmkey_2","dnsmkey_3"],["acl_ip1","acl_ip2"]}}.
%% With the optional global source-tracking default (5-field form): {srv,{"ns1.example.com","support.email.example.com",["dnsmkey_1"],["acl_ip1"],auto}}.
Il formato a 4 campi rimane valido e imposta `TrackSources` su `off` per impostazione predefinita.
### **cert** record
Il record **cert** è utilizzato per definire un certificato e una chiave privata per le comunicazioni DNS over TLS, REST API e DoH. Per la generazione e gestione dei certificati, vedere [Impostazione del certificato](#certificate-setup).
Consiste in:
- percorso di un file contenente un certificato;
- percorso di un file contenente una chiave privata codificata in PEM;
- percorso di un file con certificati CA codificati in PEM.
Esempio di record **cert**:```
{cert,{"cfg/cert.pem", "cfg/key.pem", "cfg/cacerts.pem"}}.
Il record include consente di dividere la configurazione di ioc2rpz™ in più file.
Esempio di record include:``` {include,"cfg/tkeys.include.cfg"}.
### Record **key**
Le chiavi TSIG sono utilizzate per autenticazione e autorizzazione. Si consiglia di utilizzare chiavi TSIG diverse per la gestione di ioc2rpz™ e per i trasferimenti di zona.
Il record **key** è composto da:
- nome della chiave TSIG;
- algoritmo. Sono supportati ``md5``, ``sha256`` e ``sha512``;
- la chiave;
- (opzionale) elenco di gruppi di chiavi a cui appartiene.
Esempi di record **key**:```
{key,{"key_name_1","md5","ayVnL+h2QKMszRVohrngagcEuIpN3RkecXKdwSa5WsHD5N4Y5R3NUMGM W8sIGv36gPkAtWtgarqKzN9tmHqEnA=="}}.
{key,{"key_name_2","sha256","5Yvt70eJnf95+LJeI8H3TgKGeVparmMB7udA0pv/JRE="}}.
{key,{"key_name_3","sha512","03uuaGl9kqfenjRgIeCv6e29lVvMwviB1+cDX1I0jcVOcTU4jWFwRkfo3ULRMD+NGDfwzYvXkJ94FNEaAW4vzw==",["customers","public"]}}.
dnssec-keygen è un'utilità che può essere utilizzata per generare chiavi TSIG:```bash
dnssec-keygen -a HMAC-MD5 -b 512 -n USER tsig-key
dnssec-keygen -a HMAC-SHA256 -b 256 -n USER tsig-key
dnssec-keygen -a HMAC-SHA512 -b 512 -n USER tsig-key
Fare riferimento alla documentazione di "dnssec-keygen" per i dettagli. Le chiavi possono essere assegnate a gruppi per l'autorizzazione basata su gruppi nel controllo di accesso alla zona RPZ.
### Record **key_group**
I gruppi di chiavi forniscono autorizzazione basata su gruppi per i trasferimenti e la gestione delle zone. Invece di elencare singole chiavi nei record `rpz` o `srv`, è possibile assegnare chiavi a gruppi nominati e fare riferimento al gruppo.
Esistono due modi per assegnare chiavi ai gruppi:
1. Inline tramite il 4° campo opzionale del record `key`: `{key, {Name, Alg, Secret, [Groups]}}`
2. Esplicitamente tramite un record `key_group` (mostrato di seguito)```erlang
{key_group, {GroupName, [KeyName1, KeyName2, ...]}}.
| Campo | Tipo | Descrizione |
|---|---|---|
| GroupName | string | Nome del gruppo (es. "customers") |
| Keys | lista di stringhe | Elenco dei nomi di chiave TSIG appartenenti a questo gruppo |
Esempio di record key_group:```erlang {key_group, {"customers", ["dnsproxykey_1", "dnsproxykey_2"]}}. {key_group, {"public", ["dnsproxykey_3"]}}.
I gruppi vengono referenziati in `rpz` e `srv` record utilizzando la tupla `{groups, ["group1", "group2"]}` nella lista delle chiavi:```erlang
{rpz, {"zone.ioc2rpz", 7202, 3600, 2592000, 7200, "true", "true", "nxdomain",
["dnsproxykey_1", {groups, ["customers", "public"]}],
"fqdn", 86400, 3600, ["source1"], [], []}}.
Le whitelist sono utilizzate per prevenire possibili errori e bloccare domini e indirizzi IP fidati. Gli IOC in whitelist vengono rimossi dalle zone delle policy di risposta. ioc2rpz™ controlla solo corrispondenze esatte, pertanto non suddivide o scarta una rete se un indirizzo IP in whitelist è incluso in una sottorete bloccata e viceversa. Una whitelist è un file di testo o un feed di dati testuali. Gli indicatori devono essere separati da caratteri di nuova riga (/n, /r o entrambi /n/r). Le whitelist devono contenere FQDN validi e/o indirizzi IP. ioc2rpz™ supporta un numero illimitato di indicatori.
Il record whitelists consiste in:
""), verrà utilizzata una REGEX predefinita ("^([A-Za-z0-9][A-Za-z0-9\-\._]+)[^A-Za-z0-9\-\._]*.*$"). none viene utilizzato se non è richiesta alcuna REGEX (la fonte fornisce già dati nel formato richiesto).Esempio di record whitelist:``` {whitelist,{"whitelist_1","file:cfg/whitelist1.txt",none}}.
### **source** record
Una source è un feed di indicatori malevoli. Sono supportati FQDN, indirizzi IPv4 e IPv6. Una source è un file di testo o un feed di dati testuali. Gli indicatori devono essere separati da caratteri di newline/carriage return (/n, /r o entrambi /r/n). ioc2rpz™ supporta un numero illimitato di indicatori.
Il record **source** è composto da:
- nome della source;
- percorso della source per il trasferimento completo della source (AXFR). Sono supportati URL (http/https/ftp), file locali e script. Il prefisso **file:** è usato per file locali. Il prefisso **shell:** è usato per eseguire uno script/comando locale su un host/container che deve restituire indicatori e una data di scadenza opzionale su STDOUT;
- percorso della source per il trasferimento incrementale della source (IXFR). I percorsi AXFR e IXFR supportano parole chiave per abbreviare gli URL e fornire timestamp di aggiornamento della zona:
- **[:AXFR:]** - percorso AXFR completo. Può essere usato solo nei percorsi IXFR;
- **[:FTimestamp:]** - timestamp dell'ultimo aggiornamento della source (es. 1507946281)
- **[:ToTimestamp:]** - timestamp corrente;
- REGEX utilizzata per estrarre gli indicatori e la loro data di scadenza. Il primo match è un indicatore, il secondo match è la data di scadenza. La data di scadenza è un parametro opzionale. L'espressione regolare deve essere racchiusa tra virgolette doppie. Se si specifica una REGEX vuota (`""`), verrà utilizzata una REGEX predefinita (`"^([A-Za-z0-9][A-Za-z0-9\-\._]+)[^A-Za-z0-9\-\._]*.*$"`). `none` viene usato se non è richiesta alcuna REGEX (la source fornisce già i dati nel formato richiesto).
Parametri opzionali (devono essere usati tutti o nessuno):
- UserID (usato internamente).
- Numero massimo di IoC.
- Aggiornamento completo della source, tempo di cache calda (in secondi).
- Aggiornamento incrementale della source, tempo di cache calda (in secondi).
I download da source HTTPS verificano il certificato TLS del server remoto. Le source con certificati non validi o autofirmati non riusciranno a scaricare. Per certificati autofirmati, utilizzare una source con `shell:` e `curl --insecure`.
**Restrizioni per file locali:** i percorsi `file:` contenenti `..` (attraversamento di directory padre) sono rifiutati per sicurezza; utilizzare un percorso senza `..` (all'interno della directory di lavoro/dati).
**Restrizioni per comandi shell:** l'eseguibile di ogni segmento della pipeline deve essere un percorso assoluto (es. `/usr/bin/curl`) o un'utilità di testo sicuro con nome semplice (`sort`, `uniq`, `grep`, `sed`, `awk`, `gawk`, ecc.); i comandi distruttivi e le shell (`rm`, `bash`, `sh`, ecc.) sono bloccati, e la sostituzione di comando (`$(...)`, backtick) e la redirezione dell'output (`>`, `>>`) sono rifiutate. I comandi rifiutati non vengono eseguiti e vengono registrati tramite evento CEF 151 (comandi eseguiti tramite 150). Consultare [docs/configuration.md](https://github.com/homas/ioc2rpz/blob/master/docs/configuration.md#shell-command-restrictions) per l'insieme completo di regole.
Se una source restituisce meno del 50% del suo precedente conteggio di indicatori, l'aggiornamento viene rifiutato e i dati precedenti vengono mantenuti. Questo impedisce che feed degradati riducano la copertura RPZ. Configurabile tramite la macro `?SOURCE_MIN_IOC_RATIO`.
Esempio di record **source**:```
%% Local file source — indicators without expiration
{source,{"sample_fqdn","file:cfg/sample_ioc_fqdn.txt","[:AXFR:]",none}}.
%% Local file source — indicators with expiration timestamps (tab-separated)
{source,{"sample_expire","file:cfg/sample_ioc_expire.txt","[:AXFR:]","^([A-Za-z0-9][A-Za-z0-9\-\._]+)\t([0-9TZ:\-]+)$"}}.
%% Shell source — fetch RPZ via AXFR and extract CNAMEs
{source,{"base.rpz1","shell:/usr/bin/dig -y KEYNAME:TSIGKEY @127.0.0.1 base.rpz.ioc2rpz.local axfr | /bin/grep -e CNAME | /bin/grep -v '*.' | /usr/bin/awk -F '.base.rpz' '{print $1}'","",none}}.
Source shell: viene utilizzato per estendere le opzioni di connettività di ioc2rpz™, che sono nativamente un po' limitate. Il container ioc2rpz™ include dig, grep, awk e python. Ad esempio, puoi mescolare diversi feed RPZ o recuperare dati da un database.
Restrizioni dei comandi Shell: Tutti gli eseguibili devono utilizzare percorsi assoluti (es. /usr/bin/curl non curl). I comandi distruttivi (rm, bash, sh, ecc.) sono bloccati. La sostituzione di comandi ($(...), backtick) e il reindirizzamento dell'output (>, >>) sono rifiutati. Vedi docs/configuration.md per i dettagli completi.
Sicurezza dei file locali: I percorsi dei file che contengono .. (attraversamento della directory principale) vengono rifiutati per motivi di sicurezza.
Il termine RPZ definisce una zona di policy di risposta.
Il record rpz è composto da:
true o false. true definisce che l'RPZ deve essere memorizzato nella cache, false - non memorizzato nella cache, le sorgenti delle zone live vengono scaricate e un RPZ viene generato tramite richiesta AXFR. Le zone "live" non supportano il trasferimento incrementale di zona. Se il feed RPZ non è comunque memorizzato nella cache, viene temporaneamente archiviato in una hot cache. Nel caso in cui una richiesta vada in timeout da un client, saremo in grado di rispondere la volta successiva. Il tempo AXFR verrà utilizzato per determinare la durata della cache;true o false. Definisce se devono essere generate regole wildcard;mixed, fqdn, ip. Viene utilizzato per l'ottimizzazione.TrackSources — attribuzione della sorgente per feed: auto | true | false. Quando presente, sovrascrive l'impostazione predefinita globale del server. Quando omesso (modulo a 15 campi), il feed eredita l'impostazione predefinita del server (#srv TrackSources, off se non configurato). Vedi Attribuzione della sorgente IOC.| Azione | Valore di configurazione | Descrizione |
|---|---|---|
| NXDOMAIN | "nxdomain" | Restituisce NXDOMAIN (il dominio non esiste) |
| NODATA | "nodata" | Restituisce risposta vuota (dominio esiste, nessun record) |
| Passthru | "passthru" | Consenti la query (regola di esenzione) |
| Drop | "drop" | Elimina silenziosamente la query |
| TCP-Only | "tcp-only" | Forza il client a riprovare tramite TCP |
| Block NS | "blockns" | Blocca il nameserver autorevole |
| Redirect (dominio) | {"redirect_domain","example.com"} | Reindirizza a un dominio specificato (alias per local_cname) |
| Redirect (IP) | {"redirect_ip","127.0.0.1"} | Reindirizza a un IP specificato (alias per local_a/local_aaaa) |
| Local A | {"local_a","127.0.0.1"} | Restituisce un indirizzo IPv4 personalizzato |
| Local AAAA | {"local_aaaa","fe80::1"} | Restituisce un indirizzo IPv6 personalizzato |
| Local CNAME | {"local_cname","www.example.com"} | Restituisce un reindirizzamento CNAME |
| Local TXT | {"local_txt","Text Record"} | Restituisce un record TXT |
Più azioni locali possono essere combinate in un elenco: [{"local_a","127.0.0.1"},{"local_aaaa","fe80::1"},{"local_txt","Blocked"}]
Esempio di record rpz:``` {rpz,{"zone_name",soa_refresh, soa_update_retry,soa_expire,soa_nxdomain_ttl,"cache","wildcards","action",["key1","key2"],"Zone_type",AXFT_Time, IXFR_Time,["source1","source2"],["notify_ip1","notify_ip2"],["whitelist_1","whitelist_2"]}}.
{rpz,{"zone_name",soa_refresh, soa_update_retry,soa_expire,soa_nxdomain_ttl,"cache","wildcards","action",["key1","key2",{groups,["group1","group2"]}],"Zone_type",AXFT_Time, IXFR_Time,["source1","source2"],["notify_ip1","notify_ip2"],["whitelist_1","whitelist_2"]}}.
{rpz,{"mixed.ioc2rpz",7202,3600,2592000,7200,"true","true","passthru",["dnsproxykey_1","dnsproxykey_2"],"mixed",86400,3600,["sample_fqdn","sample_expire","sample_ip"],[],["whitelist_1","whitelist_2"]}}.
{rpz,{"mixed.ioc2rpz",7202,3600,2592000,7200,"true","true","passthru",["dnsproxykey_1","dnsproxykey_2",{groups,["public","ip2"]}],"mixed",86400,3600,["sample_fqdn","sample_expire","sample_ip"],[],["whitelist_1","whitelist_2"]}}.
%% With explicit per-feed source tracking (16-field form; trailing auto):
{rpz,{"mixed.ioc2rpz",7202,3600,2592000,7200,"true","true","passthru",["dnsproxykey_1"],"mixed",86400,3600,["sample_fqdn","sample_expire","sample_ip"],[],["whitelist_1"],auto}}.
### Attribuzione della fonte IOC
Un feed RPZ è costruito unendo indicatori provenienti da più fonti. L'attribuzione della fonte consente all'API di ricerca IOC di segnalare **quale(i) fonte(i) all'interno di un feed** ha contribuito a un indicatore — utile per smistare un falso positivo segnalato. Il tracciamento è **disattivato per impostazione predefinita** e controllato per feed con un'impostazione predefinita globale opzionale a livello di server.
**Configurazione**
- Per-feed: l'elemento `TrackSources` finale opzionale (16°) della tupla `{rpz,{...}}` — `auto | true | false`.
- Impostazione predefinita globale del server: l'elemento `TrackSources` finale opzionale (5°) della tupla `{srv,{...}}` — `off | auto | on` (predefinito `off`).
Entrambi sono opzionali e retrocompatibili: i file di configurazione esistenti (rpz a 15 campi, srv a 4 campi) vengono caricati invariati e si comportano come off.
**Precedenza di risoluzione** — lo stato effettivo per un feed viene risolto come:
1. il valore esplicito `track_sources` del feed, se impostato;
2. altrimenti l'impostazione predefinita globale del server;
3. altrimenti l'impostazione predefinita incorporata `off`.
`auto` significa: traccia solo i feed **multi-fonte**. I feed a fonte singola non vengono mai mascherati — il loro unico nome di fonte viene restituito direttamente (nessun costo di tracciamento).
**API — il campo additivo `sources`**
La risposta di `/api/v1/ioc/:ioc` acquisisce un nuovo campo `sources` su ogni oggetto feed. È **additivo e retrocompatibile**: tutti i campi esistenti rimangono invariati, quindi i vecchi client che lo ignorano continuano a funzionare.
- Feed multi-fonte tracciato: un array JSON dei nomi delle fonti contribuenti.
- Feed a fonte singola: un array con un singolo elemento contenente il nome di quella fonte.
- Tracciamento disabilitato o attribuzione sconosciuta (ad es. una riga cache pre-aggiornamento prima della sua ricostruzione AXFR una tantum): `null` (JSON) / `(disabled)` o `(unavailable)` (TXT).```json
{
"feed": "mixed.ioc2rpz",
"wildcard": "true",
"type": "fqdn",
"rpz_serial": 1709000000,
"ioc_expiration": 0,
"sources": ["abuse-ch", "internal-list"]
}
Single-source feed: "sources": ["sample_fqdn"]. Tracking disattivato/sconosciuto: "sources": null.
Rollout (disattivato per impostazione predefinita)
L'aggiornamento del binario non cambia nulla — nessun tracciamento, nessuna ricostruzione delle zone, API invariata — finché non viene impostato un valore track_sources. I feed sono gestiti tramite GUI; la GUI/sito della community scriverà questi valori di configurazione opzionali e mostrerà sources in un aggiornamento successivo. Abilitare il tracciamento per un feed memorizzato nella cache attiva una ricostruzione AXFR una tantum per popolare le maschere delle sorgenti.
Limitazioni
cache = "true"), poiché la ricerca API legge la tabella della cache IXFR.{key,{"dnsproxykey_1","md5","apXqLsDs90H213eV6LS9ryYp5tY8YTpkttOkRCve7dp1Zeob3SGAbaVU9BShpsW25MmR8mTiX5OY0Qetv977Yw=="}}. {key,{"dnsproxykey_2","sha512","03uuaGl9kqfenjRgIeCv6e29lVvMwviB1+cDX1I0jcVOcTU4jWFwRkfo3ULRMD+NGDfwzYvXkJ94FNEaAW4vzw=="}}. {key,{"dnsmkey_3","sha512","03uuaGl9kqfenjRgIeCv6e29lVvMwviB1+cDX1I0jcVOcTU4jWFwRkfo3ULRMD+NGDfwzYvXkJ94FNEaAW4vzw=="}}.
{whitelist,{"whitelist_1","file:cfg/sample_whitelist.txt",none}}. {whitelist,{"whitelist_2","file:cfg/whitelist2.txt",""}}.
{source,{"sample_fqdn","file:cfg/sample_ioc_fqdn.txt","[:AXFR:]",none}}. {source,{"sample_expire","file:cfg/sample_ioc_expire.txt","[:AXFR:]","^([A-Za-z0-9][A-Za-z0-9\-\._]+)\t([0-9TZ:\-]+)$"}}. {source,{"sample_ip","file:cfg/sample_ioc_ip.txt","[:AXFR:]",none}}.
{rpz,{"localdata.ioc2rpz",7202,3600,2592000,7200,"false","true",[{"local_aaaa","fe80::1"},{"local_a","127.0.0.1"},{"local_a","127.0.0.2"},{"local_a","127.0.0.3"},{"local_a","127.0.0.4"},{"local_cname","www.example.com"},{"local_txt","Text Record www.example.com"},{"local_txt","Text Record 2"}],["dnsproxykey_1", "dnsproxykey_2"],"mixed",30,30,["sample_fqdn"],[],["whitelist_1","whitelist_2"]}}. {rpz,{"dga.ioc2rpz",7202,3600,2592000,7200,"true","true","nodata",["dnsproxykey_1","dnsproxykey_2"],"fqdn",172800,3600,["sample_expire"],[],[]}}. {rpz,{"mixed.ioc2rpz",7202,3600,2592000,7200,"true","true","passthru",["dnsproxykey_1", "dnsproxykey_2"],"mixed",86400,3600,["sample_fqdn","sample_expire"],[],["whitelist_1","whitelist_2"]}}. {rpz,{"ip-block.ioc2rpz",7202,3600,2592000,7200,"false","true","nxdomain",["dnsproxykey_1","dnsproxykey_2"],"ip",172800,0,["sample_ip"],[],[]}}.
</details>
## Valori di configurazione predefiniti - include/ioc2rpz.hrl
include/ioc2rpz.hrl contiene parametri precompilati.
Parametri standard:
- ``MGMToDNS`` (true/false) - gestione abilitata su DNS/TCP;
- ``DBStorage`` (ets) - definisce l'archiviazione DB per le cache AXFR e IXFR. La versione corrente supporta solo ETS;
- ``SaveETS`` (true/false) - definisce se le tabelle ETS AXFR/IXFR devono essere salvate su disco;
- ``Port`` (valore numerico, 1 - 65535) - definisce la porta DNS su cui il servizio è in esecuzione;
- ``PortTLS`` (valore numerico, 1 - 65535) - definisce la porta DoT su cui il servizio è in esecuzione;
- ``PortREST`` (valore numerico, 1 - 65535) - definisce la porta HTTPs su cui il servizio è in esecuzione;
- ``TTL`` (valore numerico, in secondi) - TTL predefinito per i record DNS/regole RPZ.
- ``DefConf`` (stringa) - file di configurazione predefinito;
- ``DefDB`` (stringa) - percorso del database predefinito;
- ``logTS`` - se definito, il timestamp viene aggiunto nei messaggi di log;
- ``debug`` - se definito, vengono stampati i messaggi di log di debug;
- ``TLSVersion`` ('tlsv1.2-1.3') - versioni TLS supportate per DoT e API REST;
Parametri di ottimizzazione:
- ``DNSPktMax`` (valore numerico, 100 - 65535) - dimensione massima del pacchetto. Valori consigliati:
- 16384 - dimensione minima del trasferimento di zona;
- 65535 - numero minimo di pacchetti DNS;
- ``Compression`` (valore numerico, 0 - 9) - Livello di compressione (0 - nessuna compressione, 9 - massima compressione). La cache AXFR e le tabelle su disco memorizzano dati compressi;
- ``ZoneRefTime`` (valore numerico, in millisecondi) - definisce l'intervallo di controllo dell'aggiornamento della zona;
- ``TCPTimeout`` (valore numerico, in millisecondi) - definisce il timeout della sessione TCP;
- ``HotCacheTime`` (valore numerico, in secondi) - Tempo di cache calda per IOC, Regole, Pacchetti. Le zone live sono memorizzate in una cache calda;
- ``HotCacheTimeIXFR`` (valore numerico, in secondi) - Tempo di cache calda per gli IOC IXFR in una cache calda. Per impostazione predefinita, gli indicatori IXFR vengono memorizzati nella cache per un minuto (anche se impostato a 0) perché il seriale corrente viene sempre arrotondato al minuto precedente;
- ``RATE_LIMIT_WINDOW`` (valore numerico, in millisecondi, default 10000) - durata della finestra di limitazione della velocità per IP;
- ``MAX_REQUESTS_PER_WINDOW`` (valore numerico, default 1) - numero massimo di richieste DNS per IP per finestra di limitazione della velocità;
- ``ShellMaxRespSize`` (valore numerico, default 2 GiB) - dimensione massima della risposta per le fonti di comandi shell;
- ``SourcePullTimeout`` (valore numerico, in millisecondi, default 300000) - timeout per i download delle fonti (5 minuti);
## Come vengono aggiornate le cache AXFR (completa) e IXFR (incrementale)
- La cache AXFR contiene sempre zone predefinite senza record SOA/NS/TSIG. Predefinite significa che tutti i record sono suddivisi in pacchetti e le etichette sono state accorciate/compresse.
- Se un server riceve una richiesta AXFR, recupera i pacchetti dalla cache AXFR, aggiunge i record SOA/NS e TSIG se necessario.
- L'aggiornamento delle zone AXFR dovrebbe essere considerato come una procedura di pulizia, che dovrebbe avvenire periodicamente. Solo per assicurarsi che non ci sia desincronizzazione tra le fonti e la cache.
- Per zone grandi, gli aggiornamenti AXFR dovrebbero essere programmati raramente per ridurre l'impatto sulle prestazioni del server e sulla quantità di dati trasferiti a tutti i client.
- Tutte le modifiche, se possibile, dovrebbero essere effettuate tramite aggiornamenti incrementali della zona. In tal caso, la cache AXFR verrà ricostruita solo se una zona è stata aggiornata.
- [TODO] A causa di un'ottimizzazione, solo l'ultimo pacchetto verrà ricostruito per i nuovi IOC e i pacchetti pertinenti e corrispondenti per gli IOC scaduti.
- La cache IXFR contiene solo IOC e date di scadenza. [TODO] e ID dei pacchetti (per consentire una ricostruzione rapida della zona).
- Il record RPZ contiene il Serial e il Serial_IXFR correnti della zona. Serial_IXFR funge da seriale incrementale minimo disponibile per un trasferimento di zona incrementale.
- La cache IXFR viene svuotata dopo un aggiornamento completo della zona (AXFR). Serial_IXFR = Serial. I client riceveranno comunque un aggiornamento completo della zona, motivo per cui è importante effettuare il trasferimento di zona AXFR raramente.
- Quando la cache IXFR viene aggiornata, la cache AXFR deve essere ricostruita.
- Se una zona non supporta gli aggiornamenti IXFR -> non viene salvata nella tabella IXFR.
- Le zone live non sono memorizzate nella cache nelle cache AXFR e IXFR, ma le fonti (IOC) possono essere memorizzate nella cache calda.
## Cache calda
Tutti gli IOC, le Regole, i Pacchetti, incluse le zone RPZ live, sono memorizzati nella cache calda. I parametri precompilati ``HotCacheTime``, ``HotCacheTimeIXFR`` definiscono il tempo di memorizzazione.
## Come provare ioc2rpz™ (o feed RPZ di esempio e gratuiti ospitati da ioc2rpz™)
### Dichiarazione di non responsabilità
L'autore non si assume alcuna responsabilità per eventuali errori o omissioni nel contenuto di questi feed RPZ. I feed sono forniti "così come sono" senza alcuna garanzia di completezza, accuratezza, utilità o tempestività per dimostrare solo la tecnologia ioc2rpz™. La distribuzione del servizio di feed RPZ può essere interrotta o sospesa senza alcun preavviso. L'autore non è responsabile per danni diretti o indiretti causati dall'utilizzo di questo servizio.
### Feed RPZ
Puoi testare la tecnologia ioc2rpz™ se ti registri sulla [community ioc2rpz™](https://ioc2rpz.net) con i seguenti feed:
- [notracking](https://github.com/notracking/hosts-blocklists);
- [Phishtank](https://www.phishtank.com/).
### Configurazione bind di esempio```
options {
#This is just options for RPZs. Add other options as required
recursion yes;
response-policy {
####FQDN only zones
####Mixed zones
zone "phishtank.ioc2rpz" policy nxdomain;
####IP only zones
} qname-wait-recurse no break-dnssec yes;
};
key "ioc2rpz-YOUR-UNIQUE-KEY-NAME"{
algorithm hmac-sha256; secret "ioc2rpz-YOUR-UNIQUE-KEY";
};
zone "phishtank.ioc2rpz" {
type slave;
file "/var/cache/bind/phishtank.ioc2rpz";
masters {94.130.30.123 key "ioc2rpz-YOUR-UNIQUE-KEY-NAME";};
};
rpzMaster("94.130.30.123", "phishtank.ioc2rpz", {defpol=Policy.NXDOMAIN, tsigname="ioc2rpz-YOUR-UNIQUE-KEY-NAME", tsigalgo="hmac-sha256", tsigsecret="ioc2rpz-YOUR-UNIQUE-KEY"})
### Esempio di configurazione Infoblox (file di importazione)```
header-responsepolicyzone,fqdn*,zone_format*,rpz_policy,substitute_name,view,zone_type,external_primaries,grid_secondaries,priority
responsepolicyzone,phishtank.ioc2rpz,FORWARD,Nxdomain,,default,responsepolicy,srv_1/94.130.30.123/FALSE/FALSE/TRUE/ioc2rpz-YOUR-UNIQUE-KEY-NAME/ioc2rpz-YOUR-UNIQUE-KEY/HMAC-SHA256,infoblox.localdomain/False/False/False,0
dig @94.130.30.123 -y hmac-sha256:ioc2rpz-YOUR-UNIQUE-KEY-NAME:ioc2rpz-YOUR-UNIQUE-KEY phishtank.ioc2rpz SOA
kdig @94.130.30.123 -y hmac-sha256:ioc2rpz-YOUR-UNIQUE-KEY-NAME:ioc2rpz-YOUR-UNIQUE-KEY phishtank.ioc2rpz SOA +tls
## Alcuni feed gratuiti di threat intelligence
- [Netlab](http://data.netlab.360.com)
- [awesome-threat-intelligence lista su GitHub](https://github.com/hslatman/awesome-threat-intelligence)
Puoi trovare altri feed IOC sulla pagina wiki: https://github.com/Homas/ioc2rpz/wiki/IOC-Sources.
## Documentazione aggiuntiva
Per documentazione dettagliata, vedi la directory `docs/`:
- [docs/architecture.md](https://github.com/homas/ioc2rpz/blob/master/docs/architecture.md) — Albero di supervisione OTP, responsabilità dei moduli, tabelle ETS, flusso dei dati
- [docs/configuration.md](https://github.com/homas/ioc2rpz/blob/master/docs/configuration.md) — Riferimento completo alla configurazione con tutti i tipi di tuple e opzioni
- [docs/deployment.md](https://github.com/homas/ioc2rpz/blob/master/docs/deployment.md) — Istruzioni di build, deployment Docker, certificati, monitoraggio, risoluzione dei problemi
- [docs/protocols.md](https://github.com/homas/ioc2rpz/blob/master/docs/protocols.md) — Supporto dei protocolli (UDP/TCP/DoT/DoH), API REST, TSIG, limitazione delle richieste, DNS NOTIFY
## Riferimenti
- [RFC-6895 Considerazioni IANA del Domain Name System (DNS)](https://tools.ietf.org/html/rfc6895)
- [RFC-1035 Nomi di Dominio - Implementazione e Specifica](https://tools.ietf.org/html/rfc1035)
- [RFC-1995 Trasferimento Incrementale di Zona nel DNS](https://tools.ietf.org/html/rfc1995)
- [Zone di Risposta per Criteri DNS (RPZ)](https://tools.ietf.org/html/draft-ietf-dnsop-dns-rpz-00) + [vixie](https://tools.ietf.org/html/draft-vixie-dns-rpz-02)
- [RFC-2845 Autenticazione delle Transazioni con Chiave Segreta per DNS (TSIG)](https://tools.ietf.org/html/rfc2845)
- [RFC-2104 HMAC: Hashing con Chiave per Autenticazione dei Messaggi](https://tools.ietf.org/html/rfc2104)
- [RFC-4635 Identificatori dell'Algoritmo HMAC SHA TSIG](https://tools.ietf.org/html/rfc4635)
- [RFC-5966 Trasporto DNS su TCP - Requisiti di Implementazione](https://tools.ietf.org/html/rfc5966)
- [RFC-1996 Meccanismo per la Notifica Tempestiva di Modifiche di Zona (DNS NOTIFY)](https://tools.ietf.org/html/rfc1996)
- [Meccanismi di Estensione per DNS (EDNS(0))](https://tools.ietf.org/html/rfc6891) + [Codici Opzione EDNS](https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-11)
- [RFC-7873 Cookie del Domain Name System (DNS)](https://tools.ietf.org/html/rfc7873)
- [RFC-7858 Specifica per DNS su Transport Layer Security (TLS)](https://tools.ietf.org/html/rfc7858)
- [Cowboy Web Server](https://ninenines.eu)
- [Rebar3](https://www.rebar3.org)
<details>
<summary><strong>Riferimento codici evento CEF</strong> (clicca per espandere)</summary>
| Codice | Gravità | Evento | Descrizione |
|------|----------|-------|-------------|
| 101 | Bassa | Pacchetto DNS errato | Ricevuto pacchetto DNS malformato |
| 102 | Bassa | Richiesta DNS errata | Richiesta DNS non analizzabile |
| 103 | Media | Rifiutato | Richiesta DNS rifiutata |
| 104 | Media | Chiave TSIG non trovata | Richiesta ha utilizzato chiave TSIG sconosciuta |
| 105 | Media | TSIG MAC errato | Verifica firma TSIG fallita |
| 106 | Media | TSIG ora errata | Timestamp TSIG fuori intervallo |
| 107 | Media | Altro errore TSIG | Errore TSIG non classificato |
| 108 | Media | Posizione TSIG errata | Record TSIG in posizione inaspettata |
| 109 | Bassa | Ricevuta risposta DNS | Ricevuta risposta DNS inaspettata |
| 120 | Media | RPZ non trovata | La zona RPZ richiesta non esiste |
| 121 | Bassa | RPZ non pronta | La zona RPZ è ancora in caricamento/aggiornamento |
| 130 | Bassa | Errore trasferimento RPZ | Errore durante il trasferimento di zona (solo trasferimento RPZ) |
| 131 | Bassa | Trasferimento RPZ chiuso | Connessione remota chiusa durante il trasferimento (solo trasferimento RPZ) |
| 140 | Alta | Autenticazione REST base fallita | Autenticazione di base dell'API REST fallita |
| 141 | Alta | Autenticazione REST fallita | Autorizzazione dell'API REST fallita |
| 145 | Alta | Richiesta REST MGMT negata | Richiesta di gestione REST negata dall'ACL |
| 146 | Alta | Richiesta MGMT fallita | Elaborazione della richiesta di gestione fallita |
| 147 | Alta | Richiesta non supportata | Endpoint API REST sconosciuto |
| 148 | Alta | Zona non trovata | L'API REST ha fatto riferimento a zona inesistente |
| 150 | Bassa | Comando shell eseguito | Comando sorgente shell eseguito (info) |
| 151 | Alta | Comando shell rifiutato | Comando sorgente shell rifiutato (sicurezza) |
| 201 | Bassa | Trasferimento RPZ riuscito | Trasferimento di zona completato |
| 202 | Bassa | Query DNS | Query DNS standard elaborata |
| 221 | Bassa | Notifica DNS | Notifica inviata al server secondario |
| 222 | Media | Errore notifica DNS | Invio notifica fallito |
| 230 | Alta | Richiesta MGMT | Operazione di gestione eseguita |
| 301 | Alta | Richiesta MGMT negata | Comando di gestione DNS negato |
| 429 | Alta | Troppe richieste | Limite di richieste superato |
| 501 | Alta | Possibile DDoS | Rilevato pattern CVE-2004-0789 |
</details>
# Vuoi supportare il progetto?
Puoi supportare il progetto ioc2rpz™ e la comunità ioc2rpz™ (https://ioc2rpz.net) tramite [GitHub Sponsor](https://github.com/sponsors/Homas) (pagamenti ricorrenti). Per fare una donazione una tantum puoi usare [PayPal](https://paypal.me/ioc2rpz) o Zelle (la nostra email: zelle [at] ioc2rpz [.] net).
# Sostenitori
Un ringraziamento a **craSH** e **rrbone** che supportano i miei progetti su [GitHub Sponsor](https://github.com/sponsors/Homas).
# Contattaci
Puoi contattarci via email: feedback(at)ioc2rpz[.]net o su [Telegram](https://t.me/ioc2rpz).
# Licenza
Copyright 2017 - 2025 Vadim Pavlov ioc2rpz[at]gmail[.]com
Concesso in licenza secondo l'Apache License, Versione 2.0 (la "Licenza"); non puoi utilizzare questo file se non in conformità con la Licenza.
Puoi ottenere una copia della Licenza all'indirizzo:
http://www.apache.org/licenses/LICENSE-2.0
Salvo diversamente previsto dalla legge applicabile o concordato per iscritto, il software distribuito secondo la Licenza è distribuito "COSÌ COM'È", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o implicite. Consulta la Licenza per il linguaggio specifico che regola i permessi e le limitazioni.