
Automatizza il blocco dei bot dannosi che tentano di accedere al tuo server
Una TUI, una web UI e una CLI che ti aiutano a configurare il tuo server per fermare i bot malevoli senza nasconderti dietro una CDN.
Funziona insieme a NGINX e al tuo firewall esistente (iptables o nftables), su due piani separati:
L'app fa del suo meglio per non bloccarti fuori dal server, ma la usi a tuo rischio. E nota che è distribuita sotto licenza AGPL, quindi se la usi commercialmente, assicurati di rispettare la lettera della licenza.
Da crates.io:``` cargo install stop-bots
Oppure esegui la build da un checkout:```
cargo install --path .
Un binario Linux x86_64 precompilato è disponibile nelle release su GitHub.
Richiede Rust 1.88 o versione successiva per la compilazione. In pratica solo Linux: invoca
systemctl, nginx -t e nft/iptables, quindi anche se compila altrove non sarà
di grande utilità lì.
Esegui il binario senza argomenti per avviare la TUI, stop-bots web per le stesse schermate in
un browser (vedi L'interfaccia web), oppure consulta stop-bots --help per l'elenco completo dei
sottocomandi CLI. La TUI e la CLI possono essere usate insieme. Configura tutto nella TUI e
poi usa la CLI in un crontab per mantenere le regole aggiornate.
Puoi uscire dall'app, o tornare indietro da un popup/sottomenu, con 'q' o Escape.
Puoi passare tra il tema scuro e quello chiaro con 't'. L'app proverà a rilevare automaticamente il tema, ma per alcune combinazioni di terminale e multiplexer non ci sono informazioni sufficienti per fare la scelta corretta.
1–4 (o d/b/s/p) saltano direttamente a una schermata; Left/Right, o i loro alias
vim h/l, le scorrono in sequenza; ? attiva/disattiva un riferimento completo delle combinazioni di tasti in qualsiasi momento, e :
apre una command palette che elenca ogni azione per nome. Tab / Shift+Tab si spostano sempre tra
i pannelli della schermata corrente, mai tra le schermate.
La Dashboard possiede tutto ciò che finisce nello script del firewall; Site settings possiede tutto ciò che finisce nella configurazione NGINX. Questa suddivisione decide dove risiede ogni impostazione.
Up/Down scorrono tra le tre liste; m cambia la modalità geo. Premi F per generare le
regole del firewall correnti in uno script — il
popup ha anche un interruttore "apply after writing" (Space) per applicarlo effettivamente
immediatamente, invece di applicarlo manualmente dopo. Altri tre tasti agiscono sull'intero
host: u scarica tutte le liste, a applica entrambi i piani (NGINX, poi il firewall), e
w mette questa console dietro NGINX — gli stessi tre che il browser ha come pulsanti e un
pannello.Tab per metterlo a fuoco) che contiene le scelte
a livello di host che modellano la configurazione generata — cosa riceve una richiesta bloccata (vedi sotto),
se servire un robots.txt generato, e il rate limiting — sopra ogni sito NGINX
scoperto su disco, ciascuno con uno stato live "up to date / stale / not found" e azioni per
applicare la policy corrente a un sito o a tutti. Modificare una di queste impostazioni porta
ogni sito applicato a STALE, che è il tuo segnale per riapplicare. Aprire un sito ti permette di
sovrascrivere la sua policy di categoria/bot, attivare una qualsiasi delle sei regole sulla forma delle richieste, e elencare
i percorsi esenti dal blocco.NOT BLOCKED/BLOCKED (mostrato in rosso). Tab/Shift+Tab cambiano a quale dei due pannelli
si applicano Up/Down; f cicla un filtro condiviso (all / not blocked only / blocked only);
Enter blocca la riga NOT BLOCKED selezionata, o la sblocca se è già BLOCKED.
i ispeziona l'indirizzo selezionato: quali dei feed di reputazione lo elencano, se è
all'interno di un range di crawler pubblicato (che è ciò che separa un vero Googlebot da uno user
agent che si limita a dichiararlo), a quale paese appartiene, e quali account ha tentato di
usare per il login. Tutto da liste che questo host ha già scaricato — non c'è reverse
DNS o lookup whois qui, perché un record PTR è scritto da chi detiene l'indirizzo
e sarebbe testo fornito dall'attaccante che si legge come autorevole.Bot settings, dove risiede ogni sorgente di lista e ogni singolo bot:
Site settings, dove le scelte NGINX a livello di host si trovano sopra ogni sito trovato su disco:
Dynamic Protection, la vista live di ciò che sta colpendo il server in questo momento:
Bot conosciuti, per categoria (scanner / motore di ricerca / crawler AI), provenienti da
ArcJet's Well-Known Bots,
ai.robots.txt e la
lista NGINX Ultimate Bad Bot Blocker
. Bloccare una categoria inietta una regola if ($http_user_agent ...) nella configurazione NGINX
di ogni sito (apply-blocks / a/A di Site settings).
Troppe richieste, tramite il rate limiting di NGINX stesso. A differenza di tutto il resto qui questo è applicato da NGINX al momento della richiesta anziché analizzando un log in seguito. Disattivato per impostazione predefinita: un limite tarato per il sito sbagliato allontana visitatori reali.
Con cortesia, prima — un robots.txt generato opzionale che elenca ogni bot che stai bloccando,
per i crawler che lo rispettano, più il percorso honeypot qui sotto. Disattivato per impostazione predefinita, perché
sostituisce qualunque cosa il tuo sito serva oggi su /robots.txt.
Tranne dove dici diversamente — esenzioni di percorso per sito, così puoi bloccare i crawler AI
ovunque tranne /blog.
Richieste che non sembrano provenire da un browser, per sito. Sei regole indipendenti, ciascuna con il proprio interruttore e ciascuna disattivata per impostazione predefinita — un interruttore per regola così che se qualcosa tuo smette di funzionare, puoi capire quale regola lo ha causato:
Due salvaguardie si applicano a tutte, e sono applicate anziché lasciate a te:
server HTTPS. I browser
non fanno HTTP/2 senza TLS, quindi su un blocco listen 80 semplice ogni richiesta è HTTP/1.1 —
incluso il redirect che un browser effettua verso HTTPS. I tuoi blocchi sulla porta 80 e sulla porta 443
di solito condividono un server_name, quindi l'impostazione raggiunge entrambi; solo quello TLS riceve
quelle regole. Le regole sulla forma degli header funzionano su HTTP semplice e sono scritte su entrambi./.well-known/ è sempre esente non appena una qualsiasi regola è attiva. È lì che Let's Encrypt
recupera la sua challenge HTTP-01, su HTTP/1.1 senza Accept e spesso senza User-Agent —
senza l'esenzione il tuo certificato smette di rinnovarsi settimane dopo.Una scelta a livello di host, in Site settings. Questi non sono codici di stato intercambiabili — ciascuno dice qualcosa di diverso, e la differenza conta soprattutto per i client che non intendevi intercettare:
| Opzione | A cosa serve |
|---|---|
403 Forbidden (predefinito) | dice che il blocco è stato deliberato; l'unico su cui un umano intercettato per errore può agire |
404 Not Found | nasconde che qualcosa sia stato bloccato |
410 Gone | chiede ai crawler ben educati di eliminare l'URL per sempre — preferisci questo al 403 quando stai respingendo crawler anziché attaccanti |
429 Too Many Requests | dice a un client educato di rallentare e riprovare |
418 I'm a teapot | lo scherzo della RFC 2324. Funziona; semplicemente non è registrato IANA, e NGINX lo invia con un corpo vuoto |
444 close connection | nessuna risposta; il più economico, ma indistinguibile dal server inattivo |
Tarpit | risponde 403 ma invia il corpo a singhiozzo a un byte al secondo, così il client aspetta invece di andare avanti |
Il tarpit è l'opzione più gentile per un falso positivo — un client intercettato per errore viene rallentato,
non rifiutato — e la più gravosa in termini di costo per un bot, la cui connessione resta inattiva. Due cose da
sapere prima di sceglierlo: occupa anche una delle tue connessioni worker per tutta la durata, quindi
un diluvio di client in tarpit compete con i visitatori reali per worker_connections; e quanto
duri effettivamente dipende da come NGINX sceglie di scrivere un piccolo corpo di errore, cosa
annotata in TODO.md come da verificare contro un server reale.
Ciascuno di questi è un interruttore indipendente nel pannello "Automatic blocking" della Dashboard, e ciascuno aggiunge un blocco firewall temporaneo che scade da solo e viene riaggiunto se il comportamento continua.
Funzionano su un timer interno che rilegge i tuoi log di accesso SSH e NGINX ogni minuto — ma solo mentre la TUI o l'interfaccia web è in esecuzione. Una delle due mantiene lo stesso programma, nello stesso database, quindi lasciare attiva l'interfaccia web è sufficiente; nulla viene rilevato quando nessuna delle due è in esecuzione. Per un server senza alcun processo stop-bots, vedi Unattended, from cron qui sotto.
/.env, /.git/config,
/wp-config.php e simili è conclusiva di per sé, quindi questo non richiede soglia. La
lista integrata omette deliberatamente percorsi che sono legittimi da qualche parte — /wp-login.php,
/wp-admin/, /xmlrpc.php, /phpmyadmin — poiché bloccare il tuo stesso amministratore sarebbe
peggio che mancare uno scanner che il rilevatore 404 intercetta comunque. Aggiungi i tuoi con
set-probe-paths.Disallow: nel robots.txt generato e linkato
da nessuna parte. Raggiungerlo significa ignorare robots.txt, cosa che nulla di legittimo fa per caso —
il segnale più forte qui, e il blocco più lungo. Richiede che la generazione di robots.txt sia attivata per
funzionare.Altri tre esaminano come un client si comporta anziché cosa chiede. Tutti e tre sono disattivati per impostazione predefinita, perché ciascuno ha un falso positivo che non può escludere da solo — e tutti e tre esentano i crawler dei motori di ricerca verificati, che altrimenti corrisponderebbero a ognuno di essi:
304 conta come asset recuperato).
Non può aiutarti su un sito che non serve alcun asset — una pura API JSON.Referer. Indebolito da
Referrer-Policy: no-referrer e dagli strumenti per la privacy; la soglia di percorsi distinti è ciò che
lo rende utilizzabile./24 vengono segnalati
nello stesso passaggio, blocca il /24. Disattivato per impostazione predefinita — bloccare 256 indirizzi perché tre
si sono comportati male è un danno collaterale per design. (IPv6 è diverso e non richiede interruttore: un rilevamento
blocca sempre il /64, perché un /64 è una LAN, la stessa cosa che rappresenta un singolo indirizzo IPv4.
Bloccare il singolo indirizzo che un attaccante IPv6 ha usato per caso non fermerebbe nulla
— ne hanno altri 2^64.)Tutto quanto sopra è generato. Se qualcosa di esso sia in vigore è una domanda
separata, e stop-bots status è quello che risponde:```
stop-bots status
Sette controlli, e il primo è quello che vale la pena avere: le regole generate
sono effettivamente nel kernel, o solo su disco? Un host reale ha funzionato per tre settimane con
48.860 regole di drop in `/etc/stop-bots/firewall.nft` e un ruleset vuoto,
perché scrivere lo script e caricarlo sono due passaggi e nessuno aveva mai
guardato il secondo.
Il resto: il ruleset sopravvivrà a un riavvio (`nftables.service` abilitato?), lo
script corrisponde ancora alle regole, i blocchi NGINX sono applicati, il servizio
della console sta eseguendo il binario che dichiara, c'è spazio per il database, e i
rilevatori riescono a leggere i loro log.
Esce con codice diverso da zero se qualcosa è **CRITICAL**, quindi funziona come controllo
di monitoraggio. `--quiet` stampa solo ciò che richiede attenzione, che è la forma per cron:```
0 * * * * /usr/local/bin/stop-bots status --quiet
Un controllo che non è riuscito a essere eseguito — nft list richiede i privilegi di root — riporta UNKNOWN, mai
OK. Un controllo di integrità che dice che va tutto bene perché non ha potuto guardare è
peggio di nessun controllo, perché viene creduto.
Lo stesso report è sulla Dashboard sia nella console che nella TUI, acquisito
ogni ora dal cron interno anziché a ogni render: nft list su un grande
ruleset è megabyte di testo.
Ogni decisione sul firewall di cui sopra è generata, mai applicata automaticamente: render-firewall
(o il tasto f della Dashboard) scrive uno script iptables o nftables che puoi rivedere e applicare
da solo, e rifiuta di scriverne uno che bloccherebbe una sessione SSH attualmente connessa.
Tre cose possono applicarlo per te, e tutte e tre richiedono che tu lo chieda: il popup di render della TUI
("apply after writing") o il suo tasto a, il pannello firewall della console web ("run it after
writing") o il suo pulsante "Apply everything", e batch --apply da un crontab che hai scritto — vedi
Unattended, from cron. Nessuno di essi è un effetto collaterale di qualcosa
di automatico: il cron interno genera lo script e non lo esegue mai.
Lo stesso vale sul lato NGINX: cambiare un'impostazione cambia solo ciò che sarebbe scritto.
Site settings mostra ogni sito come STALE finché non applichi.
Disattivare un rilevatore non rimuove mai i blocchi che ha già aggiunto — quelli scadono da soli.
"Stop detecting" e "undo what was detected" sono deliberatamente separati; il secondo è la
schermata Dynamic Protection o remove-firewall-rule.
C'è anche un semplice conteggio degli access log, indipendente dal blocco: record-access-stats /
list-access-stats contano quanto spesso ciascun user agent compare nelle richieste riuscite (non di errore),
così puoi vedere chi sta effettivamente visitando oltre a chi viene bloccato.
stop-bots batch è un'unica passata su tutto ciò che la TUI fa manualmente: aggiorna ogni lista,
analizza i log, scrive le regole di blocco NGINX e lo script del firewall.```
0 4 * * * root /usr/local/bin/stop-bots batch --apply --ssh-log /var/log/auth.log
*/10 * * * * root /usr/local/bin/stop-bots batch --apply --no-fetch --ssh-log /var/log/auth.log
Non dice nulla quando tutto ha funzionato, quindi un'esecuzione notturna sana non ti invia email. Un passo fallito stampa su stderr e imposta uno stato di uscita non-zero, ed è questo che fa sì che cron ti avvisi. Eseguilo una volta a mano con `--verbose` prima — stampa una riga per passo, ed è il modo più semplice per vedere cosa sta effettivamente facendo.
**`--apply` è ciò che gli fa applicare qualcosa.** Senza di esso, `batch` scrive la configurazione NGINX e lo script del firewall e si ferma: la configurazione non fa nulla finché non viene ricaricata, uno script non fa nulla finché non viene eseguito. Questo è il default di questo progetto ovunque, e resta il default anche qui.
`batch` e un front-end a lunga esecuzione coesistono in sicurezza. La TUI, la web UI e `batch` registrano tutti ciò che hanno fatto attraverso le stesse chiavi nello stesso database, quindi chi arriva per primo a un job lo esegue e gli altri lo trovano non più dovuto — non ottieni due passaggi di rilevamento, e il pannello "Scheduled tasks" della Dashboard mostra cosa è effettivamente accaduto invece di dichiarare che tutto è in ritardo. Se lasci già la web UI in esecuzione, la voce notturna di `batch` è una cintura e bretelle più che un requisito; se non lo fai, è l'unica cosa che mantiene il rilevamento aggiornato.
**Con `--apply`, la protezione contro il lockout SSH può rifiutarsi — e rifiutarsi significa che non viene applicato nulla.** Si rifiuta se le regole bloccherebbero un client attualmente connesso, *e* se non è stato possibile leggere alcun log SSH, perché in tal caso il controllo non potrebbe essere eseguito. Il comando interattivo `render-firewall` stampa solo una nota in quel secondo caso, sul ragionamento che un umano sta guardando il terminale; da cron nessuno lo fa. **Passa `--ssh-log` esplicitamente**: cron viene eseguito come root quindi `/var/log/auth.log` di solito si legge bene, ma su un host solo-journald `journalctl` sotto cron può tornare vuoto, che è esattamente il caso in cui si rifiuta. `--force` sovrascrive la protezione se fai sul serio.
Un passo che fallisce non ferma mai gli altri, e le metà NGINX e firewall sono indipendenti — un reload NGINX fallito lascia comunque il firewall applicato, e viceversa.
`batch` registra ogni passo rispetto allo stesso schedule che usa il cron interno della TUI, quindi i due concordano su cosa è già stato eseguito invece di farlo entrambi, e il pannello "Scheduled tasks" della Dashboard mostra cosa ha fatto il tuo cron reale.
# La web UI
`stop-bots web` serve le stesse cinque schermate in un browser.```
stop-bots web
Si associa a 127.0.0.1:8787 — raggiungibile solo da quella macchina — e stampa una password generata una sola volta, al primo avvio. Raggiungilo dal tuo laptop tramite un tunnel SSH:``` ssh -L 8787:127.0.0.1:8787 your-server
poi apri <http://127.0.0.1:8787/>.

La console segue l'impostazione chiara o scura del sistema operativo, con un interruttore
nell'intestazione; gli screenshot della TUI sopra sono il tema scuro, questi quello chiaro. I tasti che la
TUI utilizza funzionano anche qui: `1`–`4` cambiano schermata, `/` porta il focus sulla casella di ricerca, `?` apre la Guida.

Tre azioni a livello host si trovano nell'intestazione, nel browser come pulsanti e nella TUI
come singoli tasti:
- **Update everything** (`u`) scarica ogni lista di bot, ogni intervallo IP di crawler, ogni
feed di reputazione *abilitato* e ogni paese *selezionato* — lo stesso insieme che
`stop-bots batch` recupera, dallo stesso piano. Il fallimento di una singola fonte non ferma le altre, e nulla viene
applicato finché qualcosa non lo mette in atto.
- **Apply everything** (`a`) scrive e ricarica la configurazione NGINX, poi scrive ed esegue lo
script del firewall. I due piani sono indipendenti: qualunque dei due fallisca, l'altro ha comunque il suo
turno, perché un host applicato a metà è meglio di uno in cui un errore di sintassi NGINX ha anche lasciato
il firewall obsoleto.
- **Web Access** (`w`) configura NGINX per servire la console stessa — vedi
[Behind NGINX](#behind-nginx-a-subdomain-or-a-path-prefix).
## Come servizio (Debian)```
sudo stop-bots install web
Scrive /etc/systemd/system/stop-bots-web.service, crea /var/lib/stop-bots (0700 — contiene
l'hash della password della console) e /etc/stop-bots, genera una password se non ne esiste
una, e abilita e avvia l'unità.
--dry-run stampa l'intero piano e non modifica nulla. Questo è l'unico comando nel
progetto che avvia un demone, quindi inizia da lì. --prefix <dir> scrive lo stesso albero in un
posto che puoi leggere senza root. Se l'unità esiste già e l'hai modificata, l'
installer si ferma e lo segnala invece di sostituire la tua modifica; --force se lo intendevi davvero.
Il servizio viene eseguito come root, perché la console riscrive /etc/nginx, scrive lo script
del firewall, ed esegue nginx -t e systemctl reload nginx. Non esiste una separazione non
privilegiata che lasci intatto il set di funzionalità. L'unità porta con sé l'hardening che
sopravvive a quel requisito e un commento che dice quale hardening è stato omesso e perché.
L'indirizzo di bind, la allowlist degli host e il prefisso del percorso sono deliberatamente non
nell'unità — il server in esecuzione li rilegge dal database, quindi metterli in ExecStart darebbe
loro due fonti di verità. Modificali con stop-bots web --save ... e riavvia.
Una cosa cambia una volta che questo viene eseguito come root: il job giornaliero RenderFirewall
del cron interno può ora scrivere /etc/stop-bots/firewall.nft, cosa che non poteva fare quando eseguivi la console
a mano come te stesso. Nulla applica quello script — eseguirlo è ancora compito tuo.
Viene verificato solo Debian, perché è quello che è stato testato; l'unità è molto probabilmente corretta su qualsiasi distribuzione systemd, ma il percorso del log SSH che assume è quello di Debian.
Il binding di qualsiasi cosa che non sia loopback richiede un secondo flag deliberato, perché questa console può riscrivere il firewall e la configurazione NGINX dell'host su cui viene eseguita:``` stop-bots web --bind 0.0.0.0:8787 --expose --allowed-hosts admin.example.com --save
`--allowed-hosts` non è opzionale in pratica: una richiesta che porta un nome host che non è
elencato viene rifiutata. È questo che fa fallire il DNS rebinding contro la console, ed è
il motivo per cui un server esposto raggiunto per nome necessita che il nome sia specificato esplicitamente.
Mettilo dietro NGINX con TLS — lo stesso NGINX che questo strumento sta proteggendo. Se lo fai, e il
proxy imposta `X-Forwarded-For`, dì alla console che può fidarsi di quell'header, altrimenti non può
determinare da quale indirizzo provenga realmente una richiesta:```
stop-bots web --bind 127.0.0.1:8787 # and set web:trust_forwarded_for
Dietro TLS, imposta anche web:secure_cookie. Senza di esso un browser invierà il cookie
di sessione anche a un URL http:// per lo stesso host.
web:trust_forwarded_for è più importante di quanto sembri. Senza di esso ogni richiesta dietro un
proxy arriva da 127.0.0.1, quindi la console non può distinguere un client da un altro — il che
significa che una raffica di tentativi di login condivide lo stesso bucket di throttle che usi tu, e la guardia che
impedisce di bloccare il tuo stesso indirizzo non ha nulla con cui confrontarsi. Con esso, entrambi funzionano
per-client.
La console può configurarlo per te, e anche la TUI (w sulla Dashboard). Entrambe
scrivono la configurazione NGINX, registrano il prefisso di percorso e aggiungono il nome host alla allowlist — le
tre cose che devono concordare, perché un prefisso mancante fa uscire ogni link dal
blocco location e un nome host mancante rende ogni richiesta un 403. Entrambe validano con
nginx -t prima che la configurazione possa avere effetto, la annullano se fallisce, e registrano il
nuovo indirizzo solo una volta validato.
Due modalità, e path è quella predefinita per un motivo: aggiunge un blocco location a un sito che
hai già, quindi la console eredita il certificato di quel sito. Un sottodominio ne richiede uno proprio,
e finché certbot --nginx -d <host> non è stato eseguito, il modulo password e il cookie di sessione
di questa console attraversano la rete in chiaro.
Il resto di questa sezione è la stessa cosa fatta a mano, che vale la pena leggere una volta anche se usi il pannello — la trappola della barra finale qui sotto è l'errore che esiste per prevenire.
Un sottodominio è il deployment più semplice, e quello da scegliere se puoi:```nginx server { server_name stopbots.example.com; location / { proxy_pass http://127.0.0.1:8787; proxy_set_header Host $host; } }
## Installazione
### Requisiti
- Python 3.8+
- pip (gestore di pacchetti Python)
### Installazione tramite pip
```bash
pip install pycryptodome
git clone https://github.com/example/crypto-tool.git
cd crypto-tool
pip install -r requirements.txt
from crypto_tool import Cipher
# Inizializza il cifrario con una chiave
cipher = Cipher(key="your-secret-key")
# Cifra i dati
encrypted = cipher.encrypt("Hello, World!")
# Decifra i dati
decrypted = cipher.decrypt(encrypted)
print(decrypted) # Output: Hello, World!
from crypto_tool import Cipher, HashManager
# Crea un hash dei dati
hasher = HashManager(algorithm="sha256")
digest = hasher.hash("sensitive data")
# Verifica l'integrità dei dati
is_valid = hasher.verify("sensitive data", digest)
print(is_valid) # Output: True
| Metodo | Descrizione |
|---|---|
encrypt(data) | Cifra i dati forniti utilizzando la chiave configurata |
decrypt(data) | Decifra i dati cifrati |
set_key(key) | Aggiorna la chiave di cifratura |
| Metodo | Descrizione |
|---|---|
hash(data) | Genera un hash dei dati di input |
verify(data, digest) | Verifica i dati rispetto a un hash |
Le opzioni di configurazione possono essere impostate tramite variabili d'ambiente:
CRYPTO_KEY - Chiave di cifratura predefinitaCRYPTO_ALGORITHM - Algoritmo da utilizzare (predefinito: aes-256)CRYPTO_LOG_LEVEL - Livello di logging (predefinito: INFO)Questo progetto è distribuito sotto la licenza MIT. Consultare il file LICENSE per i dettagli.``` stop-bots web --allowed-hosts stopbots.example.com --save
**Funziona anche un prefisso di percorso**, ma la console deve esserne informata — deve
generare ogni link, azione di form, reindirizzamento e percorso dei cookie con il prefisso già
incluso, e non può indovinarlo:```
stop-bots web --base-path /stop-bots --allowed-hosts example.com --save
| -s | --server | SERVER | http://localhost:8080 | URL del server MCP |
| -t | --token | TOKEN | - | Token di autenticazione |
| -v | --verbose | - | false | Abilita logging dettagliato |
| -h | --help | - | - | Mostra il messaggio di aiuto |
# Avvia il server MCP con trasporto stdio
mcp-server
# Avvia il server MCP con trasporto HTTP
mcp-server --transport http --port 8080
# Connettiti a un server MCP remoto
mcp-server --server http://localhost:8080 --token your-token
# Abilita logging dettagliato
mcp-server --verbose
# Clona il repository
git clone https://github.com/your-org/mcp-server.git
cd mcp-server
# Installa le dipendenze
npm install
# Compila il progetto
npm run build
# Esegui i test
npm test
mcp-server/
├── src/
│ ├── index.ts # Punto di ingresso principale
│ ├── server.ts # Implementazione del server
│ ├── tools/ # Implementazioni degli strumenti
│ │ ├── index.ts
│ │ └── example.ts
│ └── utils/ # Funzioni di utilità
│ └── logger.ts
├── tests/ # File di test
├── package.json
└── tsconfig.json
Per aggiungere un nuovo strumento, crea un nuovo file nella directory src/tools/:
import { Tool } from '@modelcontextprotocol/sdk/types.js';
export const myTool: Tool = {
name: 'my-tool',
description: 'Descrizione di cosa fa questo strumento',
inputSchema: {
type: 'object',
properties: {
param1: {
type: 'string',
description: 'Descrizione del parametro',
},
},
required: ['param1'],
},
};
export async function handleMyTool(args: { param1: string }) {
// Implementazione dello strumento
return {
content: [
{
type: 'text',
text: `Risultato: ${args.param1}`,
},
],
};
}
Il server non si avvia
Errori di connessione
Gli strumenti non funzionano
Abilita il logging dettagliato per eseguire il debug dei problemi:
mcp-server --verbose
I log vengono scritti su stderr e possono essere reindirizzati a un file:
mcp-server --verbose 2> server.log
I contributi sono benvenuti! Segui questi passaggi:
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)Questo progetto è rilasciato sotto la Licenza MIT - consulta il file LICENSE per i dettagli.
**La barra finale in `proxy_pass` è importante, e la sua assenza è l'intero trucco.**
Senza di essa, NGINX passa il percorso completo e `stop-bots` vede
`/stop-bots/whatever`, che è ciò che ora serve e genera. *Con* una barra
finale, NGINX rimuove il prefisso — e poi il browser risolve i link nella pagina
rispetto alla radice del dominio, finisce fuori dal blocco `location`, e tutto restituisce 404. Nessuna
quantità di attenzione da parte del server può risolvere questo, quindi il prefisso deve sopravvivere al
proxy.
Nulla lo impone dall'esterno, ma il fallimento è evidente piuttosto che sottile: con il
prefisso configurato, una richiesta senza prefisso è un semplice 404 piuttosto che una pagina che
funziona a metà.
## Cosa non farà
Due cose mancano di proposito, e la schermata di Aiuto lo dice con le motivazioni:
- **Non sbloccherà qualcosa che una lista scaricata ha bloccato** — il prossimo aggiornamento di quella
lista lo annullerebbe silenziosamente.
- **Non cambierà la propria password.** Usa `stop-bots web --set-password` sull'host.
Rifiuta anche di bloccare l'indirizzo da cui sei connesso, il che ti toglierebbe la
console che useresti per annullarlo.
**Una volta erano tre.** Applicare lo script del firewall era la terza, sulla base che
eseguirlo è l'unica operazione che può togliere l'host dalla rete. Ora è
disponibile — "Apply everything" sulla Dashboard (`a` nella TUI), o la casella "run it after
writing" nel pannello del firewall — perché la protezione che lo rende sicuro da cron lo rende sicuro da un
pulsante: le regole vengono verificate rispetto ai client attualmente connessi via SSH, nell'
ordine in cui lo script stesso le valuterà, e una regola che ne bloccherebbe uno è un
rifiuto piuttosto che un avviso. Avvia la console con `--no-apply` per riavere il vecchio
comportamento di sola scrittura.
I tentativi di login sono limitati. Non perché la password sia indovinabile — è generata,
144 bit — ma perché verificarne una esegue Argon2id, e lasciare che un chiamante non autenticato
lo guidi il più velocemente possibile è un attacco denial of service contro l'host che questo strumento
dovrebbe proteggere. Dieci tentativi errati sono gratuiti; oltre, un client rallenta
esponenzialmente, e un limite globale limita la CPU indipendentemente da quanti indirizzi
provengano i tentativi.
## Eseguire NGINX in un container
Se NGINX è in Docker e la sua configurazione è su un bind mount, `systemctl reload nginx` non ricarica
nulla. Punta i due comandi al container invece — questo vale anche per la CLI e la
TUI:```
stop-bots set-nginx-commands \
--test "docker exec web nginx -t" \
--reload "docker exec web nginx -s reload"
Il comando viene suddiviso in parole ed eseguito direttamente. Non passa mai attraverso una shell, quindi ;,
| e $VAR sono caratteri ordinari anziché sintassi.
Come è strutturato il codice, come viene testato e le regole secondo cui è scritto sono in CONTRIBUTING.md. Il processo di rilascio è in RELEASING.md.
Puoi contattarmi all'indirizzo [email protected].
Copyright (C) 2026 Marko Ivankovic
Questo programma è software libero: puoi ridistribuirlo e/o modificarlo secondo i termini della GNU Affero General Public License come pubblicata dalla Free Software Foundation, versione 3 della Licenza, o (a tua scelta) qualsiasi versione successiva.
Consulta il file LICENSE per il testo completo della Licenza.
Una licenza alternativa NON è disponibile.
| Regola | Respinge, oltre ai bot |
|---|
| HTTP/1.0 e HTTP/1.1 | crawler e client API che non parlano HTTP/2 |
Nessun header Accept | alcuni client API non ne inviano nessuno |
Nessun Accept-Language | gli strumenti per la privacy lo rimuovono |
User-Agent vuoto/assente | script e controlli di integrità spesso lo omettono |
Host è un IP nudo | impedisce di raggiungere il sito tramite IP |
| TLS 1.0 / 1.1 | solo client molto vecchi |