2010-03-22 1 views
6

Ho un ampio database di collegamenti, che sono tutti ordinati in modi specifici e sono allegati ad altre informazioni, che è prezioso (per alcune persone).Come proteggi un database di collegamenti dallo scraping?

Attualmente il mio setup (che sembra funzionare) chiama semplicemente un file php come link.php? Id = 123, registra la richiesta con un timestamp nel DB. Prima di sputare il link, controlla quante richieste sono state fatte da quell'IP negli ultimi 5 minuti. Se è maggiore di x, ti reindirizza a una pagina captcha.

Che tutto funzioni bene e dandy, ma il sito è diventato molto popolare (oltre a ricevere DDOs per circa 6 settimane), quindi php ha perso terreno, quindi sto cercando di minimizzare i tempi che devo colpire php per fare qualcosa. Volevo mostrare i collegamenti in testo normale invece che tramite link.php? Id = e avere una funzione onclick per aggiungere semplicemente 1 al conteggio delle visualizzazioni. Sto ancora cercando php, ma almeno se è in ritardo, lo fa in background, e l'utente può vedere subito il link che ha richiesto.

Il problema è che rende il sito VERAMENTE scaricabile. C'è qualcosa che posso fare per impedirlo, ma ancora non fare affidamento su php per fare il controllo prima di sputare il link?

+1

Approccio errato, direi. Probabilmente puoi ottimizzare il tuo codice in modo che funzioni abbastanza velocemente per i tuoi scopi. – alex

+2

Prova a prevenirlo con l'avvocato. – Jacco

+2

NON cercare di impedirlo usando javascript poiché la maggior parte degli screen saver non esegue nemmeno javascript. –

risposta

2

Sembra che il collo di bottiglia si trovi nel database. Ogni richiesta esegue un inserimento (registra la richiesta), quindi seleziona (determina il numero di richieste dall'IP negli ultimi 5 minuti) e quindi qualsiasi operazione del database è necessaria per eseguire la funzione principale dell'applicazione.

Considerare di mantenere i dati di limitazione della richiesta (IP, tempo di richiesta) nella memoria del server anziché gravare sul database. Due soluzioni sono memcache (http://www.php.net/manual/en/book.memcache.php) e memcached (http://php.net/manual/en/book.memcached.php).

Come altri hanno notato, assicurarsi che esistano indici per qualsiasi chiave richiesta (campi come l'id del collegamento). Se sono presenti indici e il database soffre ancora del carico, provare un acceleratore HTTP come Varnish (http://varnish-cache.org/).

+0

Non è così. Il server DB non subisce alcun tipo di stress. –

+0

Hai confrontato il codice PHP per determinare quale codice è la fonte del collo di bottiglia? – sutch

+0

Per aggiungere a ciò che sta dicendo @sutch, il problema è probabilmente con l'inserimento e la lettura simultanei del database. Se non controlli l'apache e non riesci a impostare il Throttling IP come nella risposta di @ chris, dovresti almeno non leggere l'elenco IP durante il tempo richiesto. Insertint va bene, quindi basta eseguire uno script ogni 5 minuti che legge la tabella e analizza un elenco di tutti gli indirizzi IP vietati e lo inserisce in un file di testo in chiaro. Quindi crea lo script, durante ogni richiesta apri quel file e controlla se l'IP si trova su quell'elenco. (Il migliore sarebbe farlo in memoria invece che nel file). – arnorhs

0

Controlla il tuo database. Stai indicizzando tutto correttamente? Una tabella con così tante voci diventerà molto veloce e lenta. Si potrebbe anche voler eseguire un processo notturno che cancella le voci più vecchie di 1 ora, ecc.

Se nessuna di queste funzioni, si sta verificando l'aggiornamento/il bilanciamento del carico del server. Il collegamento diretto alle pagine ti compererà solo così tanto tempo prima di dover aggiornare comunque.

+0

Mysql non è il problema. Il server Mysql è sottoutilizzato, dal momento che tutto è memcached e ottimizzato come un inferno. Connessioni PHP è ciò che lo fa. Se non ci sono stati attacchi, il server può gestirli senza problemi. –

+1

Hai confrontato il codice PHP per determinare quale codice è la fonte del collo di bottiglia? – sutch

+1

@Yegor - Quindi in pratica il vero problema è che il server non può gestire un attacco DDOS. Dovresti farne la radice della tua domanda. –

0

La maggior parte dei ruspanti analizza solo l'HTML statico, quindi codifica i collegamenti e li decodifica dinamicamente nel browser Web del client con JavaScript.

I raschietti determinati possono ancora aggirare questo problema, ma possono aggirare qualsiasi tecnica se i dati sono abbastanza validi.

+0

sarebbe più utile lasciare un commento che solo un downvote ... – hoju

0

Ogni cosa che fai sul lato client non può essere protetta, perché non usare solo AJAX?

Avere un evento onClick che chiama una funzione Ajax, che restituisce solo il collegamento e lo compila in un DIV sulla pagina, in modo che la dimensione della richiesta sia ridotta, funzionerà in modo rapido per quello che ti serve. Assicurati che nella funzione che chiami per controllare il timestamp, è facile creare uno script che richiami quella funzione più volte per sincronizzare i tuoi link.

È possibile controllare jQuery o altre librerie AJAX (utilizzo jQuery e sAjax). E ho un sacco di pagine che cambiano dinamicamente i contenuti molto velocemente, il client non sa nemmeno che non è puro JS.

+0

Ancora dovuto eseguire una query di selezione, che sconfigge completamente lo scopo. –

+0

Il mio male non ho visto la parte in cui hai detto che non vuoi usare PHP :) Se usi solo script sul lato client non c'è alcun metodo per prevenire i slayer, ti rendi JS minimizzato, codificalo e rendere variabili e funzionare con nomi che non hanno una funzione di significato a(), var a_0 ecc ..., questo impedirà il 90% di scrapers (principianti) ma non impedirà quelli avanzati :( Se si dispone delle informazioni da mysql al primo caricamento della pagina, potresti salvarlo in SESSION e quindi usare AJAX solo per leggere dalla sessione (usa ancora PHP, ma non interrogare di nuovo il database.) –

+0

Il problema del DB non è un problema, è senza stress. PHP è ciò che voglio mantenere al minimo, eseguo la query di aggiornamento con ajax in background, quindi anche se si blocca per 2-3 secondi, non è un grosso problema, ma quando si blocca per 2-3 secondi prima di caricare il link , è un grande affare. La soluzione JS sembra l'unica strada da percorrere .... –

1

Si potrebbe eseguire il controllo ip a livello di server Web. Forse esiste un modulo per il tuo webserver, o come esempio, usando apache puoi scrivere la tua riscrittura e consultare un programma demone in modo da poter fare cose più complesse. Avere il programma demone interrogare un database di memoria. Sarà veloce.