Je veux parler du processus de développement et partager le serveur proxy, que j'utilise moi-même pour filtrer toutes sortes de déchets et autres tâches qui nécessitent une visualisation ou une intervention dans le trafic du navigateur. Peut-être qu'il existe déjà une fonctionnalité similaire quelque part, mais je voulais le faire spécifiquement pour mes besoins avec la possibilité d'ajouter du code en temps réel à n'importe quelle bagatelle momentanée. Eh bien, sous les non-petites choses aussi, mais c'est plus long.
Initialement, la tâche consistait à simplifier la visite des sites via une connexion lente (environ 5 à 10 Ko / s avec des retards). Il existe deux domaines principaux: 1) pour supprimer tout ce qui n'est pas nécessaire (principalement la publicité) et 2) pour mettre en cache tout ce qui peut être mis en cache sans trop nuire à la fonctionnalité des sites visités, même lorsque les sites eux-mêmes ne permettent pas la mise en cache dans les en-têtes http, ou même ils interfèrent évidemment en ajoutant un point d'interrogation avec un nombre aléatoire après les URL des fichiers statiques.
Attention: l'implémentation décrite ci-dessous a été faite pour Linux, elle semble fonctionner sur d'autres * nix, mais même la compiler sur Windows n'a pas été envisagée (bien qu'il y ait, bien sûr, la possibilité de s'adapter).
Brouillon: nginx + php-fpm
Je ne voulais pas passer tout ce temps, il a donc été décidé de configurer rapidement le bundle nginx + php-fpm, dont les premières connexions entrantes analysées, y compris https et toutes redirigées, sans analyser les hôtes et les URL, vers le même script php . Il y avait aussi un petit programme C qui convertissait le protocole http-proxy en trafic http (s) normal. C'est-à-dire qu'il a transformé les demandes GET http://host/path HTTP/1.x
en GET /path HTTP/1.x
(le nom d'hôte est toujours dans l'en-tête Host) et a envoyé par proxy tous les https CONNECT au nginx local. Comme il s'est avéré plus tard, il http://host
n'était pas nécessaire de supprimer des requêtes http, nginx les accepte de la même manière que les requêtes habituelles.
PHP-, , , fsockopen() ( SSL ), http-, header() echo. , Évelyne Lachance https://github.com/eslachance/php-transparent-proxy ( , , ).
-, URL , POST- , Content-Type — php- , $_POST[] , , ( ). php 5.4 enable_post_data_reading — off, 'php://input'. $_POST $_FILES, , , .
-, nginx , " " firefox . , . , . ( ), , .
. , host host/path ( php- ). , ( — ). , . GET 200, — . — , , ( , ) content-type . : http-, content-type . , , , , , .
, , , .
( - , — ).
3-4 - — nginx php C.
( ), -, . https, - ( ), SSL - php .
OpenSSL. , , . , -, ( ), - ( ), - API OpenSSL ( ), API, ( ) ssl- ( , , ).
OpenSSL SSL, - API TLS, , , (, , , , ), ASN1. , API , RFC . .
SSL/TLS-
, , SSL/TLS, , , . : , , , . .
, (accept) , SSL/TLS, ( SSL/TLS-, ), , . http- https-, , .
, : , , .
ssl-server-wrapper
ssl-client-wrapper
. , — , , SSL- , .
$ host ya.ru - ip-
ya.ru has address 87.250.250.242
$ ./ssl-client-wrapper
T/etc/ssl/certs/ca-certificates.crt - RootCA
C87.250.250.242:443/ya.ru - SNI
( , ):
DEBUG: cert[-1] subject = /C=RU/O=Yandex LLC/OU=ITO/L=Moscow/ST=Russian Federation/CN=*.yandex.az
DEBUG: cert[-1] issuer = /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA
DEBUG: cert[0] subject = /C=RU/O=Yandex LLC/OU=ITO/L=Moscow/ST=Russian Federation/CN=*.yandex.az
DEBUG: cert[0] issuer = /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA
DEBUG: cert[1] subject = /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA
DEBUG: cert[1] issuer = /C=PL/O=Unizeto Technologies S.A./OU=Certum Certification Authority/CN=Certum Trusted Network CA
DEBUG: cert[2] subject = /C=PL/O=Unizeto Technologies S.A./OU=Certum Certification Authority/CN=Certum Trusted Network CA
DEBUG: cert[2] issuer = /C=PL/O=Unizeto Sp. z o.o./CN=Certum CA
trusted
DEBUG: cert[-1] issued by cert[1]
DEBUG: cert[1] issued by cert[2]
DEBUG: cert[2]=cert[*0] was not issued by something from trusted-cert-store - chain incomplete, trying to recover
DEBUG: cache miss at ./cert-pin/cache/9nqv0qm41tlxyel95bbods0famxjagbx.0
DEBUG: downloading AIA issuer cert: http://repository.certum.pl/ca.cer
DEBUG: cert[*0] issued by cert[*1]
DEBUG: cert[*1] is self-signed, chain ended
, "Certum CA" Root CA, , (cert[2]) http://repository.certum.pl/ca.cer ; (cert[*1]), . , Root CA "Certum Trusted Network CA", .
:
DEBUG: check wildcard '*.yandex.az' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.tm' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.com.ua' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.de' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.jobs' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.net' against needed name 'ya.ru'
DEBUG: check wildcard '*.xn--d1acpjx3f.xn--p1ai' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.com.ge' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.fr' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.fr' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.kz' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.aero' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.jobs' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.ee' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.com' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.tm' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.ru' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.ru' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.lv' against needed name 'ya.ru'
DEBUG: check wildcard '*.yandex.lt' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.az' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.net' against needed name 'ya.ru'
DEBUG: check wildcard 'yandex.lt' against needed name 'ya.ru'
DEBUG: check wildcard 'ya.ru' against needed name 'ya.ru'
:
DEBUG: protocol = TLSv1.2
DEBUG: cipher = ECDHE-RSA-AES128-GCM-SHA256
DEBUG: verify_result = 0
DEBUG: server_cert subject: /C=RU/O=Yandex LLC/OU=ITO/L=Moscow/ST=Russian Federation/CN=*.yandex.az
DEBUG: server_cert issuer: /C=RU/O=Yandex LLC/OU=Yandex Certification Authority/CN=Yandex CA
OK: connection to 87.250.250.242:443/ya.ru established
, http-
GET / HTTP/1.0
Host: ya.ru
Connection: close
HTTP/1.1 200 Ok
Accept-CH: Viewport-Width, DPR, Device-Memory, RTT, Downlink, ECT
Accept-CH-Lifetime: 31536000
(...)
, .
nginx , . , \r\n \n , , , Content-Length, . Chunked encoding — , http-, .
, , — , php, . ( , , ..), php- , , "" ( C PHP), " -" . ( ) "" "" include ( ).
, 2 . — - ( ), , .
SSL/TLS-, ssl-telnet. - ( -), . , . OpenSSL ( , - ). .
- : ( ), ( ), (, , — ). ( , ). , , .
- , , trusted root CA .
, , ssh port forwarding ( helpers/remote.c proxy.c "--proxy". . SSL/TLS , "" . , .
: , , , , raw- ( real-time ).
/etc/hosts : - , , .
, , , . ( , ), . " , — ", . , , , " - ".
- — , , . - ( offline.flag , ). , , , ( POST- ), , , — .
, . , handle/inc.rewrite.c
dashboard ( ) .
./dashboard --basedir=/path/to/proxy/base --highlight --loop
. , , , , , . , - — , " ".
(+)
(-) - OpenSSL
(+)
(+-) #define
(+-) IPv6
(-)
(-)
(-) Access-Control-Allow-Origin '*' — .
(-) ,
(-) ( raw ) — , localhost- , , - ( ) 10
/
C-, zlib ( gzip http-), openssl ( ssl-). Debian zlib1g-dev libssl-dev. () .
, ( ) (, Makefile, make) build-all.sh.
: fproxy/build2.sh, fproxy/config.h ( /etc/ssl/certs/ca-certificates.crt
). (helpers/) #define (config.h ), .
, , () . , ( ), — , ( #define-). build-all.sh .
.
. prepare-dir.sh — fproxy-target/ ( ).
— ( fproxy-target/, prepare-dir.sh).
-. , , , . " " , root , 0640 0750. world-readable , , - , , MITM.
dashboard BASE/log/dashboard
.
127.0.0.10:3128. 127.0.0.10 ( ) , - .
— , , .
: .
, , "-", . , .
— (, , , ) , , .
, - .