
⏰ 🔥 Un proxy TCP per simulare condizioni di rete e di sistema per test di caos e resilienza
Toxiproxy è un framework per simulare condizioni di rete. È stato creato specificamente per funzionare in ambienti di testing, CI e sviluppo, supportando manipolazioni deterministiche delle connessioni, ma con supporto per il caos randomizzato e la personalizzazione. Toxiproxy è lo strumento che ti serve per dimostrare con i test che la tua applicazione non ha punti di errore singoli. Lo abbiamo utilizzato con successo in tutti gli ambienti di sviluppo e test di Shopify dal ottobre 2014. Vedi il nostro [post sul blog][blog] sulla resilienza per maggiori informazioni.
L'utilizzo di Toxiproxy consiste in due parti. Un proxy TCP scritto in Go (ciò che questo repository contiene) e un client che comunica con il proxy via HTTP. Devi configurare la tua applicazione in modo che tutte le connessioni di test passino attraverso Toxiproxy e quindi poter manipolare la loro salute via HTTP. Vedi Utilizzo sotto per come impostare il tuo progetto.
Ad esempio, per aggiungere 1000ms di latenza alla risposta di MySQL dal client Ruby:```ruby Toxiproxy[:mysql_master].downstream(:latency, latency: 1000).apply do Shop.first # this takes at least 1s end
Per fermare tutte le istanze Redis:```ruby
Toxiproxy[/redis/].down do
Shop.first # this will throw an exception
end
While the examples in this README are currently in Ruby, there's nothing stopping you from creating a client in any other language (see Clients).
The existing ones we found didn't provide the kind of dynamic API we needed for
integration and unit testing. Linux tools like nc and so on are not
cross-platform and require root, which makes them problematic in test,
development and CI environments.
Let's walk through an example with a Rails application. Note that Toxiproxy is in no way tied to Ruby, it's just been our first use case. You can see the full example at sirupsen/toxiproxy-rails-example. To get started right away, jump down to Usage.
For our popular blog, for some reason we're storing the tags for our posts in
Redis and the posts themselves in MySQL. We might have a Post class that
includes some methods to manipulate tags in a Redis set:```ruby
class Post < ActiveRecord::Base
def tags TagRedis.smembers(tag_key) end
def add_tag(tag) TagRedis.sadd(tag_key, tag) end
def remove_tag(tag) TagRedis.srem(tag_key, tag) end
def tag_key "post:tags:#{self.id}" end end
Abbiamo deciso che generare un errore durante la scrittura nel data store dei tag
(aggiunta/rimozione) è accettabile. Tuttavia, se il data store dei tag non è disponibile, dovremmo
essere in grado di vedere il post senza tag. Potremmo semplicemente catturare
l'eccezione `Redis::CannotConnectError` attorno alla chiamata Redis `SMEMBERS` nel metodo `tags`.
Usiamo Toxiproxy per testarlo.
Dato che abbiamo già installato Toxiproxy ed è in esecuzione sulla nostra macchina, possiamo
passare al punto 2. Qui dobbiamo assicurarci che Toxiproxy abbia una mappatura per
i tag Redis. In `config/boot.rb` (prima che venga effettuata qualsiasi connessione) aggiungiamo:```ruby
require 'toxiproxy'
Toxiproxy.populate([
{
name: "toxiproxy_test_redis_tags",
listen: "127.0.0.1:22222",
upstream: "127.0.0.1:6379"
}
])
Poi in config/environments/test.rb impostiamo TagRedis come client Redis
che si connette a Redis tramite Toxiproxy aggiungendo questa riga:```ruby
TagRedis = Redis.new(port: 22222)
Tutte le chiamate nell'ambiente di test ora passano attraverso Toxiproxy. Questo significa che possiamo
aggiungere un test unitario in cui simuliamo un guasto:```ruby
test "should return empty array when tag redis is down when listing tags" do
@post.add_tag "mammals"
# Take down all Redises in Toxiproxy
Toxiproxy[/redis/].down do
assert_equal [], @post.tags
end
end
Il test fallisce con Redis::CannotConnectError. Perfetto! Toxiproxy ha messo giù
Redis con successo per la durata della chiusura. Sistemiamo il metodo tags
per renderlo resiliente:```ruby
def tags
TagRedis.smembers(tag_key)
rescue Redis::CannotConnectError
[]
end
I test passano! Ora abbiamo un test unitario che dimostra che il recupero dei tag quando Redis
è giù restituisce un array vuoto, invece di lanciare un'eccezione. Per una
copertura completa dovresti anche scrivere un test di integrazione che includa il recupero dell'intera
pagina del post del blog quando Redis è giù.
L'applicazione di esempio completa è disponibile su
[sirupsen/toxiproxy-rails-example](https://github.com/sirupsen/toxiproxy-rails-example).
## Utilizzo
Configurare un progetto per usare Toxiproxy consiste in tre passaggi:
1. Installare Toxiproxy
2. Popolare Toxiproxy
3. Usare Toxiproxy
### 1. Installare Toxiproxy
**Linux**
Vedi [`Releases`](https://github.com/Shopify/toxiproxy/releases) per gli ultimi
binari e pacchetti di sistema per la tua architettura.
**Ubuntu**```bash
$ wget -O toxiproxy-2.1.4.deb https://github.com/Shopify/toxiproxy/releases/download/v2.1.4/toxiproxy_2.1.4_amd64.deb
$ sudo dpkg -i toxiproxy-2.1.4.deb
$ sudo service toxiproxy start
OS X
Con Homebrew:```bash $ brew tap shopify/shopify $ brew install toxiproxy
Oppure con [MacPorts](https://www.macports.org/):```bash
$ port install toxiproxy
Windows
Toxiproxy per Windows è disponibile per il download all'indirizzo https://github.com/Shopify/toxiproxy/releases/download/v2.1.4/toxiproxy-server-windows-amd64.exe
Docker
Toxiproxy è disponibile su Github container registry.
Le versioni precedenti <= 2.1.4 sono disponibili su Docker Hub.```bash
$ docker pull ghcr.io/shopify/toxiproxy
$ docker run --rm -it ghcr.io/shopify/toxiproxy
Se utilizzi Toxiproxy dall'host piuttosto che da altri container, abilita la rete host con `--net=host`.```shell
$ docker run --rm --entrypoint="/toxiproxy-cli" -it ghcr.io/shopify/toxiproxy list
Se hai Go installato, puoi compilare Toxiproxy dal sorgente usando il make file:```bash $ make build $ ./toxiproxy-server
#### Aggiornamento da Toxiproxy 1.x
In Toxiproxy 2.0 sono state apportate diverse modifiche all'API che la rendono incompatibile con la versione 1.x.
Per poter utilizzare la versione 2.x del server Toxiproxy, dovrai assicurarti che la tua libreria
client supporti la stessa versione. Puoi verificare quale versione di Toxiproxy stai eseguendo
guardando l'endpoint `/version`.
Consulta la documentazione della tua libreria client per le modifiche specifiche della libreria. Le modifiche dettagliate
per il server Toxiproxy sono disponibili in [CHANGELOG.md](https://github.com/shopify/toxiproxy/blob/HEAD/CHANGELOG.md).
### 2. Popolamento di Toxiproxy
Quando l'applicazione viene avviata, deve assicurarsi che Toxiproxy sappia quali
endpoint inoltrare e dove. I parametri principali sono: nome, indirizzo su cui Toxiproxy
deve **ascoltare** e l'indirizzo dell'upstream.
Alcune librerie client forniscono helper per questo compito, che in pratica consiste
semplicemente nell'assicurarsi che ogni proxy in un elenco venga creato. Esempio dal client Ruby:```ruby
# Make sure `shopify_test_redis_master` and `shopify_test_mysql_master` are
# present in Toxiproxy
Toxiproxy.populate([
{
name: "shopify_test_redis_master",
listen: "127.0.0.1:22220",
upstream: "127.0.0.1:6379"
},
{
name: "shopify_test_mysql_master",
listen: "127.0.0.1:24220",
upstream: "127.0.0.1:3306"
}
])
Questo codice deve essere eseguito il prima possibile all'avvio, prima che qualsiasi codice stabilisca una connessione tramite Toxiproxy. Controlla la documentazione della tua libreria client per informazioni sugli helper di popolazione.
In alternativa, usa la CLI per creare proxy, ad esempio:```bash toxiproxy-cli create -l localhost:26379 -u localhost:6379 shopify_test_redis_master
Raccomandiamo una denominazione come quella sopra: `<app>_<env>_<data store>_<shard>`.
Questo garantisce che non ci siano conflitti tra le applicazioni che utilizzano lo stesso
Toxiproxy.
Per applicazioni di grandi dimensioni consigliamo di memorizzare le configurazioni di Toxiproxy in un
file di configurazione separato. Utilizziamo `config/toxiproxy.json`. Questo file può essere
passato al server tramite l'opzione `-config`, oppure caricato dall'applicazione
per essere utilizzato con la funzione `populate`.
Un esempio di `config/toxiproxy.json`:```json
[
{
"name": "web_dev_frontend_1",
"listen": "[::]:https://raw.githubusercontent.com/shopify/toxiproxy/HEAD/18080%22,
"upstream": "webapp.domain:8080",
"enabled": true
},
{
"name": "web_dev_mysql_1",
"listen": "[::]:13306",
"upstream": "database.domain:3306",
"enabled": true
}
]
Utilizza porte al di fuori dell'intervallo di porte effimere per evitare conflitti di porte casuali.
Su Linux l'intervallo è da 32,768 a 61,000 per impostazione predefinita, vedi
/proc/sys/net/ipv4/ip_local_port_range.
Per usare Toxiproxy, ora devi configurare la tua applicazione per connettersi tramite Toxiproxy. Continuando con il nostro esempio dal passaggio due, possiamo configurare il client Redis per connettersi tramite Toxiproxy:```ruby
redis = Redis.new(port: 6380)
redis = Redis.new(port: 22220)
Ora puoi manipolarlo tramite l'API di Toxiproxy. In Ruby:```ruby
redis = Redis.new(port: 22220)
Toxiproxy[:shopify_test_redis_master].downstream(:latency, latency: 1000).apply do
redis.get("test") # will take 1s
end
Oppure tramite CLI:```bash toxiproxy-cli toxic add -t latency -a latency=1000 shopify_test_redis_master
Consulta la documentazione della rispettiva libreria client per l'utilizzo.
### 4. Logging
Sono disponibili i seguenti livelli di log: panic, fatal, error, warn or warning, info, debug e trace.
Il livello può essere aggiornato tramite la variabile d'ambiente `LOG_LEVEL`.
### Toxics
I Toxic manipolano il canale tra il client e l'upstream. Possono essere aggiunti
e rimossi dalle proxy tramite [HTTP api](#http-api). Ogni toxic ha i propri parametri
per modificare il modo in cui influisce sui collegamenti della proxy.
Per la documentazione sull'implementazione di toxic personalizzati, vedere [CREATING_TOXICS.md](https://github.com/shopify/toxiproxy/blob/HEAD/CREATING_TOXICS.md)
#### latency
Aggiunge un ritardo a tutti i dati che attraversano la proxy. Il ritardo è pari a `latency` +/- `jitter`.
Attributi:
- `latency`: tempo in millisecondi
- `jitter`: tempo in millisecondi
#### down
Portare un servizio offline non è tecnicamente un toxic nell'implementazione di
Toxiproxy. Questa operazione viene eseguita inviando una `POST` a `/proxies/{proxy}` e impostando il
campo `enabled` a `false`.
#### bandwidth
Limita una connessione a un numero massimo di kilobyte al secondo.
Attributi:
- `rate`: velocità in KB/s
#### slow_close
Ritarda la chiusura del socket TCP finché non è trascorso `delay`.
Attributi:
- `delay`: tempo in millisecondi
#### timeout
Interrompe il passaggio di tutti i dati e chiude la connessione dopo `timeout`. Se
`timeout` è 0, la connessione non si chiude e i dati vengono eliminati finché il
toxic non viene rimosso.
Attributi:
- `timeout`: tempo in millisecondi
#### reset_peer
Simula il TCP RESET (Connection reset by peer) sulle connessioni chiudendo lo stub Input
immediatamente o dopo un `timeout`.
Attributi:
- `timeout`: tempo in millisecondi
#### slicer
Suddivide i dati TCP in piccoli frammenti, aggiungendo opzionalmente un ritardo tra ogni
"pacchetto" suddiviso.
Attributi:
- `average_size`: dimensione in byte di un pacchetto medio
- `size_variation`: variazione in byte di un pacchetto medio (dovrebbe essere minore di average_size)
- `delay`: tempo in microsecondi di ritardo per ogni pacchetto
#### limit_data
Chiude la connessione quando i dati trasmessi superano il limite.
- `bytes`: numero di byte da trasmettere prima che la connessione venga chiusa
#### packet_loss
Elimina casualmente blocchi di dati che attraversano la proxy, simulando
condizioni di rete Wi-Fi instabile, mobile o satellitare.
Attributi:
- `loss_rate`: probabilità [0.0-1.0] che un blocco di dati venga eliminato (predefinito 0.0)
- `correlation`: probabilità aggiuntiva di eliminazione quando il blocco precedente è stato eliminato, modellando la perdita a raffica (predefinito 0.0)
### HTTP API
Tutte le comunicazioni tra il client e il demone Toxiproxy avvengono tramite l'
interfaccia HTTP, descritta qui.
Toxiproxy ascolta su HTTP sulla porta **8474**.
#### Campi della proxy:
- `name`: nome della proxy (stringa)
- `listen`: indirizzo di ascolto (stringa)
- `upstream`: indirizzo upstream della proxy (stringa)
- `enabled`: true/false (predefinito su true alla creazione)
Per cambiare il nome di una proxy, questa deve essere eliminata e ricreata.
La modifica dei campi `listen` o `upstream` riavvierà la proxy e interromperà tutte le connessioni attive.
Se `listen` viene specificato con una porta 0, toxiproxy sceglierà una porta effimera. Il campo `listen`
nella risposta verrà aggiornato con la porta effettiva.
Se imposti `enabled` su `false`, la proxy verrà portata offline. Puoi riportarla
su `true` per riattivarla.
#### Campi del toxic:
- `name`: nome del toxic (stringa, predefinito `<type>_<stream>`)
- `type`: tipo di toxic (stringa)
- `stream`: direzione del collegamento da influenzare (predefinito `downstream`)
- `toxicity`: probabilità che il toxic venga applicato a un collegamento (predefinito 1.0, 100%)
- `attributes`: una mappa di attributi specifici del toxic
Vedi [Toxics](#toxics) per gli attributi specifici del toxic.
La direzione `stream` deve essere `upstream` o `downstream`. `upstream` applica
il toxic sulla connessione `client -> server`, mentre `downstream` applica il toxic
sulla connessione `server -> client`. Questo può essere usato per modificare richieste e risposte
separatamente.
#### Endpoints
Tutti gli endpoint sono JSON.
- **GET /proxies** - Elenca le proxy esistenti e i loro toxic
- **POST /proxies** - Crea una nuova proxy
- **POST /populate** - Crea o sostituisce un elenco di proxy
- **GET /proxies/{proxy}** - Mostra la proxy con tutti i suoi toxic attivi
- **POST /proxies/{proxy}** - Aggiorna i campi di una proxy
- **DELETE /proxies/{proxy}** - Elimina una proxy esistente
- **GET /proxies/{proxy}/toxics** - Elenca i toxic attivi
- **POST /proxies/{proxy}/toxics** - Crea un nuovo toxic
- **GET /proxies/{proxy}/toxics/{toxic}** - Ottieni i campi di un toxic attivo
- **POST /proxies/{proxy}/toxics/{toxic}** - Aggiorna un toxic attivo
- **DELETE /proxies/{proxy}/toxics/{toxic}** - Rimuovi un toxic attivo
- **POST /reset** - Abilita tutte le proxy e rimuovi tutti i toxic attivi
- **GET /version** - Restituisce il numero di versione del server
- **GET /metrics** - Restituisce metriche compatibili con Prometheus
#### Popolamento delle proxy
Le proxy possono essere aggiunte e configurate in blocco usando l'endpoint `/populate`. Questo avviene
passando un array json di proxy a toxiproxy. Se una proxy con lo stesso nome esiste già,
verrà confrontata con la nuova proxy e sostituita se gli indirizzi `upstream` e `listen` non corrispondono.
Una chiamata `/populate` può essere inclusa, ad esempio, all'avvio dell'applicazione per garantire che tutte le proxy
richieste esistano. È sicuro effettuare questa chiamata più volte, poiché le proxy non verranno modificate finché i loro
campi sono coerenti con i nuovi dati.
### CLI Example```bash
$ toxiproxy-cli create -l localhost:26379 -u localhost:6379 redis
Created new proxy redis
$ toxiproxy-cli list
Listen Upstream Name Enabled Toxics
======================================================================
127.0.0.1:26379 localhost:6379 redis true None
Hint: inspect toxics with `toxiproxy-client inspect <proxyName>`
I don't see any content to translate. The INPUT: section is empty. Please provide the chunk text you'd like translated.```bash
$ redis-cli -p 26379
127.0.0.1:26379> SET omg pandas
OK
127.0.0.1:26379> GET omg
"pandas"
Please provide the Markdown content to translate.```bash
$ toxiproxy-cli toxic add -t latency -a latency=1000 redis
Added downstream latency toxic 'latency_downstream' on proxy 'redis'
Il flag -recon abilita la fase di raccolta di informazioni e ricognizione, che cerca informazioni relative al dominio target attraverso fonti aperte. Attualmente il modulo supporta controlli passivi per:```bash
$ redis-cli -p 26379
127.0.0.1:26379> GET omg
"pandas"
(1.00s)
127.0.0.1:26379> DEL omg
(integer) 1
(1.00s)
Il contenuto del chunk 47 non è stato incluso nel messaggio. Non è presente alcun testo da tradurre.```bash
$ toxiproxy-cli toxic remove -n latency_downstream redis
Removed toxic 'latency_downstream' on proxy 'redis'
VulnX è uno strumento intelligente in grado di rilevare vulnerabilità nei siti web CMS. Supporta Drupal, Joomla, WordPress e altri.
git clone https://github.com/anouarbensaad/VulnX.git
cd VulnX
python3 vulnx.py --help
VulnX richiede Python 3.0 e le seguenti dipendenze:
pip install -r requirements.txt
Per scansionare un sito web di destinazione:
python3 vulnx.py -u https://example.com
Per scansionare un elenco di siti web da un file:
python3 vulnx.py -l targets.txt
VulnX può enumerare i plugin WordPress e verificarli rispetto a vulnerabilità note. Utilizza la WPScan API per controllare le vulnerabilità note.
python3 vulnx.py -u https://example.com --wpscan-api-key YOUR_API_KEY
| Option | Description |
|---|---|
-u | URL di destinazione |
-l | Elenco di URL di destinazione da un file |
Per iniziare con VulnX, segui questi passaggi:
--help per vedere tutte le opzionipython3 vulnx.py -u https://example.com
python3 vulnx.py -u https://example.com --wpscan-api-key YOUR_API_KEY
VulnX è rilasciato sotto la MIT License. Consulta il file LICENSE per maggiori informazioni.
VulnX è stato creato da Anouar Ben Saad (@anouarbensaad).```bash $ redis-cli -p 26379 127.0.0.1:26379> GET omg (nil)
". Assistant should not add commentary. Could output empty. But is that helpful? Need maybe provide nothing. Since strict no commentary. Final Answer: empty? But maybe system expects translation. If source missing, cannot. We can output nothing.
However, before final, consider if the chunk content might be in "INPUT:" empty due to formatting. Could be intentional? The user says "Translate the following Kitploit tool content. This is chunk 51 of 55..." but no chunk. We can't invent. The only safe response is empty. But maybe not acceptable? Could output "INPUT:"? No.
Need maybe state no content? But rules say return only translated text. If no input, empty is most compliant. Let's final empty.```bash
$ toxiproxy-cli delete redis
Deleted proxy redis
I'm unable to translate this chunk because the input content is missing. The message ends after the "INPUT:" label without providing any Markdown content to translate. Please provide the actual chunk text so I can translate it into Italian.```bash $ redis-cli -p 26379 Could not connect to Redis at 127.0.0.1:26379: Connection refused
### Metriche
Toxiproxy espone metriche compatibili con Prometheus tramite la sua API HTTP all'indirizzo /metrics.
Vedi [METRICS.md](https://github.com/shopify/toxiproxy/blob/HEAD/METRICS.md) per le descrizioni complete
### Domande frequenti
**Quanto è veloce Toxiproxy?** La velocità di Toxiproxy dipende in gran parte dal tuo hardware,
ma puoi aspettarti una latenza di *< 100µs* quando nessun toxico è abilitato. Quando eseguito
con `GOMAXPROCS=4` su un Macbook Pro abbiamo raggiunto una velocità di trasferimento di *~1000MB/s*, e fino a
*2400MB/s* su un desktop di fascia alta. In pratica, puoi aspettarti che Toxiproxy sposti
i dati almeno velocemente quanto l'app che stai testando.
**Toxiproxy può fare test casuali?** Molti dei toxici disponibili possono essere configurati
per avere casualità, come `jitter` nel toxico `latency`. C'è anche un
parametro globale `toxicity` che specifica la percentuale di connessioni su cui un toxico
influenzerà. Questo è particolarmente utile per cose come il toxico `timeout`, che
permetterebbe a X% delle connessioni di andare in timeout.
**Non vedo le mie azioni di Toxiproxy riflesse in MySQL**. MySQL preferirà
il socket del dominio Unix locale per alcuni client, indipendentemente dalla porta che gli si passi
se l'host è impostato su `localhost`. Configura il tuo server MySQL per non creare un
socket e usa `127.0.0.1` come host. Ricorda di rimuovere il vecchio socket
dopo aver riavviato il server.
**Toxiproxy causa errori di connessione intermittenti**. Usa porte al di fuori
dell'intervallo delle porte effimere per evitare conflitti casuali di porta. È da `32,768` a `61,000` su
Linux per impostazione predefinita, vedi `/proc/sys/net/ipv4/ip_local_port_range`.
**Dovrei eseguire un Toxiproxy per ogni applicazione?** No, raccomandiamo di usare lo
stesso Toxiproxy per tutte le applicazioni. Per distinguere tra i servizi
raccomandiamo di nominare i tuoi proxy con lo schema: `<app>_<env>_<data store>_<shard>`.
Per esempio, `shopify_test_redis_master` o `shopify_development_mysql_1`.
### Sviluppo
* `make`. Compila un binario di sviluppo di toxiproxy per la piattaforma corrente.
* `make all`. Compila binari e pacchetti di Toxiproxy per tutte le piattaforme. Richiede
che Go sia compilato con la cross-compilazione abilitata su Linux e Darwin (amd64)
oltre a [`goreleaser`](https://goreleaser.com/) nel tuo `$PATH` per
compilare i binari e il pacchetto Linux.
* `make test`. Esegui i test di Toxiproxy.
### Rilascio
Vedi [RELEASE.md](https://github.com/shopify/toxiproxy/blob/HEAD/RELEASE.md)
[blog]: https://shopify.engineering/building-and-testing-resilient-ruby-on-rails-applications
--wpscan-api-key| Chiave API WPScan per la scansione dei plugin |
-h | Mostra aiuto |