Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
proxy.py — 💫 Alternativa a Ngrok FRP • ⚡ Rápido • 🪶 Ligero • 0️⃣ Dependencias • 🔌 Conectable • 😈 Interceptación TLS • 🔒 DNS sobre HTTPS • 🔥 VPN del pobre • ⏪ Reverso & ⏩ Adelante • 👮🏿 framework "Servidor Proxy" • 🌐 framework "Servidor Web" • ➵ ➶ ➷ ➠ framework "PubSub" • 👷 framework "Trabajo" aceptador y ejecutor | Kitploit
Herramientas/GitHubGitHub/abhinavsingh/proxy.py
Proxies Web e InterceptaciónPruebas de PenetraciónUtilidades y FrameworksRed Teaming
GitHubabhinavsingh/proxy.py

proxy.py

Ver RepositorioSitio web
3.5k629hace 1 añoRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →

Acerca de

💫 Alternativa a Ngrok FRP • ⚡ Rápido • 🪶 Ligero • 0️⃣ Dependencias • 🔌 Conectable • 😈 Interceptación TLS • 🔒 DNS sobre HTTPS • 🔥 VPN del pobre • ⏪ Reverso & ⏩ Adelante • 👮🏿 framework "Servidor Proxy" • 🌐 framework "Servidor Web" • ➵ ➶ ➷ ➠ framework "PubSub" • 👷 framework "Trabajo" aceptador y ejecutor

Compartir

Proxy.Py

PyPi Mensual Descargas de Docker Sin Dependencias Gitter Licencia

Probado con MacOS, Ubuntu, Windows, Android, Android Emulator, iOS, iOS Simulator Android, Android Emulator iOS, iOS Simulator

versión pypi Python 3.x Verificado con mypy

doc codecov lib

Contribuciones Bienvenidas ¿Necesitas Ayuda? Patrocinado por Jaxl Innovations Private Limited

Tabla de Contenidos

  • Características
  • Instalación
    • Usando PIP
      • Versión estable
      • Versión de desarrollo
    • Usando Docker
      • Versión estable desde Docker Hub
      • Versión de desarrollo desde GHCR
      • Construir contenedor localmente
    • Usando HomeBrew
      • Versión estable
      • Versión de desarrollo
  • Iniciar proxy.py
    • Desde la línea de comandos cuando se instala con PIP
      • Ejecutarlo
      • Entender los registros
      • Habilitar el registro DEBUG
    • Desde la línea de comandos usando el código fuente del repositorio
    • Imagen Docker
      • Personalizar las banderas de inicio
  • Ejemplos de Plugins
    • Plugins de Proxy HTTP
      • Plugin ShortLink
      • Plugin Modify Post Data
      • Plugin Mock Api
      • Plugin Redirect To Custom Server
      • Plugin Filter By Upstream Host
      • Plugin Cache Responses
      • Cache By Response Type
      • Plugin Man-In-The-Middle
      • Plugin Proxy Pool
      • Plugin Filter By Client IP
      • Plugin Modify Chunk Response
      • Plugin Modify Request Header

Características

  • Una alternativa directa a ngrok

  • Rápido y Escalable

    • Escale verticalmente usando todos los núcleos disponibles en el sistema

    • Ejecuciones sin hilos usando asyncio

    • Diseñado para manejar decenas de miles de conexiones / seg

      root@kitploit:~
      # On Macbook Pro M2 2022
      ❯ python --version
      Python 3.11.8
      ❯ oha --version
      oha 1.4.3
      ❯ ./benchmark/compare.sh
        CONCURRENCY: 100 workers, DURATION: 1m, TIMEOUT: 1sec
        =============================
        Benchmarking Proxy.Py
        Server (pid:75969) running
        Summary:
          Success rate: 100.00%
          Total:        60.0006 secs
          Slowest:      0.2525 secs
          Fastest:      0.0002 secs
          Average:      0.0019 secs
          Requests/sec: 51667.3774
      
          Total data:   56.17 MiB
          Size/request: 19 B
          Size/sec:     958.64 KiB
      
        Response time histogram:
          0.000 [1]       |
          0.025 [3073746] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
          0.051 [10559]   |
          0.076 [4980]    |
          0.101 [2029]    |
          0.126 [5896]    |
          0.152 [2466]    |
          0.177 [116]     |
          0.202 [40]      |
          0.227 [52]      |
          0.253 [87]      |
      
        Response time distribution:
          10.00% in 0.0005 secs
          25.00% in 0.0007 secs
          50.00% in 0.0009 secs
          75.00% in 0.0014 secs
          90.00% in 0.0021 secs
          95.00% in 0.0035 secs
          99.00% in 0.0198 secs
          99.90% in 0.1262 secs
          99.99% in 0.1479 secs
      
        Details (average, fastest, slowest):
          DNS+dialup:   0.0018 secs, 0.0004 secs, 0.0031 secs
          DNS-lookup:   0.0000 secs, 0.0000 secs, 0.0002 secs
      
        Status code distribution:
          [200] 3099972 responses
      
        Error distribution:
          [100] aborted due to deadline
        =============================
      

Instalación

Consulte Desplegar proxy.py en producción al implementar aplicaciones de nivel de producción usando proxy.py.

Usando PIP

Versión Estable con PIP

Instale desde `PyPi````console ❯ pip install --upgrade proxy.py

root@kitploit:~
o desde la rama `master` de GitHub```console
❯ pip install git+https://github.com/abhinavsingh/proxy.py.git@master

Versión de desarrollo con PIP```console

❯ pip install git+https://github.com/abhinavsingh/proxy.py.git@develop

root@kitploit:~
## Usando Docker

Los contenedores multiplataforma están disponibles a través de:

- Docker Hub
  - La etiqueta `latest` apunta a la última versión `stable`
  - `docker pull abhinavsingh/proxy.py:latest`
- Registro de contenedores de GitHub (GHCR)
  - La etiqueta `latest` apunta a la última versión `develop`
  - `docker pull ghcr.io/abhinavsingh/proxy.py:latest`

Las versiones estables de contenedores están disponibles para las siguientes plataformas:

- `linux/386`
- `linux/amd64`
- `linux/arm/v6`
- `linux/arm/v7`
- `linux/arm64/v8`
- `linux/ppc64le`
- `linux/s390x`

### Versión estable desde Docker Hub

Ejecuta el contenedor más reciente de `proxy.py`:```console
❯ docker run -it -p 8899:8899 --rm abhinavsingh/proxy.py:latest

El demonio de Docker extraerá automáticamente la imagen de la plataforma correspondiente. Para ejecutar un contenedor de plataforma objetivo específica en servidores compatibles con múltiples plataformas:```console ❯ docker run -it -p 8899:8899 --rm --platform linux/arm64/v8 abhinavsingh/proxy.py:latest

root@kitploit:~
### Versión de Desarrollo desde GHCR

Ejecuta el contenedor de `proxy.py` desde el código más reciente en la rama develop:```console
❯ docker run -it -p 8899:8899 --rm ghcr.io/abhinavsingh/proxy.py:latest

Compilar versión de desarrollo localmente```console

❯ git clone https://github.com/abhinavsingh/proxy.py.git ❯ cd proxy.py && make container ❯ docker run -it -p 8899:8899 --rm abhinavsingh/proxy.py:latest

root@kitploit:~
[![WARNING](https://img.shields.io/static/v1?label=MacOS&message=warning&color=red)](https://github.com/moby/vpnkit/issues/469)
La imagen de `docker` actualmente está rota en `macOS` debido a incompatibilidad con [vpnkit](https://github.com/moby/vpnkit/issues/469).

## Usando HomeBrew

Las fórmulas actualizadas para `HomeBrew` se mantienen en la rama `develop` bajo el directorio `helper/homebrew`.

- `stable` fórmulas instalan el paquete desde la rama `master`.
- `develop` fórmulas instalan el paquete desde la rama `develop`.

### Versión Estable con HomeBrew```console
❯ brew install https://raw.githubusercontent.com/abhinavsingh/proxy.py/develop/helper/homebrew/stable/proxy.rb

Versión de desarrollo con HomeBrew```console

❯ brew install https://raw.githubusercontent.com/abhinavsingh/proxy.py/develop/helper/homebrew/develop/proxy.rb

root@kitploit:~
# Iniciar proxy.py

## Desde la línea de comandos cuando se instala mediante PIP

Cuando `proxy.py` se instala mediante `pip`,
se coloca un ejecutable llamado `proxy` en tu `$PATH`.

### Ejecutarlo

Simplemente escribe `proxy` en la línea de comandos para iniciar con la configuración predeterminada.```console
❯ proxy
...[redacted]... - Loaded plugin proxy.http.proxy.HttpProxyPlugin
...[redacted]... - Started 8 threadless workers
...[redacted]... - Started 8 acceptors
...[redacted]... - Listening on 127.0.0.1:8899

Comprendiendo los registros

Cosas a notar de los registros anteriores:

  • Loaded plugin

    • proxy.py cargará proxy.http.proxy.HttpProxyPlugin por defecto
    • Como su nombre indica, este plugin principal añade capacidades de servidor proxy http(s) a la instancia de proxy.py
  • Started N threadless workers

    • Por defecto, proxy.py iniciará tantos procesos worker como núcleos de CPU tenga la máquina
    • Use la bandera --num-workers para personalizar el número de procesos worker
    • Vea Threads vs Threadless para entender cómo controlar el modo de ejecución
  • Started N acceptors

    • Por defecto, proxy.py iniciará tantos procesos acceptor como núcleos de CPU tenga la máquina
    • Use la bandera --num-acceptors para personalizar el número de procesos acceptor

Habilitar registro DEBUG

Todos los registros anteriores son de nivel INFO, el --log-level por defecto para proxy.py

Iniciemos proxy.py con registro de nivel DEBUG:```console ❯ proxy --log-level d ...[redacted]... - Open file descriptor soft limit set to 1024 ...[redacted]... - Loaded plugin proxy.http_proxy.HttpProxyPlugin ...[redacted]... - Started 8 workers ...[redacted]... - Started server on ::1:8899

root@kitploit:~
Puedes usar una sola letra para personalizar el nivel de registro.  Ejemplo:
- `d = DEBUG`
- `i = INFO`
- `w = WARNING`
- `e = ERROR`
- `c = CRITICAL`

Como podemos ver en los registros anteriores, antes de iniciar:

- `proxy.py` intentó establecer el límite de archivos abiertos `ulimit` en el sistema
- El valor predeterminado para `--open-file-limit` utilizado es `1024`
- La bandera `--open-file-limit` no tiene efecto en sistemas operativos `Windows`

Consulta [flags](#flags) para la lista completa de opciones de configuración disponibles.

## Desde la línea de comandos usando el repositorio fuente

Si estás intentando ejecutar `proxy.py` desde el código fuente,
no hay un archivo binario llamado `proxy` en el código fuente.

Para iniciar `proxy.py` desde el código fuente, sigue estas instrucciones:

- Clona el repositorio  ```console
  ❯ git clone https://github.com/abhinavsingh/proxy.py.git
  ❯ cd proxy.py
  • Crear un entorno virtual de Python 3 ```console ❯ python3 -m venv venv ❯ source venv/bin/activate

    root@kitploit:~
  • Instalar dependencias ```console ❯ make lib-dep

    root@kitploit:~
  • Generar proxy/common/_scm_version.py

    NOTA: El siguiente paso no es necesario para instalaciones editables.

    Este archivo escribe la versión detectada por SCM en el archivo proxy/common/_scm_version.py. ```console ❯ ./write-scm-version.sh

    root@kitploit:~
  • Opcionalmente, ejecute las pruebas ```console ❯ make

    root@kitploit:~
  • Ejecuta proxy.py ```console ❯ python -m proxy

    root@kitploit:~

Vea Guía para desarrolladores y contribuyentes de plugins si planea trabajar con el código fuente de proxy.py.

Imagen de Docker

Personalizar banderas de inicio

Por defecto, el binario docker se inicia con banderas de red IPv4:

root@kitploit:~
--hostname 0.0.0.0 --port 8899

Puede anular la bandera desde la línea de comandos al iniciar el contenedor Docker. Por ejemplo, para verificar la versión de proxy.py dentro del contenedor Docker, ejecute:

root@kitploit:~
❯ docker run -it \
    -p 8899:8899 \
    --rm abhinavsingh/proxy.py:latest \
    -v

Ejemplos de Plugins

  • Consulte el módulo plugin para el código completo.
  • Todos los ejemplos de plugins incluidos también funcionan con tráfico https
    • Requieren banderas adicionales y generación de certificados
    • Consulte Intercepción TLS.
  • Los ejemplos de plugins también están incluidos en la imagen Docker.
    • Consulte Personalizar banderas de inicio para probar plugins con la imagen Docker.

Plugins de Proxy HTTP

ShortLinkPlugin

Agregue soporte para enlaces cortos en sus navegadores/aplicaciones favoritos.

Plugin Shortlink

Inicie proxy.py como:```console ❯ proxy
--plugins proxy.plugin.ShortLinkPlugin

root@kitploit:~
Ahora puedes acelerar tu experiencia de navegación diaria visitando tu sitio web favorito usando nombres de dominio de un solo carácter :). Esto funciona en todos los navegadores.

Los siguientes enlaces cortos están habilitados por defecto:

| Enlace Corto |   URL de Destino    |
| :--------: | :---------------: |
|     a/     |    `amazon.com`    |
|     i/     |  `instagram.com`   |
|     l/     |   `linkedin.com`   |
|     f/     |   `facebook.com`   |
|     g/     |    `google.com`    |
|     t/     |   `twitter.com`    |
|     w/     | `web.whatsapp.com` |
|     y/     |   `youtube.com`    |
|   proxy/   |  `localhost:8899`  |

### ModifyPostDataPlugin

Modifica el cuerpo de la solicitud POST antes de enviar la solicitud al servidor upstream.

Inicia `proxy.py` como:```console
❯ proxy \
    --plugins proxy.plugin.ModifyPostDataPlugin

Por defecto el plugin reemplaza el contenido del cuerpo POST con el valor fijo b'{"key": "modified"}' y fuerza Content-Type: application/json.

Verifica lo mismo usando `curl -x localhost:8899 -d '{"key": "value"}' http://httpbin.org/post````console { "args": {}, "data": "{"key": "modified"}", "files": {}, "form": {}, "headers": { "Accept": "/", "Content-Length": "19", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "curl/7.54.0" }, "json": { "key": "modified" }, "origin": "1.2.3.4, 5.6.7.8", "url": "https://httpbin.org/post" }

root@kitploit:~
Nota a partir de la respuesta anterior:

1. Los datos POST fueron modificados `"data": "{\"key\": \"modified\"}"`.
   Los datos originales del comando `curl` eran `{"key": "value"}`.
2. Nuestro comando `curl` no añadió ningún encabezado `Content-Type`,
   pero nuestro plugin sí añadió uno `"Content-Type": "application/json"`.
   Lo mismo se puede verificar observando el campo `json` en la salida anterior:   ```
   "json": {
    "key": "modified"
   },
  1. Nuestro plugin también añadió una cabecera Content-Length para coincidir con la longitud del cuerpo modificado.

MockRestApiPlugin

Respuestas simuladas para la API REST de tu servidor. Úselo para probar y desarrollar aplicaciones del lado del cliente sin necesidad de un servidor REST API upstream real.

Inicie proxy.py como:```console ❯ proxy
--plugins proxy.plugin.ProposedRestApiPlugin

root@kitploit:~
Verificar la respuesta de la API simulada usando `curl -x localhost:8899 http://api.example.com/v1/users/````console
{"count": 2, "next": null, "previous": null, "results": [{"email": "[email protected]", "groups": [], "url": "api.example.com/v1/users/1/", "username": "admin"}, {"email": "[email protected]", "groups": [], "url": "api.example.com/v1/users/2/", "username": "admin"}]}

Verifique lo mismo al inspeccionar los registros de proxy.py:```console ... [redacted] ... - access_log:1210 - ::1:64792 - GET None:None/v1/users/ - None None - 0 byte

root@kitploit:~
El registro de acceso muestra `None:None` como servidor `ip:port`. `None` simplemente significa que la conexión al servidor nunca se realizó, ya que la respuesta fue devuelta por nuestro plugin.

Ahora modifique `ProposedRestApiPlugin` para que devuelva respuestas simuladas de la API REST según lo esperado por sus clientes.

### RedirectToCustomServerPlugin

Redirige todas las solicitudes `http` entrantes a un servidor web personalizado.
Por defecto, redirige las solicitudes de los clientes al servidor web integrado,
que también se ejecuta en el puerto `8899`.

Inicie `proxy.py` y habilite el servidor web integrado:```console
❯ proxy \
    --enable-web-server \
    --plugins proxy.plugin.RedirectToCustomServerPlugin

Verifique usando `curl -v -x localhost:8899 http://google.com```` ... [redacted] ... < HTTP/1.1 404 NOT FOUND < Server: proxy.py v1.0.0 < Connection: Close <

  • Closing connection 0
root@kitploit:~
La respuesta `404` anterior fue devuelta por el servidor web `proxy.py`.

Verifique lo mismo inspeccionando los registros de `proxy.py`.
Junto con el registro de solicitud del proxy, también debe ver un registro de solicitud del servidor web http.```
... [redacted] ... - access_log:1241 - ::1:49525 - GET /
... [redacted] ... - access_log:1157 - ::1:49524 - GET localhost:8899/ - 404 NOT FOUND - 70 bytes

FilterByUpstreamHostPlugin

Elimina tráfico inspeccionando el host ascendente. Por defecto, el plugin elimina tráfico para facebook.com y www.facebok.com.

Inicie proxy.py como:```console ❯ proxy
--plugins proxy.plugin.FilterByUpstreamHostPlugin

root@kitploit:~
Verifique usando `curl -v -x localhost:8899 http://facebook.com`:```console
... [redacted] ...
< HTTP/1.1 418 I'm a tea pot
< Proxy-agent: proxy.py v1.0.0
* no chunk, no close, no size. Assume close to signal end
<
* Closing connection 0

Arriba 418 I'm a tea pot es enviado por nuestro plugin. Verifícalo inspeccionando los registros de proxy.py:```console ... [redacted] ... - handle_readables:1347 - HttpProtocolException type raised Traceback (most recent call last): ... [redacted] ... ... [redacted] ... - access_log:1157 - ::1:49911 - GET None:None/ - None None - 0 bytes

root@kitploit:~
### CacheResponsesPlugin

Almacena en caché las respuestas del servidor upstream.

Inicia `proxy.py` como:```console
❯ proxy \
    --plugins proxy.plugin.CacheResponsesPlugin

También puede usar la bandera --cache-requests para habilitar el almacenamiento en caché de paquetes de solicitud para inspección.

Verifique usando curl -v -x localhost:8899 http://httpbin.org/get:```console ... [redacted] ... < HTTP/1.1 200 OK < Access-Control-Allow-Credentials: true < Access-Control-Allow-Origin: * < Content-Type: application/json < Date: Wed, 25 Sep 2019 02:24:25 GMT < Referrer-Policy: no-referrer-when-downgrade < Server: nginx < X-Content-Type-Options: nosniff < X-Frame-Options: DENY < X-XSS-Protection: 1; mode=block < Content-Length: 202 < Connection: keep-alive < { "args": {}, "headers": { "Accept": "/", "Host": "httpbin.org", "User-Agent": "curl/7.54.0" }, "origin": "1.2.3.4, 5.6.7.8", "url": "https://httpbin.org/get" }

  • Connection #0 to host localhost left intact
root@kitploit:~
Obtén la ruta al archivo de caché de los registros de `proxy.py`:```console
... [redacted] ... - GET httpbin.org:80/get - 200 OK - 556 bytes
... [redacted] ... - Cached response at /var/folders/k9/x93q0_xn1ls9zy76m2mf2k_00000gn/T/httpbin.org-1569378301.407512.txt

Verificar el contenido del archivo de caché `cat /path/to/your/cache/httpbin.org.txt````console HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Content-Type: application/json Date: Wed, 25 Sep 2019 02:24:25 GMT Referrer-Policy: no-referrer-when-downgrade Server: nginx X-Content-Type-Options: nosniff X-Frame-Options: DENY X-XSS-Protection: 1; mode=block Content-Length: 202 Connection: keep-alive

{ "args": {}, "headers": { "Accept": "/", "Host": "httpbin.org", "User-Agent": "curl/7.54.0" }, "origin": "1.2.3.4, 5.6.7.8", "url": "https://httpbin.org/get" }

root@kitploit:~
### CacheByResponseType

El plugin `CacheResponsesPlugin` también puede almacenar en caché automáticamente las respuestas por `content-type`.
Para probar esto, debes estar ejecutando en modo [Intercepción TLS](#tls-interception)
y luego pasar el flag `--cache-by-content-type`.  Ejemplo:```console
❯ proxy \
    --plugins proxy.plugin.CacheResponsesPlugin \
    --cache-by-content-type \
    --ca-key-file ca-key.pem \
    --ca-cert-file ca-cert.pem \
    --ca-signing-key ca-signing-key.pem

Haz algunas solicitudes al servidor proxy y verás datos en el directorio ~/.proxy/cache.

Deberías ver 2 carpetas:

  • content: Contiene archivos jpg, css, js, html, pdf, etc. analizados por tipo de contenido
  • responses: Contiene las respuestas brutas tal como se recibieron (por supuesto descifradas debido a la intercepción)

ManInTheMiddlePlugin

Modifica las respuestas del servidor ascendente.

Inicia proxy.py como:```console ❯ proxy
--plugins proxy.plugin.ManInTheMiddlePlugin

root@kitploit:~
Verificar usando `curl -v -x localhost:8899 http://google.com`:```console
... [redacted] ...
< HTTP/1.1 200 OK
< Content-Length: 28
<
* Connection #0 to host localhost left intact
Hello from man in the middle

Response body Hello from man in the middle is sent by our plugin.

ProxyPoolPlugin

Forward incoming proxy requests to a set of upstream proxy servers.

Let's start 2 upstream proxies first. To simulate upstream proxies, start proxy.py on port 9000 and `9001````console ❯ proxy --port 9000

root@kitploit:~
1. Convertir dirección IP a entero
2. Convertir entero a dirección IP
3. Convertir dominio a dirección IP
4. Obtener dirección IP desde nombre de host
5. Obtener nombre de host desde dirección IP
6. Obtener registros DNS
7. Búsqueda Whois
8. Búsqueda de dirección MAC```console
❯ proxy --port 9001

Ahora, inicia proxy.py con ProxyPoolPlugin (en el puerto predeterminado 8899), apuntando a nuestros proxies upstream en los puertos 9000 y 9001.```console ❯ proxy
--plugins proxy.plugin.ProxyPoolPlugin
--proxy-pool localhost:9000
--proxy-pool localhost:9001

root@kitploit:~
Realiza una solicitud curl a través del proxy `8899`:

`curl -v -x localhost:8899 http://httpbin.org/get`

Verifica que el proxy `8899` reenvíe las solicitudes a los proxies upstream revisando los registros respectivos.

Si un proxy upstream requiere credenciales, pásalas como argumentos. Ejemplo:

`--proxy-pool user:[email protected]:port`

### FilterByClientIpPlugin

Rechaza el tráfico de direcciones IP específicas. Por defecto, este plugin bloquea el tráfico de `127.0.0.1` y `::1`.

Inicia `proxy.py` como:```console
❯ proxy \
    --plugins proxy.plugin.FilterByClientIpPlugin

Envíe una solicitud usando curl -v -x localhost:8899 http://google.com:```console ... [redacted] ...

Proxy-Connection: Keep-Alive

< HTTP/1.1 418 I'm a tea pot < Connection: close <

  • Closing connection 0
root@kitploit:~
Modifica el plugin a tu gusto, p. ej., permitir solo direcciones IP específicas.

### ModifyChunkResponsePlugin

Este plugin demuestra cómo modificar respuestas codificadas en fragmentos. Para ello, este plugin utiliza el núcleo de `proxy.py` para analizar la respuesta codificada en fragmentos. Luego, reconstruimos la respuesta usando fragmentos personalizados codificados de forma rígida, ignorando los fragmentos originales recibidos del servidor ascendente.

Inicia `proxy.py` como:```console
❯ proxy \
    --plugins proxy.plugin.ModifyChunkResponsePlugin

Verifique usando curl -v -x localhost:8899 http://httpbin.org/stream/5:```console ... [redacted] ... modify chunk response plugin

  • Connection #0 to host localhost left intact
  • Closing connection 0
root@kitploit:~
Modifica `ModifyChunkResponsePlugin` a tu gusto. Por ejemplo, en lugar de enviar fragmentos codificados, analiza y modifica los fragmentos `JSON` originales recibidos del servidor ascendente.

### ModifyRequestHeaderPlugin

Este plugin demuestra cómo modificar las cabeceras de las solicitudes HTTPS salientes en modo de intercepción TLS.

Inicia `proxy.py` como:```console
❯ proxy \
    --plugins proxy.plugin.ModifyRequestHeaderPlugin \
    ... [TLS interception flags] ...

Verifique usando curl -x localhost:8899 --cacert ca-cert.pem https://httpbin.org/get:```console { "args": {}, "headers": { ... [redacted] ..., "X-Proxy-Py-Version": "2.4.4rc6.dev15+gf533c711" }, ... [redacted] ... }

root@kitploit:~
### CloudflareDnsResolverPlugin

Este plugin usa `Cloudflare` hospedado `DNS-over-HTTPS` [API](https://developers.cloudflare.com/1.1.1.1/encrypted-dns/dns-over-https/make-api-requests/dns-json) (json).

`DoH` requiere un cliente compatible con HTTP2. Desafortunadamente `proxy.py` aún no lo proporciona, por lo que usamos una dependencia. Instálala:```console
❯ pip install "httpx[http2]"

Ahora inicie proxy.py como:```console ❯ proxy
--plugins proxy.plugin.CloudflareDnsResolverPlugin

root@kitploit:~
Por defecto, `CloudflareDnsResolverPlugin` se ejecuta en modo `security` y proporciona protección contra malware.
Usa `--cloudflare-dns-mode family` para habilitar también la protección de contenido adulto.

### CustomDnsResolverPlugin

Este plugin demuestra cómo usar una implementación de resolución DNS personalizada con `proxy.py`.
Este plugin de ejemplo actualmente usa el mecanismo de resolución incorporado de Python. Personaliza el código
a tu gusto. Por ejemplo, consulta tu servidor DNS personalizado, implementa `DoH` u otros mecanismos.

Inicia `proxy.py` como:```console
❯ proxy \
    --plugins proxy.plugin.CustomDnsResolverPlugin

CustomNetworkInterface

El callback HttpProxyBasePlugin.resolve_dns también se puede usar para configurar la network interface que debe utilizarse como source_address para la conexión con el servidor upstream.

Ver este hilo para más detalles.

PD: No existe un plugin con ese nombre, pero CustomDnsResolverPlugin se puede personalizar fácilmente según sus necesidades.

ProgramNamePlugin

Intenta resolver el nombre del programa (application) para las solicitudes de proxy que se originan en la máquina local. Si se identifica, la IP del cliente en los registros de acceso se reemplaza con el nombre del programa.

Inicie proxy.py como:```console ❯ proxy
--plugins proxy.plugin.ProgramNamePlugin

root@kitploit:~
Haz una solicitud utilizando `curl`:```console
❯ curl -v -x localhost:8899 https://httpbin.org/get

Debes ver líneas de registro como estas:```console ... [redacted] ... - [I] server.access_log:419 - curl:58096 - CONNECT httpbin.org:443 - 6010 bytes - 1824.62ms

root@kitploit:~
Aviso `curl` en lugar de `::1` o `127.0.0.1` como IP del cliente.

[![WARNING](https://img.shields.io/static/v1?label=Compatibility&message=warning&color=red)](#programnameplugin) Si `ProgramNamePlugin` no funciona de manera fiable en su sistema operativo, por favor contribuya enviando una solicitud de extracción y/o abriendo un issue. ¡¡¡Gracias!!!

## Plugins del Servidor Web HTTP

### Ruta del Servidor Web

Demuestra el enrutamiento integrado del servidor web mediante un plugin.

Inicie `proxy.py` como:```console
❯ proxy --enable-web-server \
    --plugins proxy.plugin.WebServerPlugin

Verifica usando curl -v localhost:8899/http-route-example, debería devolver:```console HTTP route response

root@kitploit:~
## Plugins de Proxy Inverso

Extiende el servidor web integrado para agregar capacidades de proxy inverso.

### Proxy Inverso

Inicia `proxy.py` como:```console
❯ proxy --enable-reverse-proxy \
    --plugins proxy.plugin.ReverseProxyPlugin

Con la configuración predeterminada, el plugin ReverseProxyPlugin es equivalente a la siguiente configuración de Nginx:```console location /get { proxy_pass http://httpbin.org/get; }

root@kitploit:~
Verifique usando `curl -v localhost:8899/get`:```console
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Host": "localhost",
    "User-Agent": "curl/7.64.1"
  },
  "origin": "1.2.3.4, 5.6.7.8",
  "url": "https://localhost/get"
}

Reescribir Host Header

Con el ejemplo anterior, a veces puede ver:```console

  • Empty reply from server
  • Closing connection curl: (52) Empty reply from server
root@kitploit:~
Esto está sucediendo porque nuestro plugin de proxy inverso predeterminado `ReverseProxyPlugin` está configurado
con un servidor upstream `http` y otro `https`.  Y, por defecto, `ReverseProxyPlugin` preserva el
encabezado de host original.  Mientras que esto funciona con upstreams `https`, no funciona de manera confiable con
upstreams `http`.  Para solucionar este problema use los flags `--rewrite-host-header`.

Example:

```bash
some-command --rewrite-host-header
``````console
❯ proxy --enable-reverse-proxy \
    --plugins proxy.plugin.ReverseProxyPlugin \
    --rewrite-host-header

Esto asegurará que el campo de cabecera Host esté configurado como httpbin.org y funcione tanto con upstream http como https.

NOTA: Si usar --rewrite-host-header o no depende de tu caso de uso.

Orden de Plugins

Al usar múltiples plugins, dependiendo de la funcionalidad del plugin, puede valer la pena considerar el orden en que se pasan los plugins en la línea de comandos.

Los plugins se llaman en el mismo orden en que se pasan. Por ejemplo, supongamos que estamos usando tanto FilterByUpstreamHostPlugin como RedirectToCustomServerPlugin. La idea es descartar todas las solicitudes http entrantes para facebook.com y www.facebook.com y redirigir otras solicitudes http a nuestro servidor web incorporado.

Por lo tanto, en este escenario es importante usar FilterByUpstreamHostPlugin antes de RedirectToCustomServerPlugin. Si habilitamos RedirectToCustomServerPlugin antes de FilterByUpstreamHostPlugin, las solicitudes facebook también se redirigirán al servidor web incorporado, en lugar de ser descartadas.

Cifrado de Extremo a Extremo

Por defecto, proxy.py usa el protocolo http para la comunicación con los clientes, por ejemplo curl, navegador. Para habilitar el cifrado de extremo a extremo usando tls / https, primero genera certificados. Clona el repositorio y ejecuta:```console make https-certificates

root@kitploit:~
Inicia `proxy.py` como:```console
❯ proxy \
    --cert-file https-cert.pem \
    --key-file https-key.pem

Verifique usando curl -x https://localhost:8899 --proxy-cacert https-cert.pem https://httpbin.org/get:```console { "args": {}, "headers": { "Accept": "/", "Host": "httpbin.org", "User-Agent": "curl/7.54.0" }, "origin": "1.2.3.4, 5.6.7.8", "url": "https://httpbin.org/get" }

root@kitploit:~
Si quieres evitar pasar la bandera `--proxy-cacert`, también considera firmar los certificados SSL generados. Ejemplo:

Primero, genera los certificados CA:```console
make ca-certificates

Luego, firma el certificado SSL:```console make sign-https-certificates

root@kitploit:~
Ahora reinicie el servidor con el indicador `--cert-file https-signed-cert.pem`. Tenga en cuenta que también debe confiar en el certificado `ca-cert.pem` generado en su llavero de sistema.

# Intercepción TLS

Por defecto, `proxy.py` no descifrará el tráfico `https` entre el cliente y el servidor. Para habilitar la intercepción TLS, primero genere los certificados CA raíz:```console
❯ make ca-certificates

También habilitemos CacheResponsePlugin para que podamos verificar la respuesta descifrada del servidor. Inicie proxy.py como:```console ❯ proxy
--plugins proxy.plugin.CacheResponsesPlugin
--ca-key-file ca-key.pem
--ca-cert-file ca-cert.pem
--ca-signing-key-file ca-signing-key.pem

root@kitploit:~
[![NOTE](https://img.shields.io/static/v1?label=MacOS&message=note&color=yellow)](https://github.com/abhinavsingh/proxy.py#user-content-flags) También proporcione la ruta explícita del paquete CA necesaria para la validación de certificados de pares. Consulte la bandera `--ca-file`.

Verifique la intercepción TLS usando `curl````console
❯ curl -v -x localhost:8899 --cacert ca-cert.pem https://httpbin.org/get

[Más información sobre cada tarea se puede encontrar en la página de resumen o dentro de la interfaz de usuario. Cuando DrHeader esté en ejecución, puedes ir a http://localhost:5000/info]```console

  • issuer: C=US; ST=CA; L=SanFrancisco; O=proxy.py; OU=CA; CN=Proxy PY CA; emailAddress=[email protected]
  • SSL certificate verify ok.

GET /get HTTP/1.1 ... [redacted] ... < Connection: keep-alive < { "args": {}, "headers": { "Accept": "/", "Host": "httpbin.org", "User-Agent": "curl/7.54.0" }, "origin": "1.2.3.4, 5.6.7.8", "url": "https://httpbin.org/get" }

root@kitploit:~
La línea `issuer` confirma que la respuesta fue interceptada.

También verifica el contenido del archivo de respuesta en caché. Obtén la ruta al archivo de caché de los registros de `proxy.py`.

`❯ cat /path/to/your/tmp/directory/httpbin.org-1569452863.924174.txt````console
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Wed, 25 Sep 2019 23:07:05 GMT
Referrer-Policy: no-referrer-when-downgrade
Server: nginx
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Length: 202
Connection: keep-alive

{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.54.0"
  },
  "origin": "1.2.3.4, 5.6.7.8",
  "url": "https://httpbin.org/get"
}

¡Viola!!! Si eliminas las banderas CA, los datos cifrados se encontrarán en el archivo en caché en lugar de texto plano.

Ahora usa las banderas CA con otros ejemplos de plugins para verlos funcionar con tráfico https.

Intercepción TLS insegura

Para interceptar tráfico TLS de un servidor que utiliza un certificado autofirmado, añade la bandera --insecure-tls-interception para deshabilitar la validación obligatoria del certificado TLS.

NOTA: Esta bandera deshabilita la verificación del certificado para todos los servidores.

Intercepción TLS con Docker

Notas importantes sobre la intercepción TLS con contenedor Docker:

  • Desde v2.2.0, el contenedor docker de proxy.py también incluye openssl. Esto permite a proxy.py generar certificados sobre la marcha para la intercepción TLS.

  • Por razones de seguridad, el contenedor docker de proxy.py no incluye certificados CA.

Así es como iniciar un contenedor docker de proxy.py con intercepción TLS:

  1. Genera certificados CA en el ordenador anfitrión ```console ❯ make ca-certificates
    root@kitploit:~
  2. Copie todos los certificados generados en un directorio separado. Luego montaremos este directorio en nuestro contenedor docker. ```console ❯ mkdir /tmp/ca-certificates ❯ cp ca-cert.pem ca-key.pem ca-signing-key.pem /tmp/ca-certificates
    root@kitploit:~
  3. Iniciar contenedor docker ```console ❯ docker run -it --rm
    -v /tmp/ca-certificates:/tmp/ca-certificates
    -p 8899:8899
    abhinavsingh/proxy.py:latest
    --hostname 0.0.0.0
    --plugins proxy.plugin.CacheResponsesPlugin
    --ca-key-file /tmp/ca-certificates/ca-key.pem
    --ca-cert-file /tmp/ca-certificates/ca-cert.pem
    --ca-signing-key /tmp/ca-certificates/ca-signing-key.pem
    root@kitploit:~
  • El flag -v /tmp/ca-certificates:/tmp/ca-certificates monta nuestro directorio de certificados CA en el entorno del contenedor.
    • --plugins proxy.plugin.CacheResponsesPlugin habilita CacheResponsesPlugin para que podamos inspeccionar el tráfico interceptado.
    • Los flags --ca-* habilitan la Intercepción TLS.
  1. Desde otra terminal, pruebe la Intercepción TLS usando curl. Puede omitir el flag --cacert si el certificado CA ya es de confianza para el sistema. ```console ❯ curl -v
    --cacert ca-cert.pem
    -x 127.0.0.1:8899
    https://httpbin.org/get
    root@kitploit:~
  2. Verificar el campo issuer de los encabezados de respuesta. ```console
    • Server certificate:
    • subject: CN=httpbin.org; C=NA; ST=Unavailable; L=Unavailable; O=Unavailable; OU=Unavailable
    • start date: Jun 17 09:26:57 2020 GMT
    • expire date: Jun 17 09:26:57 2022 GMT
    • subjectAltName: host "httpbin.org" matched cert's "httpbin.org"
    • issuer: CN=example.com
    • SSL certificate verify ok.
    root@kitploit:~
  3. De vuelta en la terminal de Docker, copia los registros de la ruta de volcado de respuesta. ```console ...[redacted]... [I] access_log:338 - 172.17.0.1:56498 - CONNECT httpbin.org:443 - 1031 bytes - 1216.70 ms ...[redacted]... [I] close:49 - Cached response at /tmp/httpbin.org-ae1a927d064e4ab386ea319eb38fe251.txt
    root@kitploit:~
  4. En otra terminal, ejecuta cat para ver el volcado de respuesta: ```console ❯ docker exec -it $(docker ps | grep proxy.py | awk '{ print $1 }') cat /tmp/httpbin.org-ae1a927d064e4ab386ea319eb38fe251.txt HTTP/1.1 200 OK ...[redacted]... { ...[redacted]..., "url": "http://httpbin.org/get" }
    root@kitploit:~

GROUT (Alternativa a NGROK)

  1. grout es una alternativa directa para ngrok y frp
  2. grout viene empaquetado dentro de proxy.py

Uso de Grout```console

❯ grout NAME: grout - securely tunnel local files, folders and services to public URLs

USAGE: grout route [name]

DESCRIPTION: grout exposes local networked services behinds NATs and firewalls to the public internet over a secure tunnel. Share local folders, directories and websites, build/test webhook consumers and self-host personal services to public URLs.

EXAMPLES: Share Files and Folders: grout C:\path\to\folder # Share a folder on your system grout /path/to/folder # Share a folder on your system grout /path/to/folder --basic-auth user:pass # Add authentication for shared folder grout /path/to/photo.jpg # Share a specific file on your system

Expose HTTP, HTTPS and Websockets: grout http://localhost:9090 # Expose HTTP service running on port 9090 grout https://localhost:8080 # Expose HTTPS service running on port 8080 grout https://localhost:8080 --path /worker/ # Expose only certain paths of HTTPS service on port 8080 grout https://localhost:8080 --basic-auth u:p # Add authentication for exposed HTTPS service on port 8080

Expose TCP Services: grout tcp://:6379 # Expose Redis service running locally on port 6379 grout tcp://:22 # Expose SSH service running locally on port 22

Custom URLs: grout https://localhost:8080 abhinavsingh # Custom URL for HTTPS service running on port 8080 grout tcp://:22 abhinavsingh # Custom URL for SSH service running locally on port 22

Custom Domains: grout tcp://:5432 abhinavsingh.domain.tld # Custom URL for Postgres service running locally on port 5432

Self-hosted solutions: grout tcp://:5432 abhinavsingh.my.server # Custom URL for Postgres service running locally on port 5432

(*) Wildcard Domains: grout https://host:443 do.main --wildcard # Receive traffic on provided domain and all it's subdomains

(*) Host based routing for Wildcard Domains: grout ... --tunnel-route-url host=https://h:p # When using wildcards, optionally route traffic by incoming host header

SUPPORT: Write to us at [email protected]

Privacy policy and Terms & conditions https://jaxl.com/privacy/

Created by Jaxl™ https://jaxl.io

root@kitploit:~
## Autenticación de Grout

Grout soporta autenticación para proteger tus archivos, carpetas y servicios de accesos no autorizados. Usa la bandera `--basic-auth` para exigir autenticación. Ejemplo:```console
grout /path/to/folder --basic-auth user:pass
grout https://localhost:8080 --basic-auth u:p

Grout Paths

Por defecto, Grout permite el acceso a todas las rutas en los servicios. Use la bandera --path para restringir el acceso solo a ciertas rutas en su servicio web. Ejemplo:```console grout https://localhost:8080 --path /worker/ grout https://localhost:8080 --path /webhook/ --path /callback/

root@kitploit:~
## Grout Wildcard Domains

Por defecto, el cliente Grout sirve tráfico entrante en un subdominio dedicado.
Sin embargo, algunos servicios (por ejemplo, Kubernetes) pueden querer servir tráfico en subdominios ad hoc.
Iniciar un cliente Grout dedicado para cada subdominio ad hoc puede no ser una solución práctica.

Para tales escenarios, Grout soporta dominios wildcard. Aquí se explica cómo configurar tu propio dominio wildcard para usar con clientes Grout.

1. Elige un dominio, p. ej. `custom.example.com`
2. Tu servicio desea servir tráfico para `custom.example.com` y `*.custom.example.com`
3. Si planeas usar `https://`, necesitas configurar un balanceador de carga:
   - Configura un balanceador de carga HTTPS (LB)
   - Configura el LB con un certificado generado para `custom.example.com` y `*.custom.example.com`
   - Dirige el tráfico a las direcciones IP públicas del servicio Grout
4. Contacta al equipo de Grout en [email protected] para incluir `custom.example.com` en la lista blanca. El equipo de Grout se asegurará de que realmente eres dueño del dominio y de que has configurado un certificado SSL válido como se describió anteriormente

Inicia Grout con la bandera `--wildcard`. Ejemplo:```console
grout https://localhost:8080 custom.example.com --wildcard
2024-08-05 18:24:59,294 - grout - Logged in as [email protected]
2024-08-05 18:25:03,159 - setup - Grouting https://*.custom.domain.com

Enrutamiento de Dominio Comodín Grout Basado en el Encabezado "Host"

Solo disponible con --wildcard

Junto con la ruta predeterminada, también puede proporcionar rutas adicionales que tienen prioridad cuando el campo host coincide. Ejemplo:```console grout https://localhost:8080 custom.example.com
--wildcard
--tunnel-route-url stream.example.com=http://localhost:7001

root@kitploit:~
Puede proporcionar múltiples rutas personalizadas repitiendo esta bandera.

## Complemento de Cliente Grout

`GroutClientBasePlugin` le permite enrutar tráfico dinámicamente a diferentes upstreams.  A continuación se muestra una implementación simple con una descripción sobre cómo usarlo.```python
class GroutClientPlugin(GroutClientBasePlugin):

    def resolve_route(
        self,
        route: str,
        request: HttpParser,
        origin: HostPort,
        server: HostPort,
    ) -> Tuple[Optional[str], HttpParser]:
        print(request, origin, server, '->', route)
        print(request.header(b'host'), request.path)
        #
        # Here, we send traffic to localhost:7001 irrespective
        # of the original "route" value provided to the grout
        # client OR any custom host:upstream mapping provided
        # through the --tunnel-route-url flags (when using
        # --wildcard).
        #
        # Optionally, you can also strip path before
        # sending traffic to upstrem, like:
        # request.path = b"/"
        #
        # To drop the request, simply return None for route
        # return None, request
        #
        return 'http://localhost:7001', request

Vea grout_client.py para más información. Para probarlo, comience pasando --plugin proxy.plugin.grout_client.GroutClientPlugin al iniciar el cliente grout.

Grout usando Docker```console

❯ docker run --rm -it
--entrypoint grout
-v ~/.proxy:/root/.proxy
abhinavsingh/proxy.py:latest
http://host.docker.internal:29876

root@kitploit:~
Sobre:

- Cambiamos `--entrypoint` a `grout`
- Reemplazamos `localhost` con `host.docker.internal`, para que `grout` pueda enrutar tráfico al puerto `29876` ejecutándose en la máquina host
- *(Opcional)* Montar la carpeta `~/.proxy` de la máquina host, para que las credenciales de `grout` puedan persistir entre reinicios del contenedor

## Cómo funciona Grout

- La infraestructura de `grout` tiene 2 componentes: cliente y servidor
- El cliente de `grout` tiene 2 componentes: un cliente ligero y un cliente pesado
- El cliente ligero de `grout` es parte de `proxy.py` de código abierto (Licencia BSD 3-Clause)
- El cliente pesado de `grout` y los servidores están alojados en [jaxl.io](https://jaxl.io)
  y son propiedad intelectual de [Jaxl Innovations Private Limited](https://jaxl.com)
- El servidor de `grout` tiene 3 componentes: un servidor de registro, un servidor proxy inverso y un servidor de túneles

## `grout` autoalojado

- El cliente pesado de `grout` y los servidores también pueden alojarse en tus infraestructuras GCP, AWS, Cloud
- Con una versión autoalojada, tu tráfico fluye a través de la red que controlas y en la que confías
- Los desarrolladores de `grout` en [jaxl.io](https://jaxl.io) proporcionan imágenes GCP, AWS y Docker para soluciones autoalojadas
- Por favor, envía un correo electrónico a [[email protected]](mailto:[email protected]) para empezar.

# Proxy a través de túnel SSH

**Esto es un trabajo en progreso y puede no funcionar como está documentado**

Requiere `paramiko` para funcionar. Instala las dependencias usando `pip install "proxy.py[tunnel]"`

## Proxy de solicitudes remotas localmente

                            |
    +------------+          |            +----------+
    |   LOCAL    |          |            |  REMOTE  |
    |   HOST     | <== SSH ==== :8900 == |  PROXY   |
    +------------+          |            +----------+
    :8899 proxy.py          |
                            |
                         FIREWALL
                      (allow tcp/22)

### Qué

Proxy de solicitudes HTTP(s) realizadas en un servidor proxy `remoto` a través del servidor `proxy.py` ejecutándose en `localhost`.

### Cómo

- El puerto `remoto` solicitado se reenvía a través de la conexión SSH.
- `proxy.py` ejecutándose en `localhost` maneja y responde a
  las solicitudes proxy `remotas`.

### Requisitos

1. `localhost` DEBE tener acceso SSH al servidor `remoto`
2. El servidor `remoto` DEBE estar configurado para proxy de solicitudes HTTP(s)
   a través del número de puerto reenviado, p. ej., `:8900`.
   - Los puertos `remoto` y `localhost` PUEDEN ser el mismo, p. ej., `:8899`.
   - Se eligió `:8900` en el diagrama ASCII con fines de diferenciación.

### Pruébalo

Inicia `proxy.py` como:```console
❯ # On localhost
❯ proxy --enable-ssh-tunnel \
    --tunnel-username username \
    --tunnel-hostname ip.address.or.domain.name \
    --tunnel-port 22 \
    --tunnel-remote-port 8899 \
    --tunnel-ssh-key /path/to/ssh/private.key \
    --tunnel-ssh-key-passphrase XXXXX
...[redacted]... [I] listener.setup:97 - Listening on 127.0.0.1:8899
...[redacted]... [I] pool.setup:106 - Started 16 acceptors in threadless (local) mode
...[redacted]... [I] transport._log:1873 - Connected (version 2.0, client OpenSSH_7.6p1)
...[redacted]... [I] transport._log:1873 - Authentication (publickey) successful!
...[redacted]... [I] listener.setup:116 - SSH connection established to ip.address.or.domain.name:22...
...[redacted]... [I] listener.start_port_forward:91 - :8899 forwarding successful...

Haga una solicitud HTTP proxy en el servidor remote y verifique que la respuesta contiene la dirección IP pública de localhost como origen:```console ❯ # On remote ❯ curl -x 127.0.0.1:8899 http://httpbin.org/get { "args": {}, "headers": { "Accept": "/", "Host": "httpbin.org", "User-Agent": "curl/7.54.0" }, "origin": "x.x.x.x, y.y.y.y", "url": "https://httpbin.org/get" }

root@kitploit:~
Además, verifique que los registros de `proxy.py` en `localhost` contengan la IP `remote` como IP del cliente.```console
access_log:328 - remote:52067 - GET httpbin.org:80

Proxy de solicitudes locales de forma remota

root@kitploit:~
                        |
+------------+          |     +----------+
|   LOCAL    |          |     |  REMOTE  |
|   HOST     | === SSH =====> |  SERVER  |
+------------+          |     +----------+
                        |     :8899 proxy.py
                        |
                    FIREWALL
                 (allow tcp/22)

No planificado.

Si tienes un caso de uso válido, por favor abre un issue. Siempre eres bienvenido a enviar contribuciones a través de pull-requests para añadir esta funcionalidad :)

Para hacer proxy de solicitudes locales de forma remota, utiliza el Proxy Pool Plugin.

Incrustar proxy.py

Modo Bloqueante

Inicia proxy.py en modo incrustado con la configuración por defecto usando el método proxy.main. Ejemplo:```python import proxy

if name == 'main': proxy.main()

root@kitploit:~
Personaliza las banderas de inicio pasándolas como kwargs:```python
import ipaddress
import proxy

if __name__ == '__main__':
  proxy.main(
    hostname=ipaddress.IPv6Address('::1'),
    port=8899
  )

Nota:

  1. main es equivalente a iniciar proxy.py desde la línea de comandos.
  2. main no acepta ningún args (solo kwargs).
  3. main consumirá automáticamente cualquier sys.argv disponible como args.
  4. main se bloqueará hasta que proxy.py se cierre.

Modo sin bloqueo

Inicie proxy.py en modo integrado sin bloqueo con la configuración predeterminada usando el administrador de contexto Proxy: Ejemplo:```python import proxy

if name == 'main': with proxy.Proxy() as p: # Uncomment the line below and # implement your app your logic here proxy.sleep_loop()

root@kitploit:~
Ten en cuenta que:

1. `Proxy` es similar a `main`, excepto que `Proxy` no bloqueará.
2. Internamente, `Proxy` es un administrador de contexto que iniciará
   `proxy.py` al ser llamado y lo detendrá una vez que el ámbito termine.
3. A diferencia de `main`, las banderas de inicio con `Proxy` también se pueden personalizar
   usando `args` y `kwargs`. p. ej. `Proxy(['--port', '8899'])` o
   pasando banderas como kwargs, p. ej. `Proxy(port=8899)`.
4. A diferencia de `main`, `Proxy` no inspeccionará `sys.argv`.

## Puerto Efímero

Usa `--port=0` para vincular `proxy.py` a un puerto aleatorio asignado por el kernel.

En modo embebido, puedes acceder a este puerto.  Ejemplo:```python
import proxy

if __name__ == '__main__':
  with proxy.Proxy(port=0) as p:
    print(p.flags.port)
    proxy.sleep_loop()

flags.port le dará acceso al puerto aleatorio asignado por el kernel.

Cargando Plugins

Los usuarios pueden usar la bandera --plugins varias veces para cargar múltiples plugins. Consulte Incapaz de cargar plugins si tiene problemas.

Cuando se usa en modo embebido, tiene algunas opciones más. Ejemplo:

  1. Proporcione un nombre completamente calificado de la clase del plugin como bytes al método proxy.main o al administrador de contexto proxy.Proxy.
  2. Proporcione una instancia type de la clase del plugin. Esto es especialmente útil si planea definir plugins en tiempo de ejecución.

Ejemplo, cargar un solo plugin usando la bandera --plugins:```python import proxy

if name == 'main': proxy.main(plugins=['proxy.plugin.CacheResponsesPlugin'])

root@kitploit:~
Para simplificar, también puedes pasar la lista de plugins como un argumento de palabra clave a `proxy.main` o al constructor `Proxy`.

Ejemplo:```python
import proxy
from proxy.plugin import FilterByUpstreamHostPlugin

if __name__ == '__main__':
  proxy.main(plugins=[
    b'proxy.plugin.CacheResponsesPlugin',
    FilterByUpstreamHostPlugin,
  ])

Pruebas unitarias con proxy.py

proxy.TestCase

Para configurar y limpiar proxy.py para tus clases de unittest de Python, simplemente usa proxy.TestCase en lugar de unittest.TestCase. Ejemplo:```python import proxy

class TestProxyPyEmbedded(proxy.TestCase):

root@kitploit:~
def test_my_application_with_proxy(self) -> None:
    self.assertTrue(True)
root@kitploit:~
Tenga en cuenta que:

1. `proxy.TestCase` anula el método `unittest.TestCase.run()` para configurar y cerrar `proxy.py`.
2. El servidor `proxy.py` escuchará en un puerto disponible aleatorio del sistema.
   Este puerto aleatorio está disponible como `self.PROXY.flags.port` dentro de sus casos de prueba.
3. Solo se inicia un único acceptor y worker de forma predeterminada (`--num-workers 1 --num-acceptors 1`) para una configuración y cierre más rápidos.
4. Más importante aún, `proxy.TestCase` también garantiza que el servidor `proxy.py`
   esté en funcionamiento antes de proceder con la ejecución de las pruebas. Por defecto,
   `proxy.TestCase` esperará `10 segundos` para que el servidor `proxy.py` se inicie;
   en caso de fallo, se generará una excepción `TimeoutError`.

## Sobrescribir banderas de inicio

Para sobrescribir las banderas de inicio predeterminadas, defina una variable `PROXY_PY_STARTUP_FLAGS` en su clase de prueba.
Ejemplo:```python
class TestProxyPyEmbedded(TestCase):

    PROXY_PY_STARTUP_FLAGS = [
        '--num-workers', '2',
        '--num-acceptors', '1',
        '--enable-web-server',
    ]

    def test_my_application_with_proxy(self) -> None:
        self.assertTrue(True)

See test_embed.py for full working example.

Con unittest.TestCase

Si por alguna razón no puedes usar directamente proxy.TestCase, entonces simplemente sobrescribe unittest.TestCase.run tú mismo para configurar y desmontar proxy.py. Ejemplo:```python import unittest import proxy

class TestProxyPyEmbedded(unittest.TestCase):

root@kitploit:~
def test_my_application_with_proxy(self) -> None:
    self.assertTrue(True)

def run(self, result: Optional[unittest.TestResult] = None) -> Any:
    with proxy.start([
            '--num-workers', '1',
            '--num-acceptors', '1',
            '--port', '... random port ...']):
        super().run(result)
root@kitploit:~
o simplemente configurar / finalizar `proxy.py` dentro de los métodos de clase `setUpClass` y `teardownClass`.

# Utilidades

## Sockets TCP

### new_socket_connection

Intenta crear una conexión IPv4, luego IPv6 y finalmente una conexión de doble pila hacia la dirección proporcionada.```python
>>> conn = new_socket_connection(('httpbin.org', 80))
>>> ...[ use connection ]...
>>> conn.close()

socket_connection

socket_connection es un decorador + administrador de contexto conveniente alrededor de new_socket_connection que asegura que conn.close sea implícito.

Como administrador de contexto:```python

with socket_connection(('httpbin.org', 80)) as conn: ... [ use connection ] ...

root@kitploit:~
Como un decorador:```python
>>> @socket_connection(('httpbin.org', 80))
>>> def my_api_call(conn, *args, **kwargs):
>>>   ... [ use connection ] ...

Cliente HTTP

build_http_request

  • Generar solicitud HTTP GET ```python

    build_http_request(b'GET', b'/') b'GET / HTTP/1.1\r\n\r\n'

    root@kitploit:~
  • Generar solicitud HTTP GET con encabezados ```python

    build_http_request(b'GET', b'/', conn_close=True) b'GET / HTTP/1.1\r\nConnection: close\r\n\r\n'

    root@kitploit:~
  • Generar solicitud HTTP POST con cabeceras y cuerpo ```python

    import json build_http_request(b'POST', b'/form', headers={b'Content-type': b'application/json'}, body=proxy.bytes_(json.dumps({'email': '[email protected]'}))) b'POST /form HTTP/1.1\r\nContent-type: application/json\r\n\r\n{"email": "[email protected]"}'

    root@kitploit:~

build_http_response```python

build_http_response( status_code: int, protocol_version: bytes = HTTP_1_1, reason: Optional[bytes] = None, headers: Optional[Dict[bytes, bytes]] = None, body: Optional[bytes] = None) -> bytes

root@kitploit:~
## PKI

### Uso de la API

- `gen_private_key`  ```python
  gen_private_key(
      key_path: str,
      password: str,
      bits: int = 2048,
      timeout: int = 10) -> bool
  • gen_public_key ```python gen_public_key( public_key_path: str, private_key_path: str, private_key_password: str, subject: str, alt_subj_names: Optional[List[str]] = None, extended_key_usage: Optional[str] = None, validity_in_days: int = 365, timeout: int = 10) -> bool
    root@kitploit:~
  • remove_passphrase ```python remove_passphrase( key_in_path: str, password: str, key_out_path: str, timeout: int = 10) -> bool
    root@kitploit:~
  • gen_csr ```python gen_csr( csr_path: str, key_path: str, password: str, crt_path: str, timeout: int = 10) -> bool
    root@kitploit:~
  • sign_csr ```python sign_csr( csr_path: str, crt_path: str, ca_key_path: str, ca_key_password: str, ca_crt_path: str, serial: str, alt_subj_names: Optional[List[str]] = None, extended_key_usage: Optional[str] = None, validity_in_days: int = 365, timeout: int = 10) -> bool
    root@kitploit:~

Consulte pki.py y test_pki.py para ver ejemplos de uso.

Uso de CLI

Utilice el módulo proxy.common.pki para:

  1. Generación de claves públicas y privadas
  2. Generación de solicitudes CSR
  3. Firma de solicitudes CSR usando una CA personalizada.```console ❯ python -m proxy.common.pki -h usage: pki.py [-h] [--password PASSWORD] [--private-key-path PRIVATE_KEY_PATH] [--public-key-path PUBLIC_KEY_PATH] [--subject SUBJECT] [--csr-path CSR_PATH] [--crt-path CRT_PATH] [--hostname HOSTNAME] [--openssl OPENSSL] action

proxy.py v2.4.4rc2.dev12+gdc06ea4 : PKI Utility

positional arguments: action Valid actions: remove_passphrase, gen_private_key, gen_public_key, gen_csr, sign_csr

options: -h, --help show this help message and exit --password PASSWORD Password to use for encryption. Default: proxy.py --private-key-path PRIVATE_KEY_PATH Private key path --public-key-path PUBLIC_KEY_PATH Public key path --subject SUBJECT Subject to use for public key generation. Default: /CN=localhost --csr-path CSR_PATH CSR file path. Use with gen_csr and sign_csr action. --crt-path CRT_PATH Signed certificate path. Use with sign_csr action. --hostname HOSTNAME Alternative subject names to use during CSR signing. --openssl OPENSSL Path to openssl binary. By default, we assume openssl is in your PATH

root@kitploit:~
## Documentación Interna

### Leer la Documentación

- Visita [proxypy.readthedocs.io](https://proxypy.readthedocs.io/)
- Construye localmente usando:

`make lib-doc`

### pydoc

El código está bien documentado. Obtén el código fuente y ejecuta:

`pydoc3 proxy`

### pyreverse

Genera diagramas UML de jerarquía a nivel de clase para un análisis en profundidad:

`make lib-pyreverse`

# Ejecutar Dashboard

El Dashboard está actualmente en desarrollo y aún no incluido en los paquetes `pip`.
Para ejecutar el dashboard, debes clonar el código fuente.

Dashboard está escrito en Typescript y SCSS, así que construyámoslo primero usando:```console
❯ make dashboard

También construye el Chrome DevTools embebido si planeas usarlo:```console ❯ make devtools

root@kitploit:~
Ahora inicie `proxy.py` con el plugin de panel y sobrescribiendo el directorio raíz para el servidor estático:```console
❯ proxy --enable-dashboard --static-server-dir dashboard/public
...[redacted]... - Loaded plugin proxy.http.server.HttpWebServerPlugin
...[redacted]... - Loaded plugin proxy.dashboard.dashboard.ProxyDashboard
...[redacted]... - Loaded plugin proxy.dashboard.inspect_traffic.InspectTrafficPlugin
...[redacted]... - Loaded plugin proxy.http.inspector.DevtoolsProtocolPlugin
...[redacted]... - Loaded plugin proxy.http.proxy.HttpProxyPlugin
...[redacted]... - Listening on ::1:8899
...[redacted]... - Core Event enabled

Actualmente, habilitar el panel también habilitará todos los plugins del panel.

Visite el panel:```console ❯ open http://localhost:8899/dashboard/

root@kitploit:~
## Inspeccionar Tráfico

***Esto es un trabajo en progreso y puede que no funcione como está documentado***

Espere a que se cargue `Chrome Dev Console` incrustado. Actualmente, los detalles sobre todo el tráfico que fluye a través de `proxy.py` se envían a la pestaña `Inspeccionar Tráfico`. Sin embargo, los payloads recibidos aún no están integrados con la consola de desarrollador incrustada.

La funcionalidad actual se puede verificar abriendo la `Dev Console` del panel e inspeccionando la conexión websocket que el panel estableció con el servidor `proxy.py`.

[![Proxy.Py Dashboard Inspect Traffic](https://assets.kitploit.com/production/public/readmes/157/1e6258665ca9259fc526ebb90892d4b322094bb1e8139d329ab2379fc76ab66d.png)](https://github.com/abhinavsingh/proxy.py)

# Chrome DevTools Protocol

Para escenarios donde quieras acceso directo al endpoint websocket del protocolo `Chrome DevTools`, inicie `proxy.py` como:```console
❯ proxy --enable-devtools --enable-events

Ahora apunta tu instancia CDT a ws://localhost:8899/devtools.

Métricas de Prometheus

  1. Inicia proxy.py con el flag --enable-metrics para métricas internas a través de un endpoint de prometheus
  2. Configura tu prometheus.yaml para que recolecte del endpoint /metrics, por ejemplo http://localhost:8899/metrics
  3. Personaliza la ruta de métricas usando el flag --metrics-path
  4. NOTA que --enable-metrics internamente también habilita --enable-events y el plugin del servidor web

Preguntas Frecuentes

Desplegando proxy.py en producción

A continuación se enumeran algunas estrategias para usar proxy.py en tus proyectos privados/de producción/corporativos.

¿Qué no hacer?

DEBES evitar bifurcar el repositorio "solo" para poner tu código de plugin en el directorio proxy/plugin. La bifurcación es un flujo de trabajo recomendado para los contribuyentes del proyecto, NO para los usuarios del proyecto.

  • En su lugar, usa uno de los enfoques sugeridos a continuación.
  • Luego carga tus plugins usando los flags --plugin, --plugins o el argumento plugin.
  • Consulta la aplicación skeleton como ejemplo de proyecto independiente que usa proxy.py.

Mediante Requirements

Se recomienda encarecidamente que uses proxy.py mediante requirements.txt o configuraciones similares de gestión de dependencias. Esto te permitirá aprovechar las actualizaciones periódicas de rendimiento, correcciones de errores, parches de seguridad y otras mejoras que ocurren en el ecosistema de proxy.py. Ejemplo:

  1. Usa la opción --pre para depender de la última pre-release

    root@kitploit:~
    ❯ pip install proxy.py --pre
    

    Las pre-releases son similares a depender del código de la rama develop, solo que las pre-releases pueden no apuntar al HEAD. Esto puede ocurrir porque las pre-releases NO están disponibles en PyPi después de cada fusión de PR.

  2. Usa TestPyPi con la opción --pre para depender del código de la rama develop

    root@kitploit:~
    ❯ pip install -i https://test.pypi.org/simple/ proxy.py --pre
    

    Se pone a disposición una pre-release en TestPyPi después de cada fusión de PR.

  3. Usa el código de la última versión stable

Mediante Contenedor Docker

Si te gusta desplegar contenedores, simplemente construye tu imagen a partir de las imágenes base del contenedor proxy.py.

  1. Usa GHCR para construir desde el código de la rama develop:

    root@kitploit:~
    FROM ghcr.io/abhinavsingh/proxy.py:latest as base
    

    PD: Yo uso la última versión de GHCR para varios proyectos de nivel de producción

  2. Usa DockerHub para construir desde el código de la última versión stable:

    root@kitploit:~
    FROM abhinavsingh/proxy.py:latest as base
    

PD: En mi humilde opinión, la estrategia basada en contenedores es el mejor enfoque y la única estrategia que yo mismo uso.

Integra tu CI/CD con proxy.py

Oye, pero sigues haciendo cambios que rompen la compatibilidad en la rama develop.

Te escucho. Y por lo tanto, para tus aplicaciones de nivel de producción, DEBES integrar el CI/CD de la aplicación con proxy.py. Debes asegurarte de que tu aplicación se construya y pase sus pruebas por cada fusión de PR en el repositorio ascendente de proxy.py.

Si tu repositorio de aplicación es público, en ciertos escenarios, los autores de PR pueden enviar PRs de parche para todas las dependencias para mantener la incompatibilidad hacia atrás y el CI/CD en verde.

La integración de CI/CD asegura que tu aplicación continúe construyéndose con el código más reciente de proxy.py. Dependiendo de dónde alojes tu código, usa la estrategia listada a continuación:

  • GitHub

    Pendiente

  • Google Cloud Build

    Pendiente

  • AWS

    Pendiente

  • Azure

    Pendiente

  • Otros

    Pendiente

En algún momento, dejaremos de usar la segregación de la rama master y simplemente mantendremos una rama develop. Ya que los dependientes pueden mantener la estabilidad mediante integraciones de CI/CD. Actualmente, es difícil para un proyecto de nivel de producción depender ciegamente de la rama develop.

Estable vs Develop

  • La rama master contiene el código stable más reciente y está disponible a través del repositorio PyPi y contenedores Docker a través de los registros docker.io y ghcr.io.

    Los problemas reportados para versiones stable se consideran con la máxima prioridad. Sin embargo, actualmente no retroportamos correcciones a versiones anteriores. Por ejemplo, si reportaste un problema en v2.3.1, pero la rama master actual ahora contiene v2.4.0rc1. Entonces, la corrección llegará en v2.4.0rc2.

  • La rama develop contiene cambios de vanguardia

    La rama de desarrollo se mantiene estable (la mayoría de las veces). Pero, si deseas 100% de confiabilidad y servir usuarios en entorno de producción, SIEMPRE usa la versión estable.

Cronograma de Lanzamientos

Se crea una solicitud de extracción vX.Y.ZrcN una vez al mes que fusiona develop → master. A continuación se muestra cómo fluye el código desde una solicitud de extracción hasta la próxima versión estable.

  1. La versión de desarrollo se despliega de develop → test.pypi.org después de cada fusión de solicitud de extracción

  2. La versión alfa se despliega de develop → pypi.org antes de fusionar la solicitud de extracción vX.Y.Z.rcN de develop → rama master. Puede haber múltiples versiones alfa antes de fusionar la solicitud de extracción rc

  3. La versión beta se despliega de master → pypi.org. Las versiones beta se realizan en preparación de las versiones rc y pueden omitirse si no son necesarias

  4. El candidato de lanzamiento se despliega de master → pypi.org. Los candidatos de lanzamiento siempre están disponibles antes de la versión estable final

Hilos vs Sin Hilos

v1.x

proxy.py solía generar nuevos hilos para manejar las solicitudes de los clientes.

v2.0+

proxy.py agregó soporte para ejecución sin hilos de solicitudes de clientes usando asyncio.

v2.4.0+

La ejecución sin hilos se activó por defecto para Python 3.8+ en entornos mac y linux.

La ejecución sin hilos de proxy.py ha sido reportada como segura en estos entornos por nuestros usuarios. Si tienes problemas, vuelve al modo con hilos usando el flag --threaded.

Para windows y Python < 3.8, aún puedes probar el modo sin hilos iniciando proxy.py con el flag --threadless.

Si el modo sin hilos te funciona, considera enviar un PR editando el método _env_threadless_compliant en el archivo proxy/common/constants.py.

Modo de ejecución Remoto vs Local sin Hilos

La implementación original sin hilos usaba el modo de ejecución remote. Esto también se muestra en Arquitectura de alto nivel como arte ASCII.

En el modo de ejecución remote, los aceptores delegan el procesamiento de las conexiones entrantes de clientes a un proceso trabajador remoto. Por defecto, los aceptores delegan las conexiones de forma round-robin. El trabajador que procesa la solicitud puede o no estar ejecutándose en el mismo núcleo de CPU que el aceptor. Esta arquitectura escala bien para alto rendimiento, pero resulta en la creación de dos procesos por núcleo de CPU.

Por ejemplo, si hay N CPU en la máquina, por defecto se inician N aceptores y N procesos trabajadores. Puedes ajustar el número de procesos usando los flags --num-acceptors y --num-workers. Puede que necesites más trabajadores que aceptores o viceversa según tu caso de uso.

En v2.4.x, se agregó el modo de ejecución local, principalmente para reducir la cantidad de procesos generados por defecto. Este modelo funciona bien para casos de uso diario de un solo usuario y para escenarios de pruebas de desarrolladores. En el modo de ejecución local, los aceptores delegan las conexiones de clientes a un hilo compañero, en lugar de a un proceso remoto. El modo de ejecución local asegura afinidad de CPU, a diferencia del modo remote donde el aceptor y el trabajador pueden estar ejecutándose en diferentes núcleos de CPU.

--local-executor 1 se estableció como predeterminado en la serie v2.4.x. En el modo de ejecución local, el flag --num-workers no tiene efecto, ya que no se inician trabajadores remotos.

Para usar el modo de ejecución remote, usa el flag --local-executor 0. Luego usa --num-workers para ajustar el número de procesos trabajadores.

SyntaxError: invalid syntax

proxy.py está estrictamente tipado y usa anotaciones de typing de Python. Ejemplo:```python

my_strings : List[str] = [] #############^^^^^^^^^#####

root@kitploit:~
Por lo tanto, se requiere una versión de Python que entienda las anotaciones typing. Asegúrate de usar `Python 3.6+`. Verifica la versión antes de ejecutar `proxy.py`: `❯ python --version` Todas las anotaciones `typing` se pueden reemplazar con anotaciones `comment-only`. Ejemplo:```python
>>> my_strings = [] # List[str]
>>> ################^^^^^^^^^^^

Esto permitirá que proxy.py se ejecute en Python pre-3.6, incluso en 2.7. Sin embargo, dado que todas las versiones futuras de Python serán compatibles con las anotaciones typing, esto no se ha considerado.

No se pueden cargar los plugins

Asegúrese de que los módulos de los plugins se puedan descubrir agregándolos a PYTHONPATH. Ejemplo:

`PYTHONPATH=/path/to/my/app proxy --plugins my_app.proxyPlugin````console ...[redacted]... - Loaded plugin proxy.HttpProxyPlugin ...[redacted]... - Loaded plugin my_app.proxyPlugin

root@kitploit:~
O, simplemente pase la ruta completamente calificada como parámetro, por ej.

`proxy --plugins /path/to/my/app/my_app.proxyPlugin`

Aquí hay un ejemplo rápido de trabajo:

- Contenidos de la carpeta `/tmp/plug````console
╰─ ls -1 /tmp/plug                                                                                                                       ─╯
my_plugin.py
  • Clase MyPlugin personalizada```console ╰─ cat /tmp/plug/my_plugin.py ─╯ from proxy.http.proxy import HttpProxyBasePlugin

class MyPlugin(HttpProxyBasePlugin): pass

root@kitploit:~
Este es un plugin vacío para demostrar el uso de plugins externos. Debes implementar los métodos necesarios para que tus plugins funcionen con tráfico real

- Inicia `proxy.py` con `MyPlugin````console
╰─ PYTHONPATH=/tmp/plug proxy --plugin my_plugin.MyPlugin                                                                      ─╯
...[redacted]... - Loaded plugin proxy.http.proxy.HttpProxyPlugin
...[redacted]... - Loaded plugin my_plugin.MyPlugin
...[redacted]... - Listening on ::1:8899

No se puede conectar con proxy.py desde un host remoto

Asegúrate de que proxy.py esté escuchando en la interfaz de red correcta. Prueba las siguientes opciones:

  • Para IPv6 --hostname ::
  • Para IPv4 --hostname 0.0.0.0

La autenticación básica no funciona con un navegador

Probablemente sea un problema de integración del navegador con el llavero del sistema.

  • Primero verifica que la autenticación básica funcione usando curl

    curl -v -x username:password@localhost:8899 https://httpbin.org/get

  • Consulta este hilo para obtener más detalles.

La imagen de Docker no funciona en macOS

Es un problema de compatibilidad con vpnkit.

Consulta moby/vpnkit agota los recursos de docker y Conexión rechazada: El proxy no pudo conectar para más contexto.

Integración del visor de registros de GCE para proxy.py

Hay disponible una plantilla inicial de fluentd.conf.

  1. Copia este archivo de configuración como proxy.py.conf en /etc/google-fluentd/config.d/

  2. Actualiza el campo path a la ruta del archivo de registro utilizada con la opción --log-file. Por defecto se sigue la ruta /tmp/proxy.log.

  3. Recarga google-fluentd:

    sudo service google-fluentd restart

Ahora los registros de proxy.py se pueden explorar usando el visor de registros de GCE.

ValueError: filedescriptor out of range in select

proxy.py está diseñado para manejar miles de conexiones por segundo sin fugas de sockets.

  1. Utiliza la opción --open-file-limit para personalizar ulimit -n.
  2. Asegúrate de ajustar la opción --backlog para mayor concurrencia.

Si nada ayuda, abre un issue con las solicitudes por segundo enviadas y la salida del siguiente script de depuración:

root@kitploit:~
import socket
import select

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    s.connect(('127.0.0.1', 8899))
except Exception as e:
    print("Could not connect to proxy.py:", e)
    raise SystemExit(1)

# Print the file descriptor number
print("Socket FD:", s.fileno())

# Try to select on it
r, w, e = select.select([s], [], [], 1)
print("Readable:", r, "Writable:", w, "Error:", e)
``````console
❯ ./helper/monitor_open_files.sh <proxy-py-pid>

None:None en registros de acceso

A veces puedes ver None:None en los registros de acceso. Simplemente significa que nunca se estableció una conexión con el servidor upstream, es decir, upstream_host=None, upstream_port=None.

Puede haber varias razones para que no haya conexión upstream; algunas obvias incluyen:

  1. El cliente estableció una conexión pero nunca completó la solicitud.
  2. Un plugin devolvió una respuesta prematuramente, evitando la conexión al servidor upstream.

OSError al envolver el cliente para la Intercepción TLS

Con la Intercepción TLS activada, ocasionalmente puedes ver las siguientes excepciones:```console 2021-11-06 23:33:34,540 - pid:91032 [E] server.intercept:678 - OSError when wrapping client Traceback (most recent call last): ...[redacted]... ...[redacted]... ...[redacted]... ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:997) ...[redacted]... - CONNECT oauth2.googleapis.com:443 - 0 bytes - 272.08 ms

root@kitploit:~
Algunos clientes pueden lanzar `TLSV1_ALERT_UNKNOWN_CA` si no pueden verificar el certificado del servidor porque está firmado por una CA emisora desconocida. Que es el caso cuando estamos realizando interceptación TLS. Esto puede deberse a varias razones, por ejemplo, fijación de certificados, etc.

Otra excepción que podrías ver es `CERTIFICATE_VERIFY_FAILED`:```console
2021-11-06 23:36:02,002 - pid:91033 [E] handler.handle_readables:293 - Exception while receiving from client connection <socket.socket fd=28, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8899), raddr=('127.0.0.1', 51961)> with reason SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:997)')
Traceback (most recent call last):
  ...[redacted]...
  ...[redacted]...
  ...[redacted]...
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:997)
...[redacted]... - CONNECT init.push.apple.com:443 - 0 bytes - 892.99 ms

En el futuro, podríamos admitir la entrega de contenido HTTPS original para dichos clientes mientras seguimos realizando la intercepción TLS en segundo plano. Esto mantendrá a los clientes satisfechos sin afectar nuestra capacidad de intercepción TLS. Desafortunadamente, esta funcionalidad no está disponible actualmente.

Otro ejemplo con la excepción SSLEOFError:```console 2021-11-06 23:46:40,446 - pid:91034 [E] server.intercept:678 - OSError when wrapping client Traceback (most recent call last): ...[redacted]... ...[redacted]... ...[redacted]... ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:997) ...[redacted]... - CONNECT stock.adobe.io:443 - 0 bytes - 685.32 ms

root@kitploit:~
# Guía para desarrolladores de plugins y colaboradores

## Arquitectura de alto nivel```console
                        +-------------+
                        |             |
                        |  Proxy([])  |
                        |             |
                        +------+------+
                               |
                               |
                   +-----------v--------------+
                   |                          |
                   |    AcceptorPool(...)     |
                   |                          |
                   +------------+-------------+
                                |
+-----------------+             |           +-----------------+
|                 |             |           |                 |
|   Acceptor(..)  <-------------+----------->  Acceptor(..)   |
|                 |                         |                 |
+---+-------------+                         +---------+-------+
    |                                                 |
    |                                                 |
    |    +------++------++------++------++------+     |
    |    |      ||      ||      ||      ||      |     |
    +---->      ||      ||      ||      ||      <-----+
         |      ||      ||      ||      ||      |
         +------++------++------++------++------+
                Threadless Worker Processes

proxy.py está hecho con el rendimiento en mente. Por defecto, proxy.py intentará utilizar todos los núcleos de CPU disponibles para aceptar nuevas conexiones de clientes. Esto se logra iniciando AcceptorPool, que escucha en el puerto del servidor configurado. Luego, AcceptorPool inicia procesos Acceptor (--num-acceptors) para aceptar conexiones entrantes de clientes. Además, si --threadless está habilitado, se configura ThreadlessPool, que inicia procesos Threadless (--num-workers) para manejar las conexiones entrantes de clientes.

Cada proceso Acceptor delega la conexión de cliente aceptada a un proceso threadless a través de la clase Work. Actualmente, HttpProtocolHandler es la clase de trabajo predeterminada.

HttpProtocolHandler simplemente asume que los clientes entrantes seguirán la especificación HTTP. Las implementaciones específicas de proxy HTTP y servidor HTTP se escriben como complementos de HttpProtocolHandler.

Consulte la documentación de HttpProtocolHandlerPlugin para conocer los hooks de ciclo de vida disponibles. Use HttpProtocolHandlerPlugin para agregar nuevas funciones para clientes http(s). Por ejemplo, consulte HttpWebServerPlugin.

Todo es un complemento

Dentro de proxy.py, todo es un complemento.

  • Habilitamos complementos de proxy server usando la bandera --plugins. El proxy server HttpProxyPlugin es un complemento de HttpProtocolHandler. Además, el proxy server permite complementos a través de la especificación HttpProxyBasePlugin.

  • Todos los ejemplos de complementos del proxy server implementaban HttpProxyBasePlugin. Consulte la documentación de HttpProxyBasePlugin para conocer los hooks de ciclo de vida disponibles. Use HttpProxyBasePlugin para modificar el comportamiento del protocolo proxy http(s) entre el cliente y el servidor upstream. Por ejemplo, FilterByUpstreamHostPlugin.

  • También habilitamos el web server incorporado usando --enable-web-server. El web server HttpWebServerPlugin es un complemento de HttpProtocolHandler e implementa la especificación .

Gestión de estados para sus complementos sin estado

Las instancias de clases de complemento se crean por solicitud. Es importante destacar que las instancias de complemento se crean dentro del contexto del núcleo de CPU donde se recibió la solicitud.

Por la razón anterior, las variables globales en sus complementos pueden no funcionar como se espera. Su código de complemento, por diseño, debe ser sin estado.

Para gestionar estados globales, tiene un par de opciones:

  1. Utilizar las estructuras de datos seguras para multiprocesamiento de Python.
  2. Utilizar el mecanismo de eventos integrado de proxy.py.

Pasar contexto de procesamiento entre complementos

A veces, un complemento puede necesitar pasar contexto adicional a otros complementos que le siguen en la cadena de procesamiento. Por ejemplo, este contexto adicional también puede ser volcado como parte de los registros de acceso.

Para pasar contexto de procesamiento, use el método on_access_log del complemento. Consulte cómo el complemento Program Name modifica la clave client_ip predeterminada en el contexto y la actualiza al nombre del programa detectado.

Como resultado, cuando habilitamos Program Name Plugin, vemos el nombre del programa del cliente local en lugar de la dirección IP en los registros de acceso.

Guía de desarrollo

Configurar el entorno local

Los contribuyentes deben iniciar proxy.py desde el código fuente para verificar y desarrollar nuevas características / correcciones.

Consulte Ejecutar proxy.py desde la línea de comandos usando el código fuente del repositorio para más detalles.

WARNING En macOS debe instalar Python usando pyenv, ya que el Python instalado mediante homebrew tiende a ser problemático. Consulte el hilo vinculado para más detalles.

Configurar Git Hooks

El hook pre-commit asegura que las pruebas pasen.

  1. cd /path/to/proxy.py
  2. ln -s $(PWD)/git-pre-commit .git/hooks/pre-commit

El hook pre-push asegura que el lint y las pruebas pasen.

  1. cd /path/to/proxy.py
  2. ln -s $(PWD)/git-pre-push .git/hooks/pre-push

Enviar un Pull Request

Cada pull request se prueba usando GitHub actions.

Consulte el flujo de trabajo de GitHub para la lista de pruebas.

Proyectos que usan Proxy.Py

Algunos proyectos populares que usan proxy.py

  • pip
  • ray-project
  • aio-libs
  • Selenium Base
  • wifipumpkin3
  • MerossIot
  • pyshorteners
  • Slack API
  • ibeam
  • PyPaperBot

Para la lista completa, consulte usado por

Benchmarks

Consulte el directorio Benchmark sobre cómo ejecutar comparaciones de benchmarks con otros servidores web OSS.

Para ejecutar el benchmark independiente de proxy.py, use el siguiente comando desde la raíz del repositorio:```console ❯ ./benchmark/compare.sh

root@kitploit:~
# Banderas```console
❯ proxy -h
usage: -m [-h] [--tunnel-hostname TUNNEL_HOSTNAME] [--tunnel-port TUNNEL_PORT]
          [--tunnel-username TUNNEL_USERNAME]
          [--tunnel-ssh-key TUNNEL_SSH_KEY]
          [--tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE]
          [--tunnel-remote-port TUNNEL_REMOTE_PORT] [--threadless]
          [--threaded] [--num-workers NUM_WORKERS] [--enable-events]
          [--inactive-conn-cleanup-timeout INACTIVE_CONN_CLEANUP_TIMEOUT]
          [--enable-proxy-protocol] [--enable-conn-pool] [--key-file KEY_FILE]
          [--cert-file CERT_FILE] [--client-recvbuf-size CLIENT_RECVBUF_SIZE]
          [--server-recvbuf-size SERVER_RECVBUF_SIZE]
          [--max-sendbuf-size MAX_SENDBUF_SIZE] [--timeout TIMEOUT]
          [--local-executor LOCAL_EXECUTOR] [--backlog BACKLOG]
          [--hostname HOSTNAME] [--hostnames HOSTNAMES [HOSTNAMES ...]]
          [--port PORT] [--ports PORTS [PORTS ...]] [--port-file PORT_FILE]
          [--unix-socket-path UNIX_SOCKET_PATH]
          [--num-acceptors NUM_ACCEPTORS] [--version] [--log-level LOG_LEVEL]
          [--log-file LOG_FILE] [--log-format LOG_FORMAT]
          [--open-file-limit OPEN_FILE_LIMIT]
          [--plugins PLUGINS [PLUGINS ...]] [--enable-dashboard]
          [--basic-auth BASIC_AUTH] [--enable-ssh-tunnel]
          [--work-klass WORK_KLASS] [--pid-file PID_FILE] [--openssl OPENSSL]
          [--data-dir DATA_DIR] [--ssh-listener-klass SSH_LISTENER_KLASS]
          [--disable-http-proxy] [--disable-headers DISABLE_HEADERS]
          [--ca-key-file CA_KEY_FILE] [--insecure-tls-interception]
          [--ca-cert-dir CA_CERT_DIR] [--ca-cert-file CA_CERT_FILE]
          [--ca-file CA_FILE] [--ca-signing-key-file CA_SIGNING_KEY_FILE]
          [--auth-plugin AUTH_PLUGIN] [--cache-requests]
          [--cache-by-content-type] [--cache-dir CACHE_DIR]
          [--proxy-pool PROXY_POOL] [--enable-web-server]
          [--enable-static-server] [--static-server-dir STATIC_SERVER_DIR]
          [--min-compression-length MIN_COMPRESSION_LENGTH]
          [--enable-reverse-proxy] [--rewrite-host-header] [--enable-metrics]
          [--metrics-path METRICS_PATH] [--pac-file PAC_FILE]
          [--pac-file-url-path PAC_FILE_URL_PATH]
          [--cloudflare-dns-mode CLOUDFLARE_DNS_MODE]
          [--filtered-upstream-hosts FILTERED_UPSTREAM_HOSTS]
          [--filtered-client-ips-mode FILTERED_CLIENT_IPS_MODE]
          [--filtered-client-ips FILTERED_CLIENT_IPS]
          [--filtered-url-regex-config FILTERED_URL_REGEX_CONFIG]

proxy.py v2.4.8.dev8+gc703edac.d20241013

options:
  -h, --help            show this help message and exit
  --tunnel-hostname TUNNEL_HOSTNAME
                        Default: None. Remote hostname or IP address to which
                        SSH tunnel will be established.
  --tunnel-port TUNNEL_PORT
                        Default: 22. SSH port of the remote host.
  --tunnel-username TUNNEL_USERNAME
                        Default: None. Username to use for establishing SSH
                        tunnel.
  --tunnel-ssh-key TUNNEL_SSH_KEY
                        Default: None. Private key path in pem format
  --tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE
                        Default: None. Private key passphrase
  --tunnel-remote-port TUNNEL_REMOTE_PORT
                        Default: 8899. Remote port which will be forwarded
                        locally for proxy.
  --threadless          Default: True. Enabled by default on Python 3.8+ (mac,
                        linux). When disabled a new thread is spawned to
                        handle each client connection.
  --threaded            Default: False. Disabled by default on Python < 3.8
                        and windows. When enabled a new thread is spawned to
                        handle each client connection.
  --num-workers NUM_WORKERS
                        Defaults to number of CPU cores.
  --enable-events       Default: False. Enables core to dispatch lifecycle
                        events. Plugins can be used to subscribe for core
                        events.
  --inactive-conn-cleanup-timeout INACTIVE_CONN_CLEANUP_TIMEOUT
                        Time after which inactive works must be cleaned up.
                        Increase this value if your backend services are slow
                        to response or when proxy.py is handling a high
                        volume. When running proxy.py on Google Cloud (GCP)
                        you may see 'backend_connection_closed_before_data_sen
                        t_to_client', with curl clients you may see 'Empty
                        reply from server' error when '--inactive-conn-
                        cleanup-timeout' value is low for your use-case.
                        Default 1 seconds
  --enable-proxy-protocol
                        Default: False. If used, will enable proxy protocol.
                        Only version 1 is currently supported.
  --enable-conn-pool    Default: False. (WIP) Enable upstream connection
                        pooling.
  --key-file KEY_FILE   Default: None. Server key file to enable end-to-end
                        TLS encryption with clients. If used, must also pass
                        --cert-file.
  --cert-file CERT_FILE
                        Default: None. Server certificate to enable end-to-end
                        TLS encryption with clients. If used, must also pass
                        --key-file.
  --client-recvbuf-size CLIENT_RECVBUF_SIZE
                        Default: 128 KB. Maximum amount of data received from
                        the client in a single recv() operation.
  --server-recvbuf-size SERVER_RECVBUF_SIZE
                        Default: 128 KB. Maximum amount of data received from
                        the server in a single recv() operation.
  --max-sendbuf-size MAX_SENDBUF_SIZE
                        Default: 64 KB. Maximum amount of data to flush in a
                        single send() operation.
  --timeout TIMEOUT     Default: 10.0. Number of seconds after which an
                        inactive connection must be dropped. Inactivity is
                        defined by no data sent or received by the client.
  --local-executor LOCAL_EXECUTOR
                        Default: 1. Enabled by default. Use 0 to disable. When
                        enabled acceptors will make use of local (same
                        process) executor instead of distributing load across
                        remote (other process) executors. Enable this option
                        to achieve CPU affinity between acceptors and
                        executors, instead of using underlying OS kernel
                        scheduling algorithm.
  --backlog BACKLOG     Default: 100. Maximum number of pending connections to
                        proxy server.
  --hostname HOSTNAME   Default: 127.0.0.1. Server IP address.
  --hostnames HOSTNAMES [HOSTNAMES ...]
                        Default: None. Additional IP addresses to listen on.
  --port PORT           Default: 8899. Server port. To listen on more ports,
                        pass them using --ports flag.
  --ports PORTS [PORTS ...]
                        Default: None. Additional ports to listen on.
  --port-file PORT_FILE
                        Default: None. Save server port numbers. Useful when
                        using --port=0 ephemeral mode.
  --unix-socket-path UNIX_SOCKET_PATH
                        Default: None. Unix socket path to use. When provided
                        --host and --port flags are ignored
  --num-acceptors NUM_ACCEPTORS
                        Defaults to number of CPU cores.
  --version, -v         Prints proxy.py version.
  --log-level LOG_LEVEL
                        Valid options: DEBUG, INFO (default), WARNING, ERROR,
                        CRITICAL. Both upper and lowercase values are allowed.
                        You may also simply use the leading character e.g.
                        --log-level d
  --log-file LOG_FILE   Default: sys.stdout. Log file destination.
  --log-format LOG_FORMAT
                        Log format for Python logger.
  --open-file-limit OPEN_FILE_LIMIT
                        Default: 1024. Maximum number of files (TCP
                        connections) that proxy.py can open concurrently.
  --plugins PLUGINS [PLUGINS ...]
                        Comma separated plugins. You may use --plugins flag
                        multiple times.
  --enable-dashboard    Default: False. Enables proxy.py dashboard.
  --basic-auth BASIC_AUTH
                        Default: No authentication. Specify colon separated
                        user:password to enable basic authentication.
  --enable-ssh-tunnel   Default: False. Enable SSH tunnel.
  --work-klass WORK_KLASS
                        Default: proxy.http.HttpProtocolHandler. Work klass to
                        use for work execution.
  --pid-file PID_FILE   Default: None. Save "parent" process ID to a file.
  --openssl OPENSSL     Default: openssl. Path to openssl binary. By default,
                        assumption is that openssl is in your PATH.
  --data-dir DATA_DIR   Default: ~/.proxypy. Path to proxypy data directory.
  --ssh-listener-klass SSH_LISTENER_KLASS
                        Default: proxy.core.ssh.listener.SshTunnelListener. An
                        implementation of BaseSshTunnelListener
  --disable-http-proxy  Default: False. Whether to disable
                        proxy.HttpProxyPlugin.
  --disable-headers DISABLE_HEADERS
                        Default: None. Comma separated list of headers to
                        remove before dispatching client request to upstream
                        server.
  --ca-key-file CA_KEY_FILE
                        Default: None. CA key to use for signing dynamically
                        generated HTTPS certificates. If used, must also pass
                        --ca-cert-file and --ca-signing-key-file
  --insecure-tls-interception
                        Default: False. Disables certificate verification
  --ca-cert-dir CA_CERT_DIR
                        Default: ~/.proxy/certificates. Directory to store
                        dynamically generated certificates. Also see --ca-key-
                        file, --ca-cert-file and --ca-signing-key-file
  --ca-cert-file CA_CERT_FILE
                        Default: None. Signing certificate to use for signing
                        dynamically generated HTTPS certificates. If used,
                        must also pass --ca-key-file and --ca-signing-key-file
  --ca-file CA_FILE     Default: /Users/abhinavsingh/Dev/proxy.py/.venv3122/li
                        b/python3.12/site-packages/certifi/cacert.pem. Provide
                        path to custom CA bundle for peer certificate
                        verification
  --ca-signing-key-file CA_SIGNING_KEY_FILE
                        Default: None. CA signing key to use for dynamic
                        generation of HTTPS certificates. If used, must also
                        pass --ca-key-file and --ca-cert-file
  --auth-plugin AUTH_PLUGIN
                        Default: proxy.http.proxy.auth.AuthPlugin. Auth plugin
                        to use instead of default basic auth plugin.
  --cache-requests      Default: False. Whether to also write request packets
                        in the cache file.
  --cache-by-content-type
                        Default: False. Whether to extract content by type
                        from responses. Extracted content type is written to
                        the cache directory e.g. video.mp4.
  --cache-dir CACHE_DIR
                        Default: /Users/abhinavsingh/.proxy/cache. Flag only
                        applicable when cache plugin is used with on-disk
                        storage.
  --proxy-pool PROXY_POOL
                        List of upstream proxies to use in the pool
  --enable-web-server   Default: False. Whether to enable
                        proxy.HttpWebServerPlugin.
  --enable-static-server
                        Default: False. Enable inbuilt static file server.
                        Optionally, also use --static-server-dir to serve
                        static content from custom directory. By default,
                        static file server serves out of installed proxy.py
                        python module folder.
  --static-server-dir STATIC_SERVER_DIR
                        Default: "public" folder in directory where proxy.py
                        is placed. This option is only applicable when static
                        server is also enabled. See --enable-static-server.
  --min-compression-length MIN_COMPRESSION_LENGTH
                        Default: 20 bytes. Sets the minimum length of a
                        response that will be compressed (gzipped).
  --enable-reverse-proxy
                        Default: False. Whether to enable reverse proxy core.
  --rewrite-host-header
                        Default: False. If used, reverse proxy server will
                        rewrite Host header field before sending to upstream.
  --enable-metrics      Default: False. Enables metrics.
  --metrics-path METRICS_PATH
                        Default: /metrics. Web server path to serve proxy.py
                        metrics.
  --pac-file PAC_FILE   A file (Proxy Auto Configuration) or string to serve
                        when the server receives a direct file request. Using
                        this option enables proxy.HttpWebServerPlugin.
  --pac-file-url-path PAC_FILE_URL_PATH
                        Default: /. Web server path to serve the PAC file.
  --cloudflare-dns-mode CLOUDFLARE_DNS_MODE
                        Default: security. Either "security" (for malware
                        protection) or "family" (for malware and adult content
                        protection)
  --filtered-upstream-hosts FILTERED_UPSTREAM_HOSTS
                        Default: Blocks Facebook. Comma separated list of IPv4
                        and IPv6 addresses.
  --filtered-client-ips-mode FILTERED_CLIENT_IPS_MODE
                        Default: blacklist. Can be either "whitelist"
                        (restrict access to specific IPs)or "blacklist" (allow
                        everything except specific IPs).
  --filtered-client-ips FILTERED_CLIENT_IPS
                        Default: 127.0.0.1,::1. Comma separated list of IPv4
                        and IPv6 addresses.
  --filtered-url-regex-config FILTERED_URL_REGEX_CONFIG
                        Default: No config. Comma separated list of IPv4 and
                        IPv6 addresses.

Proxy.py not working? Report at:
https://github.com/abhinavsingh/proxy.py/issues/new
Descargar herramienta
Plugin Cloudflare DNS Resolver
  • Plugin Custom DNS Resolver
  • Interfaz de Red Personalizada
  • Plugin Program Name
  • Plugins de Servidor Web HTTP
    • Ruta del Servidor Web
  • Plugins de Proxy Inverso
    • Proxy Inverso
  • Orden de los Plugins
  • Cifrado de Extremo a Extremo
  • Intercepción TLS
    • Intercepción TLS Insegura
    • Intercepción TLS con Docker
  • GROUT (Alternativa a NGROK)
    • Uso de Grout
    • Autenticación de Grout
    • Rutas de Grout
    • Dominios Comodín de Grout
    • Enrutamiento Comodín Basado en la Cabecera "Host"
    • Enrutamiento "Dinámico"
    • Grout usando Docker
    • Cómo funciona Grout
    • Grout autoalojado
  • Proxy sobre Túnel SSH
    • Proxy de solicitudes remotas localmente
    • Proxy de solicitudes locales de forma remota
  • Integrar proxy.py
    • Modo Bloqueante
    • Modo No Bloqueante
    • Puerto Efímero
    • Cargar Plugins
  • Pruebas unitarias con proxy.py
    • proxy.TestCase
    • Sobrescribir las Banderas de Inicio
    • Con unittest.TestCase
  • Utilidades
    • TCP
      • new_socket_connection
      • socket_connection
    • Http
      • build_http_request
      • build_http_response
    • Infraestructura de Clave Pública
      • Uso de la API
      • Uso de la CLI
  • Ejecutar el Panel de Control
    • Inspeccionar Tráfico
  • Protocolo Chrome DevTools
  • Métricas de Prometheus
  • Preguntas Frecuentes
    • Desplegar proxy.py en producción
      • ¿Qué no hacer?
      • Mediante Requirements
      • Mediante Contenedor Docker
      • Integrar tu CI/CD con proxy.py
    • Estable vs Desarrollo
      • Ciclo de Lanzamiento
    • Threads vs Threadless
    • Modo de Ejecución Threadless Remoto vs Local
    • SyntaxError: invalid syntax
    • No se pueden cargar los plugins
    • No se puede conectar con proxy.py desde un host remoto
    • La autenticación básica no funciona con un navegador
    • La imagen Docker no funciona en MacOS
    • ValueError: filedescriptor out of range in select
    • None:None en los registros de acceso
    • OSError al envolver el cliente para Intercepción TLS
  • Guía para Desarrolladores de Plugins y Contribuidores
    • Arquitectura de Alto Nivel
    • Todo es un plugin
    • Gestionar estados para tus plugins sin estado
    • Pasar contexto de procesamiento entre plugins
    • Documentación Interna
      • Read The Doc
      • pydoc
      • pyreverse
    • Guía de Desarrollo
      • Configurar Entorno Local
      • Configurar Git Hooks
      • Enviar un Pull Request
  • Proyectos Usando Proxy.Py
  • Benchmarks
  • Banderas
  • Registro de Cambios
    • v2.x
    • v1.x
    • v0.x
  • Consulte Threads vs Threadless y Modo de Ejecución Threadless Remoto vs Local para controlar el número de núcleos de CPU utilizados.

    Vea Benchmark para más detalles y para saber cómo ejecutar benchmarks localmente.

  • Ligero

    • Utiliza solo ~5-20 MB de RAM
      • Sin fugas de memoria
      • Inicie una vez y olvídese, no requiere reinicios
    • El tamaño de los contenedores comprimidos es de solo ~25 MB
    • Sin dependencias externas aparte de la biblioteca estándar de Python
  • Programable

    • Personalice el comportamiento del proxy usando Plugins del Servidor Proxy. Ejemplo:
      • --plugins proxy.plugin.ProxyPoolPlugin
    • Habilite el Servidor Web incorporado. Ejemplo:
      • --enable-web-server --plugins proxy.plugin.WebServerPlugin
    • Habilite el Servidor Proxy Inverso incorporado. Ejemplo:
      • --enable-reverse-proxy --plugins proxy.plugin.ReverseProxyPlugin
    • La API de plugins se encuentra actualmente en fase de desarrollo. Espere cambios que rompan la compatibilidad. Vea Desplegar proxy.py en producción sobre cómo asegurar la fiabilidad entre cambios de código.
  • Puede escuchar en múltiples direcciones y puertos

    • Use la bandera --hostnames para proporcionar direcciones adicionales
    • Use la bandera --ports para proporcionar puertos adicionales
    • Opcionalmente, use la bandera --port para sobrescribir el puerto predeterminado 8899
    • Capaz de servir múltiples protocolos en el mismo puerto
  • Panel de Control en Tiempo Real

    • Opcionalmente, habilite el panel de proxy.py.
      • Use --enable-dashboard
      • Luego, visite http://localhost:8899/dashboard
    • Inspeccione, Monitoree, Controle y Configure proxy.py en tiempo de ejecución
    • Soporte para Protocolo Chrome DevTools
    • Extienda el frontend del panel usando plugins basados en typescript
    • El panel se encuentra actualmente en fase de desarrollo. Espere cambios que rompan la compatibilidad.
  • Seguro

    • Habilite el cifrado de extremo a extremo entre los clientes y proxy.py
    • Vea Cifrado de Extremo a Extremo
  • Privado

    • Protección contra bloqueadores de tráfico basados en DNS
    • Navegue con protección contra malware y contenido para adultos activada
    • Vea DNS-over-HTTPS
  • Man-In-The-Middle

    • Puede descifrar el tráfico TLS entre los clientes y los servidores ascendentes
    • Vea Intercepción TLS
  • Protocolos http soportados para solicitudes de proxy

    • http(s)
      • http1
      • http1.1 con pipeline
    • http2
    • websockets
  • Soporte para Protocolo HAProxy

    • Vea la bandera --enable-proxy-protocol
  • Soporte para servidor de archivos estáticos

    • Vea las banderas --enable-static-server y --static-server-dir
  • Optimizado para cargas y descargas de archivos grandes

    • Vea las banderas --client-recvbuf-size, --server-recvbuf-size, --max-sendbuf-size
  • Soporte para IPv4 e IPv6

    • Vea la bandera --hostname
  • Soporte para sockets de dominio Unix

    • Vea la bandera --unix-socket-path
  • Soporte para autenticación básica

    • Vea la bandera --basic-auth
  • Soporte para PAC (Configuración Automática de Proxy)

    • Vea las banderas --pac-file y --pac-file-url-path
  • Vea High Level Architecture para entender la relación entre acceptors y workers
  • Started server on ::1:8899

    • Por defecto, proxy.py escucha en IPv6 ::1, que es el equivalente de IPv4 127.0.0.1
    • Si desea acceder a proxy.py desde un host externo, use --hostname :: o --hostname 0.0.0.0 o vincúlese a cualquier otra interfaz disponible en su máquina.
    • Vea CustomNetworkInterface para saber cómo personalizar la IP pública de proxy.py vista por los servidores upstream.
  • Port 8899

    • Use la bandera --port para personalizar el puerto TCP por defecto.
  • Como de costumbre, simplemente usa:

    root@kitploit:~
    ❯ pip install proxy.py
    
  • La versión estable se despliega de master → pypi.org

  • HttpProtocolHandlerPlugin
  • También existe una bandera --disable-http-proxy. Deshabilita el proxy server incorporado. Use esta bandera junto con --enable-web-server para ejecutar proxy.py como un servidor http(s) programable.