Skip to main content

Rotate through IPs in Python with HTTPX using AWS API Gateway.

Project description

httpx-ip-rotator

A Python library to utilize AWS API Gateway's large IP pool as a proxy to generate pseudo-infinite IPs for web scraping and brute forcing.

This library will allow the user to bypass IP-based rate-limits for sites and services.

X-Forwarded-For headers are automatically randomised and applied unless given. This is because otherwise, AWS will send the client's true IP address in this header.

AWS' ApiGateway sends its requests from any available IP - and since the AWS infrastructure is so large, it is almost guarenteed to be different each time. By using ApiGatewayTransport as a proxy, we can take advantage of this to send requests from different IPs each time. Please note that these requests can be easily identified and blocked, since they are sent with unique AWS headers (i.e. "X-Amzn-Trace-Id").


Installation

This package is on pypi so you can install via any of the following:

  • pip3 install httpx-ip-rotator
  • python3 -m pip install httpx-ip-rotator

 

Simple Usage

import httpx
from httpx_ip_rotator import ApiGatewayTransport

# Create gateway object and initialise in AWS
gateway_transport = ApiGatewayTransport("https://site.com")
gateway.start()


# Create mounts (see ![httpx documentation](https://www.python-httpx.org/advanced/transports/#mounting-transports))
mounts = {
    "https://site.com": gateway_transport
}
# Create client with mounts
client = httpx.Client(mounts=mounts)

# Send request (IP will be randomised)
response = client.get("https://site.com/index.php", params={"theme": "light"})
print(response.status_code)

# Delete gateways
gateway_transport.shutdown()

Alternate Usage (auto-start and shutdown)

import httpx
from httpx_ip_rotator import ApiGatewayTransport

with ApiGatewayTransport("https://site.com") as g:
    mounts = {
        "https://site.com": g
    }
    with httpx.Client(mounts=mounts) as client:
        response = client.get("https://site.com/index.php")
        print(response.status_code)

Async Usage

import httpx
import asyncio
from httpx_ip_rotator import AsyncApiGatewayTransport


async def main():
    # Create gateway object and initialise in AWS
    # note: this with statement can also be async with, they do the same thing for this implementation
    with AsyncApiGatewayTransport("https://site.com") as g:
        mounts = {
            "https://site.com": g
        }
        async with httpx.AsyncClient(mounts=mounts):
            response = await client.get("https://site.com/index.php", params={"theme": "light"})
            print(response.status_code)


asyncio.run(main())

Please remember that if gateways are not shutdown via the shutdown() method when using method #1, you may be charged in future.

 

Costs

API Gateway is free for the first million requests per region, which means that for most use cases this should be completely free.
At the time of writing, AWS charges ~$3 per million requests after the free tier has been exceeded.
If your requests involve data stream, AWS would charge data transfer fee at $0.09 per GB.  

Documentation

AWS Authentication

It is recommended to setup authentication via environment variables. With awscli, you can run aws configure to do this, or alternatively, you can simply set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY variables yourself.

You can find your access key ID and secret by following the official AWS tutorial.

 

Creating ApiGatewayTransport object

The ApiGatewayTransport class can be created with the following optional parameters:

Name Description Required Default
site The site (without path) requests will be sent to. True
regions An array of AWS regions to setup gateways in. False rotator.DEFAULT_REGIONS
access_key_id AWS Access Key ID (will override env variables). False Relies on env variables.
access_key_secret AWS Access Key Secret (will override env variables). False Relies on env variables.
verbose Include status and error messages. False True
from httpx_ip_rotator import ApiGatewayTransport, DEFAULT_REGIONS, EXTRA_REGIONS

# Gateway to outbound HTTP IP and port for only two regions
gateway_1 = ApiGatewayTransport("http://1.1.1.1:8080", regions=["eu-west-1", "eu-west-2"])

# Gateway to HTTPS google for the extra regions pack, with specified access key pair
gateway_2 = ApiGatewayTransport("https://www.google.com", regions=EXTRA_REGIONS, access_key_id="ID", access_key_secret="SECRET")

 

Starting API gateway

An ApiGatewayTransport object must then be started using the start method.
By default, if an ApiGatewayTransport already exists for the site, it will use the existing endpoint instead of creating a new one.
This does not require any parameters, but accepts the following:

Name Description Required Default
endpoints Array of pre-existing endpoints (i.e. from previous session). False
force Create a new set of endpoints, even if some already exist. False False
require_manual_deletion Bool specifying whether Apigateways should persist shutdown() calls False False
# Starts new ApiGatewayTransport instances for site, or locates existing endpoints if they already exist.
gateway_1.start()

# Starts new ApiGatewayTransport instances even if some already exist.
gateway_2.start(force=True)

 

Sending requests

Requests are sent by attaching the ApiGatewayTransport object to an httpx client object.
The site given in mount must match the site passed in the ApiGatewayTransport constructor.

import httpx

# Posts a request to the site created in gateway_1. Will be sent from a random IP.
session_1 = httpx.Client(mounts={"http://1.1.1.1:8080": gateway_1})
session_1.post("http://1.1.1.1:8080/update.php", headers={"Hello": "World"})

# Send 127.0.0.1 as X-Forwarded-For header in outbound request (otherwise X-Forwarded-For is randomised).
session_1.post("http://1.1.1.1:8080/update.php", headers={"X-Forwarded-For", "127.0.0.1"})

# Execute Google search query from random IP
session_2 = httpx.Client(mounts={"https://www.google.com": gateway_2})
session_2.get("https://www.google.com/search?q=test")

 

Closing ApiGatewayTransport Resources

It's important to shutdown the ApiGatewayTrabsport resources once you have finished with them, to prevent dangling public endpoints that can cause excess charges to your account.
This is done through the shutdown method of the ApiGatewayTransport object. It will close all resources for the regions specified in the ApiGatewayTransport object constructor.

# This will shutdown all gateway proxies for "http://1.1.1.1:8080" in "eu-west-1" & "eu-west-2"
gateway_1.shutdown()

# This will shutdown all gatewy proxies for "https://www.google.com" for all regions in rotator.EXTRA_REGIONS
gateway_2.shutdown()

Alternatively, you can selectively shutdown specific endpoints, if needed. To do this, simply pass in an array of endpoints to the shutdown() method, i.e:

# This will force start a new gateway (i.e. create new endpoints even if some exist on the region already), and then delete the first 3 of them only.
gateway_3 = ApiGatewayTransport("http://1.1.1.1:8082", regions=ALL_REGIONS)
endpoints = gateway_3.start(force=True)
gateway_3.shutdown(endpoints[:3])

Please bear in mind that any gateways started with the require_manual_deletion parameter set to True will not be deleted via the shutdown method, and must be deleted manually through either the AWS CLI or Website.

Credit

The core code for this module comes from 'requests-ip-rotator' requests-ip-rotator and this gist ip-requests-rotator-with-httpx.py.

Requests IP Rotator Credits:

The core gateway creation and organisation code was adapter from RhinoSecurityLabs' IPRotate Burp Extension.
The X-My-X-Forwarded-For header forwarding concept was originally conceptualised by ustayready in his fireprox proxy.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

httpx_ip_rotator-0.1.4.tar.gz (35.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

httpx_ip_rotator-0.1.4-py3-none-any.whl (33.8 kB view details)

Uploaded Python 3

File details

Details for the file httpx_ip_rotator-0.1.4.tar.gz.

File metadata

  • Download URL: httpx_ip_rotator-0.1.4.tar.gz
  • Upload date:
  • Size: 35.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.4

File hashes

Hashes for httpx_ip_rotator-0.1.4.tar.gz
Algorithm Hash digest
SHA256 31ce34ee5a145d90693705e4c096552f618571118787e8b4a37a6ea625eb741e
MD5 8df900f082fbcbecc53e3712520580c7
BLAKE2b-256 4d986fd183ddc45aab6fc4cc04801f2fa5e9dec63a9c3934eb7837a2abe44794

See more details on using hashes here.

File details

Details for the file httpx_ip_rotator-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for httpx_ip_rotator-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 ba1cff296acd6bb1cfcbffd3e5be1c1e378bd3dbe2a0849b6f2639fa5251ba3f
MD5 b79131689370ba3b80f36f07afadf6b5
BLAKE2b-256 84ba0cb61ca614622091112282a5ca6387d4ef02e1b79748e9b6cb6c464599d7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page