А так же о всякой фигне
Давайте за пару минут напишем приложуньку на nodejs, которая будет сканировать интернеты в поисках открытых прокси серверов.
После беглого гугления по npmjs.org, я нашел пакетик с подходящим функционалом: portscanner. Из него нам понадобится только функция portscanner.checkPortStatus, и которую нам нужно обернуть в промис:
function Pscan(addr, port) { return new Promise( function(resolve) { portscanner.checkPortStatus(port, addr, function(error, status) { resolve(status); }); }); }
Наша Pscan будет использоваться в более расширенной функции, которая будет перебирать порты для сканирования и в случае нахождения открытого порта, возвращать его:
async function scan(addr, ports) { let strAddr = addr.join('.'); let testStart = new Date(); for (let port of ports) { let status = await Pscan(strAddr, port); if ( status === 'open' ) { let testTime = new Date() - testStart; console.log(colors.green(`${strAddr}:${port} time: ${testTime}`)); return { addr: strAddr, port: port, type: 'HTTP', time: testTime }; } } let testTime = new Date() - testStart; console.log(colors.red(`${strAddr} time: ${testTime}`)); return null; }
Далее нам потребуется немного магии по работе с ИП адресами. Нужны функции: увеличения ип адреса на 1, преобразования строкового адреса в массив байт и из массива байт в инт, для сравнения.
function parseIPv4(str) { let result = []; let parts = str.trim().split('.'); if ( parts.length != 4 ) { return null; } for (let part of parts) { let byte = parseInt(part); if ( byte < 0 ) { return null; } if ( byte > 255 ) { return null; } result.push(byte); } return result; } function incIPv4(addr) { addr[ 3 ]++; for (let index=3; index>0; index--) { if ( addr[ index ] > 255 ) { addr[ index - 1 ]++; addr[ index ] = 0; } } if ( addr[ 0 ] > 255 ) { return null; } return addr; } function Ipv4IntValue(addr) { return addr[ 3 ] + ( addr[ 2 ] * 255 ) + ( addr[ 1 ] * 255 * 255 ) + +( addr[ 1 ] * 255 * 255 * 255 ); }
И нам остаётся собрать этот пазл воедино, не забыв о псевдопараллелизме, чтобы не приходилось проверять адреса один за другим, а условно, сразу N адресов:
async function main() { if ( process.argv.length < 5 ) { console.error(colors.red('Not enough arguments, usage:')); console.log('node scanner.js ipv4_start_add ipv4_stop_addr out_file.csv [ optional pseudo_threads_count ]'); console.log('Example:'); console.log('node scanner.js 127.0.0.0 127.0.0.1 ./out_file.csv 5'); process.exit(1); } const startADDR = parseIPv4(process.argv[ 2 ]); const stopADDR = parseIPv4(process.argv[ 3 ]); const dstFile = process.argv[ 4 ]; let pseudoThreads = 1; if ( process.argv[ 5 ] ) { pseudoThreads = parseInt(process.argv[ 5 ]); } if ( startADDR === null ) { console.error(colors.red('Wrong start addr: ' + process.argv[ 2 ])); process.exit(1); } if ( stopADDR === null ) { console.error(colors.red('Wrong stop addr: ' + process.argv[ 3 ])); process.exit(1); } // prepare output file if ( !fs.existsSync(dstFile) ) { fs.writeFileSync(dstFile, outHeaders.join(',') + ' ', { encoding: 'utf8' }); } let curAddr = startADDR.map( item => item); let eof = false; let addrScanned = 0; let scanStart = new Date(); while ( !eof ) { let promises = []; for (let tc=0; tc<pseudoThreads; tc++) { addrScanned++; if ( curAddr === null ) {// The end of IPv4 network eof = true; break; } if ( Ipv4IntValue(curAddr) > Ipv4IntValue(stopADDR) ) { eof = true; break; } promises.push(scan(curAddr, defaultPorts)); curAddr = incIPv4(curAddr); } let results = await Promise.all(promises); let outString = ''; for (let result of results) { if ( result !== null ) { let cols = []; for (let header of outHeaders) { cols.push( result[ header ] ); } outString += cols.join(',') + ' '; } } if ( outString !== '' ) { fs.writeFileSync(dstFile, outString, { encoding: 'utf8', flag: 'a' }); } } console.log('Done!'); console.log('Addressess scaned:', addrScanned, 'scan time:', new Date() - scanStart, 'ms'); process.exit(); } main();
Ещё чтобы увеличить скорость проверки, мы не будем сканировать все 65к портов на каждом хосте, а просканируем только самые распространённые порты указанные в константе: const defaultPorts = [ 8000, 8080, 8888, 3128 ]
Результаты сканирования выведутся в консоль, а успешные сканы запишутся в .csv файл.
Давайте запустим эту хреновину:
node scanner.js 5.135.100.0 5.135.255.255 ./result.csv 100
За тестовое сканирование было опрошено 39937 адресов, было найдено 2173 открытых порта, и потрачено 647183 ms (~10 минут) времени.
Но это не значит, что на всех этих 2173 хостах работают именно прокси, это всего лиш найденные открытые порты, и даже если часть из них действительно прокси сервера, то они почти со 100% вероятностью закрыты авторизацией. По этому поиск открытых анонимных прокси дело долгое.
Что бы ускорить поиск, можно разбивать диапазоны ИП адресов на блоки и одновременно запускать несколько сканеров.
Готовый проект на гитлабе: https://gitlab.com/hololoev/http_proxy_scanner
Проверяем список прокси серверов на доступность, с помощью nodejs
Где взять бесплатные прокси? Часть 2: Парсим бесплатные прокси листы
Проверяем список прокси серверов на доступность, с помощью nodejs
Допустим у нас есть список прокси серверов в овер 9999 строк, и как обычно большая часть из них не работает. Нам же нужно выбрать только работоспособные, да ещё которые позволяют достучаться до конкретного сайта.
Где взять бесплатные прокси? Часть 2: Парсим бесплатные прокси листы
Тут проблем меньше, чем со сканированием всего интернета, нужно лишь скравлить несколько разных сайтов и слить списки проксей в 1 итоговый файл.