6.1 Навіщо вам проксі?

Зараз таке час, коли в кожній країні свій власний інтернет. Тепер під заборону потрапляють не окремі користувачі, а цілі сайти, домени, застосунки і навіть країни. Не дуже приємно. Але якщо ти програміст, то це не проблема — в інтернеті повно проксі-серверів...

Проксі-сервер (або просто проксі) — це проміжний сервер, який виконує роль посередника між клієнтом (наприклад, твоїм комп'ютером) і сервером, до якого ти намагаєшся отримати доступ. Проксі-сервер приймає запити від клієнта, пересилає їх до цільового сервера, отримує відповіді і відправляє їх назад клієнту.

У кожного великого продукту є принаймні кілька проксі-серверів, які виконують різні корисні функції. Наприклад, такі:

  • Анонімізація: Проксі-сервер може приховати справжню IP-адресу клієнта, надаючи анонімний доступ до інтернет-ресурсів. IP-адреса — це унікальний ідентифікатор пристрою в мережі, і її приховання допомагає зберегти конфіденційність користувача.
  • Кешування: Проксі-сервер може кешувати часто запитувані ресурси, що прискорює доступ до них і зменшує навантаження на мережеві ресурси. Наприклад, якщо багато користувачів запитують одну й ту ж веб-сторінку, проксі-сервер може зберегти її копію і віддавати її напряму, не звертаючись кожного разу до вихідного сервера.
  • Фільтрація контенту: Проксі-сервер може блокувати доступ до певних веб-сайтів або типів контенту, забезпечуючи контроль і безпеку.
  • Обхід обмежень доступу: Проксі-сервер може допомогти обійти регіональні обмеження доступу до контенту, надаючи доступ до ресурсів, заблокованих у певних географічних областях.
  • Логування і моніторинг: Проксі-сервер може вести журнал всіх запитів і відповідей, що дозволяє відстежувати і аналізувати мережевий трафік.

Принцип роботи проксі-сервера

  • Клієнт відправляє запит: Клієнтський пристрій (наприклад, комп'ютер або смартфон) відправляє запит на проксі-сервер.
  • Проксі-сервер обробляє запит: Проксі-сервер отримує запит, може змінити його (наприклад, додати або видалити заголовки) і пересилає його на цільовий сервер.
  • Цільовий сервер відповідає: Цільовий сервер обробляє запит і надсилає відповідь на проксі-сервер.
  • Проксі-сервер повертає відповідь клієнту: Проксі-сервер отримує відповідь від цільового сервера, може кешувати її для подальшого використання і пересилає її клієнту.

Переваги використання проксі-сервера

  • Покращення безпеки: Проксі-сервер може приховати внутрішні мережі від зовнішнього світу, зменшуючи ризик атак.
  • Прискорення доступу: Кешування часто запитуваних ресурсів знижує час доступу до них.
  • Контроль доступу: Проксі-сервер може обмежувати доступ до певних сайтів або типів контенту, забезпечуючи контроль над використанням мережі.
  • Зниження навантаження на мережу: Завдяки кешуванню і фільтрації трафіку проксі-сервери можуть зменшити загальний обсяг передаваних даних і навантаження на мережу.

Багато серверних програм заради безпеки не мають прямого доступу в інтернет. Замість цього вони звертаються до нього через проксі, а у нього вже є список дозволених сайтів і ресурсів. Так що і ваші програми повинні вміти працювати з проксі.

Незважаючи на всі переваги, використання проксі-серверів може мати й недоліки. Наприклад, це може призвести до зниження швидкості з'єднання, так як запити проходять через додаткову ланку. Крім того, деякі сайти можуть блокувати доступ із відомих проксі-серверів.

6.2 Проксі і модуль requests

Бібліотека requests підтримує використання проксі-серверів через параметр proxies.

HTTP (Hypertext Transfer Protocol) і HTTPS (HTTP Secure) — це протоколи передачі даних в інтернеті. HTTPS — це захищена версія HTTP. Для них можуть використовуватися різні проксі-сервери, так як вони можуть вимагати різної обробки через особливості шифрування HTTPS.

Приклад використання HTTP-проксі

В якості проксі зазвичай передають не один проксі, а цілий список. Це дуже зручно, якщо деякі з проксі будуть забанені або недоступні.

Приклад виклику функції requests.get() з передачею запиту через proxy.


import requests

# URL-адреса, до якої виконується запит
url = 'http://httpbin.org/ip'
            
# Налаштування проксі-сервера
proxies = {
    'http': 'http://10.10.1.10:3128',
    'https': 'http://10.10.1.10:1080',
}
            
# Відправка GET-запиту через проксі
response = requests.get(url, proxies=proxies)
            
print(response.json())
        

http-запити підуть через перший проксі-сервер, а https — через другий.

Приклад використання проксі з аутентифікацією

Багато проксі-серверів вимагають спочатку пройти аутентифікацію, а потім вже дають можливість ними користуватися. Нам на допомогу прийде цікава штука…

Коли URL тільки придумали, то в стандарт URL заклали, що в ньому можна передати одразу логін і пароль до ресурсу. Виглядає це так:


http://user:password@domain/path

Тому якщо проксі-сервер вимагає аутентифікації, можна включити облікові дані в URL.

Приклад:


import requests

# URL-адреса, до якої виконується запит
url = 'http://httpbin.org/ip'
            
# Налаштування проксі-сервера з аутентифікацією
proxies = {
    'http': 'http://user:password@10.10.1.10:3128',
    'https': 'http://user:password@10.10.1.10:1080',
}
            
# Відправка GET-запиту через проксі
response = requests.get(url, proxies=proxies)
            
print(response.json())
        

Я не бачив, щоб на практиці цим користувалися, але якщо ти будеш піднімати свій тестовий проксі-сервер, то чому б і ні.

Однак варто зазначити, що передача логіна і пароля в URL може бути небезпечною, так як URL може зберігатися в історії браузера або логах сервера. В реальних додатках слід використовувати більш безпечні методи аутентифікації.

Важливо пам'ятати про безпечне зберігання облікових даних для проксі-серверів в реальних додатках. Ніколи не зберігайте паролі у відкритому вигляді в коді або конфігураційних файлах. Замість цього використовуйте змінні середовища або захищені сховища секретів.

6.3 Проксі і http.client

Для роботи з проксі-серверами в модулі http.client необхідно налаштувати з'єднання і заголовки запиту вручну.

Тобі потрібно просто вказати host і порт при створенні з'єднання.

Приклад:


# Налаштування проксі-сервера
proxy_host = '10.10.1.10'
proxy_port = 3128
            
# Створення з'єднання з проксі-сервером
conn = http.client.HTTPConnection(proxy_host, proxy_port)
        

Потім потрібно встановити тунель з проксі-сервером, і тільки потім відправити йому запит:


dest_url = 'httpbin.org'
dest_path = '/ip'
            
# Формування і відправка запиту
conn.set_tunnel(dest_url)
conn.request('GET', dest_path)
        

Щоб перевірити, чи працює проксі-сервер коректно, можна порівняти свою IP-адресу до і після використання проксі. Для цього можна використовувати сервіси, що показують твою поточну IP-адресу, наприклад, httpbin.org/ip.

Все дуже «просто». Повний приклад використання HTTP-проксі з http.client буде виглядати так:


import http.client

# Налаштування проксі-сервера
proxy_host = '10.10.1.10'
proxy_port = 3128
dest_url = 'httpbin.org'
dest_path = '/ip'
            
# Створення з'єднання з проксі-сервером
conn = http.client.HTTPConnection(proxy_host, proxy_port)
            
# Формування і відправка запиту
conn.set_tunnel(dest_url)
conn.request('GET', dest_path)
            
# Отримання відповіді
response = conn.getresponse()
print(response.status, response.reason)
print(response.read().decode('utf-8'))
            
# Закриття з'єднання
conn.close()
        

Що сказати? Використання модуля requests буде, звісно, простіше. Але! Багато модулів і фреймворків використовують під капотом саме низькорівневий http.client. Тобі потрібно знати, як з ним працювати, щоб ти міг правильно конфігурувати їх роботу.

Незважаючи на всі переваги, використання проксі-серверів може мати й недоліки. Наприклад, це може призвести до зниження швидкості з'єднання, так як запити проходять через додаткову ланку. Крім того, деякі сайти можуть блокувати доступ із відомих проксі-серверів. Тому при використанні проксі завжди потрібно враховувати як його переваги, так і потенційні обмеження.