net4people / bbs

Forum for discussing Internet censorship circumvention
3.38k stars 80 forks source link

HTTPT: A Probe-Resistant Proxy (FOCI 2020) #50

Open wkrp opened 4 years ago

wkrp commented 4 years ago

HTTPT: A Probe-Resistant Proxy Sergey Frolov, Eric Wustrow https://censorbib.nymity.ch/#Frolov2020b https://www.usenix.org/conference/foci20/presentation/frolov (video and slides) https://github.com/sergeyfrolov/httpt

The paper describes HTTPT, a probe-resistant proxy design built on HTTPS. Probe-resistant proxy servers defeat active probing attacks by requiring the client to prove knowledge of a secret before revealing their proxy functionality. Most contemporary probe-resistant proxies, like obfs4 and Shadowsocks, use a randomized protocol and respond to authentication failures by remaining silent, which is conceptually sound, but somewhat uncommon in the universe of protocols and tricky to do right. HTTPT, in comparison, uses HTTPS as its carrier protocol, and responds to unauthenticated client requests not by remaining silent, but by replying the way a non-proxy-capable web server would. HTTPS offers a number of nice features for implementing a proxy: it is a common protocol with many diverse implementations; TLS itself is resistant to replay-based probing; TLS adds only a small amount of framing overhead; and it is possible to co-locate a proxy with exiting HTTPS services.

An HTTPT client authenticates itself by requesting a secret URL path. This unguessable path is known only to legitimate clients and is the only means of accessing the web server's hidden proxy functionality. Unauthenticated clients are therefore unable to probe it. The web server is configured to forward requests for the secret path as if it were forwarding a WebSocket connection, transforming the HTTPS connection into a two-way TLS-protected stream between the client and the HTTPT proxy backend. This WebSocket trick enables broad compatibility for HTTPT, as all major web servers have the ability to do WebSocket forwarding, without a custom plugin. (The paper tests with Apache, Nginx, and Caddy.) Once forwarded, the remainder of the connection does not even have to conform to the WebSocket protocol, which means there is no overhead beyond what is added by TLS.

The ideal situation for HTTPT deployment is to install a proxy on an established HTTPS web site. Unauthenticated active probers will only find whatever the web site normally serves, while authenticated clients who know the secret path can access the proxy. An established web site already has a reasonable TLS fingerprint and a valid certificate. (The client still has to take care about its TLS fingerprint, using uTLS or something similar.) A deployment not connected to any existing web server is also possible, but requires some thought towards what to return on an authentication failure. Section 3.2 of the paper covers some options, which include returning an error page or transparently proxying some other web site are all possibilities. According to a Censys survey, returning an error page is not unusual: about half of actual HTTPS servers respond with a 4xx or 5xx status code when probed.

Thanks to the authors for reviewing a draft of this summary.

ghost commented 4 years ago

One thing worth to mention, almost same goal has been implemented in some proxy software in China. V2Ray has a WebSocket transport layer and TLS support, VMess with WSS is one of the most popular proxy protocol in China. Trojan-Go also has WebSocket transport, and because of it's low overhead, it's became popular. In typical deployment, they're hidden behind a web server (Nginx or Caddy), if you are interested about it, here's some example config: https://github.com/v2fly/v2ray-examples About WebSocket, one good thing is they can proxy by CDN (In most situation CloudFlare).

RPRX commented 4 years ago

And VLESS Protocol: https://github.com/v2ray/v2ray-core/issues/2636

https://www.v2fly.org/config/protocols/vless.html#fallbackobject

https://github.com/v2fly/v2ray-examples/tree/master/VLESS-TCP-TLS-WS%20(recommended)

RPRX commented 4 years ago

When working over TLS, VLESS protocol supports pure TLS, WebSocket, and even fake HTTP header at the same time.

Also, when using WebSocket or fake HTTP header, users are able to replace VLESS with VMess or any other protocols.

VLESS will simply recognize HTTP PATH, then transfer data to another VLESS or maybe another protocol.

(Plus, CDN like CloudFlare supports WebSocket.)

wkrp commented 4 years ago

In typical deployment, they're hidden behind a web server (Nginx or Caddy), if you are interested about it, here's some example config: https://github.com/v2fly/v2ray-examples

Thank you for these links. Let me see if I understand. I am looking at https://github.com/v2fly/v2ray-examples/tree/23ff897072fb51ee23f5c4391a2118a2c328d934/VMess-Websocket-TLS/Nginx. In nginx_Domain.Name.conf there is a section that forwards requests for a secret path /GLMzpX/ to 127.0.0.1:10086 using proxy_pass:

upstream v2ray {
        server      127.0.0.1:10086;    #注:v2ray后端监听地址、端口 "Note: The v2ray back-end listens on addresses and ports."
        keepalive   2176;   # 链接池空闲链接数 "Number of free links in the link pool"
}

...

    location /GLMzpX/ { #注:修改路径 "Note: Modify the path"
        proxy_http_version  1.1;
        proxy_set_header    Upgrade $http_upgrade;
        proxy_set_header    Connection $connection_upgrade; #此处与<map>对应 "This corresponds to <map>."
        proxy_set_header    Host $http_host;

        # 向后端传递访客ip "Passing guest IPs to the backend"
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        #后端错误重定向 "Back-end error redirects"
        proxy_intercept_errors on;
                error_page 400 = URL;       # url是一个网站地址。例如:https://www.xxxx.com/ "A url is a website address. For example: https://www.xxxx.com/"
        if ($http_host = "domain.Name" ) {  #注: 修改 domain.Name 为自己的域名 "Note: Change domain.Name to your own domain."
            #v2ray 后端 查看上面"upstream"字段 "v2ray Backend View the "upstream" field above."
            proxy_pass      http://v2ray;
        }
    }

In config_client.json, there is a stanza configuring WebSocket-in-TLS. I suppose that the /PATH/ would have to be changed to match the secret path above.

      "streamSettings": {
        "tlsSettings": {
          "allowInsecure": false
        },
        "wsSettings": {
          "headers": {
            "Host": "domain.Name"
          },
          "path": "/PATH/"
        },
        "network": "ws",
        "security": "tls"
      },

I agree, this is quite similar. It gives proper probing resistance while hiding the proxy behind a secret path. In HTTPT, they found that it is not even necessary to use WebSocket framing when using such a setup--though it may be required when forwarding through Cloudflare, I am not sure.

sergeyfrolov commented 4 years ago

It is true that we probably are not the first to think of hiding the proxies behind popular applications. Out of those popular applications, the web servers seem to be the best choice, but I encourage the use of other applications, too, as well as highly encourage other HTTPS proxying implementations. This paper's primary purpose is to convince the censorship circumvention tool developers to redirect their efforts into this approach.

Deployment of HTTPS proxies is considerably more complicated than shadowsocks or obfs4, so anti-censorship developers need to know the benefits before spending the effort, and we documented those benefits. As David summed up, we argue that our HTTPS proxying approach is practical, performant, resistant to the current state of the art probing attacks, and more resistant to fingerprinting than other protocols, including randomized ones. We've also shown that you don't need original website content, which was a potential pain point for censorship circumvention developers, although, as David pointed out, that "requires some thought towards what to return on an authentication failure"; perhaps we can eventually automate the random selection of one of the options and its deployment.

RPRX commented 4 years ago

Another lightweight way is fake HTTP header, it's HTTP PATH can be recognized by VLESS when VLESS handling TLS at the server side.

RPRX commented 4 years ago

https://www.v2fly.org/config/transport/tcp.html#httpheaderobject