PHP + Apache como proxy directo / inverso: ¿cómo procesar las requestes del cliente y las respuestas del server en PHP?

Estoy teniendo un montón de problemas con la configuration adecuada de Apache mod_proxy.so para trabajar como desee …

La idea principal es crear un proxy en una máquina local en una networking que tendrá la capacidad de procesar una request de cliente (cliente conectado a través de este proxy preparado por Apache) en PHP. Y también, tendrá la capacidad de procesar las respuestas del server en PHP también.

Esas son las 2 funcionalidades, y son independientes el uno del otro.

Permítanme presentar un pequeño esquema de lo que necesito lograr:

texto alternativo

Como puede ver aquí, hay dos maneras: azul uno y rojo uno.

Para el azul, básicamente conecté un cliente (Máquina B – teléfono celular) a mi networking local (casa) y lo configuré para pasar por un proxy, que es la Máquina A (computadora personal) en la misma networking.

Así que digamos (no DHCP):

Máquina A: 192.168.1.40 -> Apache se está ejecutando en esta máquina, y configurado para escuchar el puerto 80.

Máquina B (teléfono celular): 192.168.1.75 -> configurado para pasar por un proxy, que es IP 192.168.1.75 y el puerto 80 (básicamente, Máquina A).

Después de configurar correctamente Apache, que es básicamente eliminar el "#" de httpd.conf en las líneas para el mod_proxy.so (trabajador principal), mod_proxy_connect.so (SSL, allowCONNECT, …) y mod_proxy_http.so (necesario para manejar request HTTP / respuestas) y tener en mi caso, líneas como esta:

# Implements a proxy/gateway for Apache. Include "conf/extra/httpd-proxy.conf" # Various default settings Include "conf/extra/httpd-default.conf" # Secure (SSL/TLS) connections Include "conf/extra/httpd-ssl.conf" 

Lo que me da la posibilidad de configurar el file httpd-proxy.conf para preparar el proxy directo o el proxy inverso.

Así que no estoy seguro, si lo que necesito es un proxy directo o uno inverso.

Para un proxy directo he hecho esto:

 <IfModule proxy_module> <IfModule proxy_http_module> # # FORWARD Proxy # #ProxyRequests Off ProxyRequests On ProxyVia On <Proxy *> Order deny,allow # Allow from all Deny from all Allow from 192.168.1 </Proxy> </IfModule> </IfModule> 

que básicamente pasa todos los packages normalmente al server y de vuelta al cliente. Puedo rastrear perfectamente (y probar que funciona) mirando el "access.log" de Apache. Cualquier request que haga con el teléfono celular aparecerá en el logging de Apache. Así funciona.

Pero aquí viene el problema:

  • Necesito procesar las requestes de los clientes. Y tengo que hacerlo, en PHP.

He leído mucho sobre esto. He leído en detalle el sitio oficial de Apache sobre mod_proxy. Y he buscado mucho en los foros, pero sin suerte.

Así que pensé en una primera aproximación:

1) Forward proxy en Apache, pasa todos los packages y no es posible procesarlos. Esto parece ser cierto, por lo tanto, ¿qué pasa con un proxy inverso?

Así que imaginé algo como:

 ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass http://www.google.com http://www.yahoo.com ProxyPassReverse http://www.google.com http://www.yahoo.com 

que es sólo una testing, pero esto debería causar en mi teléfono celular que al tratar de navegar a Google, debo ir a Yahoo, ¿no? Pero no. No funciona.

Así que realmente ves, que TODOS los ejemplos en Apache proxy inverso, va como:

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

lo que significa que cualquier tipo de request en un context local, se resolverá en una location remota.

¡Pero lo que necesitaba era lo inverso! Es que al solicitar un sitio remoto en mi teléfono, resuelvo esta request en mi server local (el Apache) para procesarlo con un module PHP.

Por lo tanto, si es un proxy directo, necesito pasar primero por PHP. Si es un proxy inverso, necesito cambiar la dirección "going" a mi server local para procesar primero en PHP.

Entonces viene en mente segunda opción:

2) He visto algo como:

 <Proxy http://example.com/foo/*> SetOutputFilter INCLUDES </Proxy> 

Y empecé a search SetOutputFilter, SetInputFilter, AddOutputFilter y AddInputFilter .

Pero realmente no sé cómo puedo usarlo.

Parece ser bueno, o una solución para mí, porque con algo como esto, debería ser capaz de añadir un filter de input para procesar en PHP las requestes del cliente y devolver al cliente lo que programé / desea (no la respuesta del server remoto ) que es el path BLUE en el esquema, y ​​debería tener la capacidad de agregar un filter de salida que parece darme la capacidad de procesar la respuesta del server remoto antes de enviarlo al cliente, que debería ser la ruta ROJA en el esquema.

Camino rojo, es sólo para leer las respuestas del server y jugar con ellos. Pero nada más. El path azul, es el importante. Porque enviaré al cliente lo que quiera después de procesar las peticiones.

Lo siento por este post increíblemente grande, pero necesitaba explicarlo tan bien como pueda.

¡Espero que alguien entienda mi problema, y ​​me ayudará a solucionarlo!

2 Solutions collect form web for “PHP + Apache como proxy directo / inverso: ¿cómo procesar las requestes del cliente y las respuestas del server en PHP?”

Bueno, entonces primero de todo: Apache es la herramienta equivocada!

Apache es un server web, no un server proxy. Sí, viene con un module proxy, pero ante todo es un server web.

Por el contrario, debe search en un server proxy real como calamar. Y dentro de squid usted está buscando una característica llamada "Content Adaptation":

http://wiki.squid-cache.org/SquidFaq/ContentAdaptation

@Sarek tiene razón, pero la pregunta es acerca de cómo manejar las requestes de proxy con PHP (desde el mod_proxy de Apache) no si Apache es la herramienta adecuada para eso.

Para usar PHP con Apache como proxy, utilizo (requiere mod_proxy y mod_rewrite) en httpd.conf :

 # Forward proxy server <VirtualHost *:8080> ProxyRequests On ProxyVia On <Proxy *> Order deny,allow Deny from all Allow from 192.168 RewriteEngine On RewriteCond %{REQUEST_URI} !/pac.php RewriteRule ^ /endpoint.php [L] </Proxy> </VirtualHost> 

Luego en /pac.php (que definen el contenido del file PAC ):

 <?php header('Content-Type: application/x-javascript-config') ?> function FindProxyForURL(url, host) { return "PROXY <?php echo $_SERVER['SERVER_ADDR'] ?>:<?php echo $_SERVER['SERVER_PORT'] ?>; DIRECT"; } 

Se utiliza para la configuration de proxy en la máquina B (cliente proxy). Utilice http://192.168.1.40:8080/pac.php . Con eso, el cliente siempre utilizará el proxy para cualquier dominio / ip (como 127.0.0.1, localhost, * .local, etc.). Nota: las aplicaciones IE y .Net todavía necesitan escribir sólo para localhost y 127.0.0.1 el punto final FQDN: http://localhost. y http://127.0.0.1. .

Finalmente en /endpoint.php :

 <?php // Don't handle domain existance $url = $_SERVER['REQUEST_URI']; $url_parts = parse_url($url); // Some security checks (no local file...) if(false === $url_parts || empty($url_parts['scheme']) || !in_array($url_parts['scheme'], array('http', 'https'))){ die(); } $headers_raw = ''; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') { $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))); $headers_raw .= $name . ': ' . $value . "\r\n"; } else if ($name == "CONTENT_TYPE") { $headers_raw .= 'Content-Type: ' . $value . "\r\n"; } else if ($name == "CONTENT_LENGTH") { $headers_raw .= 'Content-Length: ' . $value . "\r\n"; } } // http://php.net/manual/en/context.http.php $context = stream_context_create(array( 'http' => array( 'method' => $_SERVER['REQUEST_METHOD'], 'header' => $headers_raw, 'ignore_errors' => true, 'content' => file_get_contents('php://input') ) )); $content = file_get_contents($url, false, $context); $content_type = 'application/octet-stream';// "text/html" $content_type_raw = $content_type;// "text/html; charset=UTF-8" foreach($http_response_header as $response_header){ if('Content-Type:' == substr($response_header, 0, 13)){ $content_type_raw = substr($response_header, 14); $content_type = strstr($content_type_raw, ';', true); header($response_header); } elseif('Content-Encoding:' == substr($response_header, 0, 17) && 'gzip' == substr($response_header, 18, 4)) { //Now lets uncompress the compressed data $content = gzinflate(substr($content, 10, -8)); } elseif('Content-Length:' == substr($response_header, 0, 15)) { //Skip it } else{ header($response_header); } } // Content transforms //var_dump($url_parts);exit(); if('text/html' == $content_type){ echo str_replace('cat', 'dog', $content); }else{ echo $content; } 

Es un ejemplo, no lo utilice en la producción. No maneja ningún dominio no válido / timeout / ip.

Con esto puedes volver a escribir la URL solicitada (el proxy puede publicar el contenido de http://google.com/search?q=dog para la URL http://google.com/search?q=cat , una broma divertida) y actualizar el contenido (como eliminar anuncios, insert JS / CSS, etc.)

  • ¿Cómo puedo configurar un proxy casual
  • Cómo cambiar la configuration de proxy para la count de service de networking desde el símbolo del sistema?
  • Cómo configurar una networking para bloquear gmail pero permitir google apps correo?
  • Extraño problema de proxy de networking
  • ¿Cómo puedo networkingirigir con Apache proxy inverso en errores de server
  • ¿Los proxies realmente proporcionan anonimato?
  • ¿Qué comportamiento debo esperar cuando un file proxy "PAC" de los usuarios no está disponible?
  • ¿Revertir proxy para el server de correo?
  • Buen software de server proxy de código abierto para el server de Windows?
  • Autenticar automáticamente al proxy de mi empresa sin la interacción del usuario
  • Anubis como proxy GPG
  • Cómo configurar apache para comportarse como un browser remoto?
  • URL de redirect de Apache2 a otro server interno
  • El linux y los temas del servidor de Windows, como ubuntu, centos, apache, nginx, debian y consejos de red.