Namecheap.com - Cheap domain name registration, renewal and transfers - Free SSL Certificates - Web Hosting

Apache в качестве прокси сервера. Reverse Proxy & Forward Proxy.

Wednesday, November 24th, 2010

А вы знаете, что web-server Apache можно использовать как прокси сервер? Все что нужно – установить модуль mod_proxy.

Apache может быть сконфигурирован как forward proxy и как reverse proxy.

Forward Proxy – это промежуточный сервер, который находится между клиентом и оригинальным сервером. Для того, чтобы получить контент с оригинального сервера, клиент посылает запрос на прокси сервер который в свою очередь шлет запрос на оригинальный сервер и возвращает ответ клиенту. Клиент должен быть специально сконфигурирован для того, чтобы использовать форвард прокси для доступа к другим сайтам.

Как правило, форвард прокси служат для того, чтобы предоставлять интернет доступ клиентам которые находятся за файрволом. Форвард проки так же могут использовать кэширование (mod_cache) чтобы уменьшать интенсивность использования сети. Активировать forward proxy можно следующим образом :

Forward Proxy

ProxyRequests On
ProxyVia On
<Proxy *>
Order deny,allow
Deny from all
Allow from internal.example.com
</Proxy>

Форвард прокси можно активировать используя директиву ProxyRequest. Потому что форвард прокси позволяют клиенту получать доступ к произвольным сайтам, через ваш сервер и скрывать свои реальные данные (ip адрес, например) крайне необходимо, чтоб у вас было все в порядке с безопасностью сервера, и только авторизированные клиенты имели доступ к прокси.

Reverse proxy, наоборот, представляются клиенту как обычный веб-сервер. На стороне клиента не нужно проводить никакого конфигурирования. Клиент делает обычные запросы чтобы получить данные в пространстве имен реверс прокси. Далее реверс прокси решает куда послать этот запрос и возвращает ответ так, как будто ответ был послан самим прокси сервером.

Reverse Proxy

ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>

ProxyPass /foo http://foo.example.com/bar
ProxyPassReverse /foo http://foo.example.com/bar

Реверс прокси используют, например, чтобы предоставлять интернет пользователям доступ к серверу который находится за файрволом. Реверс прокси, так же могут быть использованы чтобы балансировать нагрузку между несколькими back-end серверами, или чтобы предоставлять кэширования для медленного бэк-энд сервера. Ну и реверс прокси может быть использованы для того, чтобы вонзить несколько серверов на одно и то же пространство URL адресов.

Реверс прокси активируют используя директиву ProxyPass или флаг [P] в директиве RewriteRule. Не нужно включать ProxyRequest чтобы сконфигурировать реверс прокси.

В соответствии с модульной архитектурой Apache, mod_proxy так же состоит из модулей :

  • mod_proxy: The core module deals with proxy infrastructure and configuration and managing a proxy request.
  • mod_proxy_http: This handles fetching documents with HTTP and HTTPS.
  • mod_proxy_ftp: This handles fetching documents with FTP.
  • mod_proxy_connect: This handles the CONNECT method for secure (SSL) tunneling.
  • mod_proxy_ajp: This handles the AJP protocol for Tomcat and similar backend servers.
  • mod_proxy_balancer implements clustering and load-balancing over multiple backends.
  • mod_cache, mod_disk_cache, mod_mem_cache: These deal with managing a document cache. To enable caching requires mod_cache and one or both of disk_cache and mem_cache.
  • mod_proxy_html: This rewrites HTML links into a proxy’s address space.
  • mod_xml2enc: This supports internationalisation (i18n) on behalf of mod_proxy_html and other markup-filtering modules. space.
  • mod_headers: This modifies HTTP request and response headers.
  • mod_deflate: Negotiates compression with clients and backends.

Очень мощная шутка, если использовать её можно конфигурировать сервер или даже сервера для поддержки проектов произвольной сложности. Если вы хотите добавить кэширование – луркайте mod_cache.

Типичная конфигурация выглядит так (файл конфига httpd.conf – найти его можно командой locate httpd.conf):

# слушать порт 6000
Listen 6000
# организуем виртуальный хост
<VirtualHost *:6000>
# определяем кто будет иметь доступ к прокси. в данном случае
# это будет любой пользователь с айпи 192.168.0.*
<IfModule mod_proxy.c>
ProxyRequests On
<Proxy *>
Order deny,allow
Deny from all
Allow from 192.168.0.0/255.255.255.0
</Proxy>
</IfModule>
# включаем форвард прокси
ProxyRequests On
# чтобы писался лог
CustomLog /vsr/log/proxy_log common
</VirtualHost>

Так же можно управлять заголовками (нужен модуль mod_headers), устанавливая значения согласно этой спецификации. Например так можно установить юзер агент и убрать реферер :

RequestHeader set User-Agent "Mozilla/5.0"
RequestHeader unset Referer

а так можно запретить куки :

Header unset Set-Cookie

Исходящие от браузера заголовки устанавливаются директивой RequestHeader.
Заголовки, приходящие клиенту (браузеру), устанавливаются директивой Header.

Более глубокие знания можно получить по адресу :
http://www.devshed.com/c/a/Administration/Using-Apache-As-A-Proxy-Server/

Как запустить скрипт с другого IP?

Friday, November 19th, 2010

Как правило, если вы берете VDS или Dedicated сервер, в комплект идет несколько дополнительных IP адресов, обычно 2 или 4, зависит от дата центра. Вы межете без проблем развешивать сайты на разные айпи, управляя записями DNS домена. А как запустить скрипт на не основном ip адресе сервера? Один из вариантов предложил Lorien – использовать прокси сервер – Squid. О том, как установить Squid я писал ранее. Короче говоря часто на одном ипе висит куча скриптов которые дрочат какие-то сервисы время от времени, и чтобы не натыкаться на бан или превышение лимитов API лучше всего распределить нагрузку между доступными ip адресами. Это потребует небольшой модификации скриптов, нужно будет направлять запросы через прокси. “Прозрачно” это можно сделать используя библиотеку socksipy-branch.

Чтобы перенаправлять запросы на другой ип адрес используется следующая хитрая схема : мы направляем запрос на ip:port откуда squid роутит его на айпи используя директиву tcp_outgoing_address.

route script to dedicated ip

Allows you to map requests to different outgoing IP addresses based on the username or source address of the user making the request.
Позволяет вам назначать запрос на другие исходящие IP адреса, основываясь на имени или адресе источника откуда юзер сделал запрос.

Осталось только настроить конфиг Squid’а нужным образом, естественно если ипов больше чем 2а лучше всего потратить 5 минут и написать скрипт который будет генерировать нужную последовательность директив :

# Говорим squid слушать нужные порты
# http_port 20000
# http_port 20001

# Создаём ACL правила
# acl p20000 myport 20000
# acl p20001 myport 20001

# С помощью созданных ACL правил выбираем нужный исходящий IP
# tcp_outgoing_address 78.109.20.226 p20000
# tcp_outgoing_address 78.109.20.227 p20001

Взял отсюда. Немного переделал приблизив скрипт к “боевым” условиям. Список айпи берет из файла ips.txt. Начальный порт задаем в start_port.

Внимание, лучше лишний раз проверить, чтобы на ипах ничего не висело. Делается это с помощью команды : netstat -tulnap

start_port = 2000
ips_list = [ item.strip() for item in open("ips.txt", "r").readlines()]

chunks = ([], [], [])

for num, ip in enumerate(ips_list):
    port = start_port + num
    chunks[0].append('http_port %d' % port)
    chunks[1].append('acl p%d  myport %d' % (port, port))
    chunks[2].append('tcp_outgoing_address %s p%d' % (ip, port))

for group in chunks:
    for line in group:
        print line
    print

print "-------------------------------\n"

Если кто знает более простой способ welcome в комменты. Я задавал это вопрос на freenode #linux (IRC канал), но практичного решения с ходу никто не предложил. Пока что единственный рабочий вариант предложил Lorien.

Прокси чекер на Python.

Sunday, November 14th, 2010

Как написать многопоточный прокси чекер на Python? Как нефиг делать =) Я уже писал немного о том как проверять прокси на alive, с тех пор прошло много времени и чекер немного усовершенствовался. Изначально я передал материал на форум Privatetalks, но теперь пришло время пополнить им блог. Исходные ходы поставляются как есть, в отрыве от контекста, собственно для тех кто шарит не составит труда доработать и реализовать многопоточность (на ActiveState и StackOverflow есть уже готовые решения по этой части).

Многопоточный чекер проксейВсе просто. Есть какая-то страница, которую нужно запрашивать через прокси, и проверят что там отдали. Помимо этой простейшей проверки на метод GET, есть еще проверки на POST и Cookie, некоторые прокси не держат, и поэтому часто бывают бесполезны для каких-то задач. Проверка на куки мне пока была не нужна, а вот проверку на POST я сделал.

TProxy – класс который обеспечивает работу с данными прокси. Такая тема в программировании называется – инкапсуляция.

На сервере нужно разместить несколько файлов с которыми будет взаимодействовать скрипт. Можно размещать и скрипт и эти файлы на одном сервере, я так и делал =) правда тогда будьте осторожны с многопоточностью у меня скрпит в 300 потоков бодро ложил апачи (не всегда, но бывало), на неслабом железе.
Предположим это index.php :

<html>
<head>
</head>
<body><h1>SIGNATURE</h1>
<h2>Real IP : xx.xx.xx.xx</h2>
<h2>IP : xx.xx.xx.xx</h2>
</body>
</html>

SIGNATURE – уникальный идентификатор страницы. должен совпадать с CHECK_STR. Еще нужно определить 2е “константы” CHECK_URL – урл где лежит вышеприведенная страница, и CHECK_MAX_TIMEOUT – максимальный таймаут (если отклик через прокси больше, то она помечается как bad) поставьте 2.0 для начала.
Как формируются Real IP и IP? Getting real IP address in PHP – вообщем с помощью этого кода нужно сформировать Real IP и IP.
А вот тут умные дядьки пишут как чекать геолокейшн – Check GEO Location. В принципе, я так понимаю таких сервисов много и можно долбить следующий если первый не вернул адекватный результат.

def check_proxy(proxy, need_country=False):
    """Check if proxy alive + anonymity and record proxy to file if we need this"""
    ip = TProxy(proxy)

    gt = urllib2.build_opener(urllib2.ProxyHandler({"http":ip.get_proxy()}))
    start_time = time.time()
    try:
        result = gt.open(CHECK_URL, timeout=CHECK_MAX_TIMEOUT)
        result = result.read()
    except (urllib2.URLError, socket.timeout, httplib.BadStatusLine, httplib.InvalidURL):
        ip.set_alive_status(False)
        return ip
    except:
        ip.set_alive_status(False)
        return ip

    ip.set_alive_status(True)
    ip.set_timout(time.time() - start_time)     # proxy response time

    # get ip and real ip values. check for anonymity
    search = re.compile(CHECK_STR)
    pattern = re.search(search, result)

    if pattern != None:
        ip.set_alive_status(True)
        search = re.compile("IP : \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
        ips = re.findall(search, result)
        # extract ip and real ip values from page
        if ips != []:
            try:
                real_ip = ips[0]
                given_ip = ips[1]
                if real_ip == given_ip:
                    ip.set_anonymous_status(True)
            except:
                ip.set_alive_status(False)
                return ip

        # check country
        if need_country:
            try:
                response = gt.open('http://api.hostip.info/get_html.php?ip=%s' % ip.get_host(), timeout=5).read()
                country = re.search('Country: (.*)', response)
                if country <> "":
                    ip.set_country(country.group(1))
                else:
                    ip.set_country('undefined')
            except:
                ip.set_country('undefined')
    return ip

Теперь как проверить на POST.

def generate_random_str(length=10):
    str = string.lowercase+string.digits
    return ''.join(random.sample(str, length))

def check_proxy_for_post(proxy):
    token = generate_random_str(20)
    try:
        gt = urllib2.build_opener(urllib2.ProxyHandler({"http":proxy}))
        post_data = urllib.urlencode({'zpost' : token})
        response = gt.open(CHECK_URL + "post.php", post_data, timeout=POST_MAX_TIMEOUT).read()
        # check token
        print response
        search = re.compile(token)
        pattern = re.search(search, response)
        if pattern != None:
            return True
        else:
            return False
    except HTTPError, e:
        print "Http error"
        return False
    except URLError, e:
        print "Url error"
        return False
    except:
        print "Unknown error"
        return False

Легко встраивается в функцию check_proxy приведенную выше. Нужно только немножко пошевелить мозгами.
в файл index.php добавляется форма :

<form action="post.php" "method="post">
<input type="text" name="zpost" value="post check">
<input type="submit" value="Check POST method">
</form>

В ту же папочку аккуратно ложится файлик

<html>
<body>
<h1><?php echo $_POST["zpost"]; ?></h1>
</body>
</html>

Вообщем код легко собирается в готовый продукт, добавляются фичи по вашему вкусу и вперед ура.
Кстати говоря готовый код недавно обнаружил на гитхабе – чекер прокси. Оттуда тоже можно взять несколько идей.

А еще нужно не жадничать и быть аккуратным т.к. ДЦ может абузить по подозрению в Netscan.

Понравилась статья? Зарегайся на форуме privatetalks – общайся с профессионалами.

Настройка своего прокси сервера Squid

Sunday, June 13th, 2010

Бывает банят по ипу социальные сети, или форумы, или нужно работать с нескольких аккаунтов, короче говоря нужен дополнительный айпи. Если есть свой сервер, где-нибудь в европе или США, то реализовать это довольно просто, нужно лишь поставить Squid :

Fedora/Centos : yum install squid
Ubuntu/Debian : sudo apt-get install squid

Поставим его на автозагрузку (при ребуте)

chkconfig squid on

Старт/Стоп/Рестарт (рестарт нужно делать при обновлении конфига)

service squid start
service squid stop
service squid restart

Посмотреть запущен ли Squid можно так :

pgrep squid

Файл конфигурации должен быть тут : /etc/squid/squid.conf
Если, вдруг, его там нет >>> whereis squid и внимательно втыкаем в показанные папки

По дефолту должно все быть настроено, единственное что нужно это указать свой ип с которого планируется пользоваться прокси.

acl my_work src 192.168.1.0/24
http_access allow my_work

Внимательно правите конфиг, там есть небольшая подъебка, которая неопытных пользователей линукса может ввести в ступор.

После всех объявлений идет такая строчка :

# And finally deny all other access to this proxy
http_access deny all

Т.е. запрет доступа от всего что не перечисленно выше, поэтому все настройки доступа нужно прописывать до этого. Если вам все равно что вашей проксей будут пользоваться все – делаете http_access allow all, тем самым разрешая доступ всему что имеет честь законнектится на 3128 порт. Между делом говоря, деволтный порт так же легко меняется в конфиге :

http_port 3128

Подробнее можно прочитать тут. Если у вас поднять файр, то все несколько сложнее, придется прописывать правила. Squid без проблем работает на OpenVZ контейнере, т.е. на VPS/VDS

Работа с Blogspot

Friday, September 4th, 2009

Да-да, теперь не лезет, в свое время многие постарались на славу, чтобы ушатать этот блогхост кодеками и прочими интересными вещами. Но тем не менее даже на данный момент блогспот можно использовать для привлечения траффика, хотя для этого теперь нужно приложить хоть какие-то усилия. Помимо этого хост можно использовать в качестве индексируемой базы данных (я например какое-то время сохранял результаты google hot trends), собрания каких-либо тематических ссылок. На самом деле вариантов масса, в результате будут получаться различные блоги, и если обновленеи будет поставленно на поток, то эти сайты в конечном итоге послужат фундаментом SEO-империи.

Помимо этого гугл любезно предоставляет API для работы с большей частью своих сервисов, все это дело регулярно апдейтится и документируется, скачать библиотеку для Python можно на официальной странице Google GData Python Client. В данном случае нас интересует работа с blogspot.com. Внутри архива Google GData есть подробная (и короткая) инструкция по установке пакетов (package) для Python.

По поводу использования, на активстэйт как обычно все уже сделали до нас, однако в этом примере мой питон выдает ошибку :
TypeError: CreatePost() takes exactly 6 arguments (5 given)
Это легко исправить, функция CreatePost() помимов всего прочего принимает список тэгов которые нужно добавить к посту. В примере не хватает как раз этого параметра, хз в чем прикол, возможно защита от дурака =) Я пофиксил баг (пример работы с blogspot через API), чтобы все запускалось без проблем, нужно только разобраться в коде и использовать уже готовые функции, единственная не поддающаяся автоматизации через API задача – регистрация аккаунтов, но гмыла можно купить, а регистрировать и оформлять блог или руками, или используя софт эмулирующий работу браузера вроде Human Emulator, хардкорные кодеры, конечно могут реализовать это через curl.

Работать через API конечно удобно, если собирать более-менее красивые блоги в небольшом количестве. В остальных случаях, крайне желательно использовать прокси и как вы понимаете этого (во всяком случае прямо) в API не предусмотрено, нужно или хитрить запуская код через различные проксификаторы или править код самой библиотеки.

Проверка прокси – простейший Proxy Checker.

Friday, August 14th, 2009

Недавно возникла задача проверять прокси из списка. Посмотрев в гугл, нашел следующий код :

import urllib2
import socket

def is_bad_proxy(pip):
    try:
        proxy_handler = urllib2.ProxyHandler({'http': pip})
        opener = urllib2.build_opener(proxy_handler)
        opener.addheaders = [('User-agent', 'Mozilla/5.0')]
        urllib2.install_opener(opener)
        req=urllib2.Request('http://www.example.com')  # change the URL to test here
        sock=urllib2.urlopen(req)
    except urllib2.HTTPError, e:
        print 'Error code: ', e.code
        return e.code
    except Exception, detail:
        print "ERROR:", detail
        return True
    return False

def main():
    socket.setdefaulttimeout(120)

    # two sample proxy IPs
    proxyList = ['125.76.226.9:80', '213.55.87.162:6588']

    for currentProxy in proxyList:
        if is_bad_proxy(currentProxy):
            print "Bad Proxy %s" % (currentProxy)
        else:
            print "%s is working" % (currentProxy)

if __name__ == '__main__':
    main()

Все просто, пытаемся открыть ресурс по адресу example.com (который 100% работает), если открыли – все ок, если нет – то нет. Подгрузить список проксей можно и из файла например так :

# Just load list from file
def LoadListFromFile(filename):
    result = []
    fileIn = open(filename, 'r')
    for line in fileIn:
        result.append(line.strip())
    fileIn.close()
    return result

My blog is Do-Follow


Пишу код, делаю сайты.
Check out my about.me profile!

парсинг сайтов, форумов, интернет магазинов

Want to subscribe?

istinspring twitter account
istinspring facebook account

 Subscribe in a reader Or, subscribe via email:
Enter your email address:  
Find entries :