Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Surveillance proof proxy connection with plausible deniability. #224

Closed
xiaokangwang opened this issue Jul 30, 2016 · 14 comments
Closed

Comments

@xiaokangwang
Copy link
Contributor

I was thinking about implementing a new transport, so that an observer will identify connection it create as valid TLS connection to an well-known site.

This transport consists of two parts, the first one will harvest the certifications from other sites, the content harvested also include offered encryption methods, signatures for key exchange if connection have perfect forward secrecy.

The rest part will integrated with your program, which will utilize content we have harvested. Before key change, both client and server will replay the content is harvested, incuding SNI, preferred encryption method and more if possible. As for key exchange, for connections without PFS, server will use the pre-shared key as content it decrypted by its server private key as if it own the key. The client will also use the pre-shared key as content it encrypted with server's public key. Both side will compute the session key from client random, server random and pre-shared key. An observer will not be able to notice that server does not actually own the private key for the certificate it provided to client. For connections with FPS, we will send the the DH or ECDH info with harvested signature(both info and signature are harvested), both client and server will ignore the key from DH and use pre-shared key as key exchange result. The computation of session key is similar to that of non-PFS connections. The observer might notice the DH or ECDH info never change or have a limited possibility, but have no way to deduce if server have the private key.

Currently, the use of TLS connection in v2ray is more complicated than an ordinary user can accept, as the issue of valid certificate follows a secure routine which can be hard to follow. The certificate user used is often self-signed which can be easy to detect or block. Even using the certificate from valid CA can raise notice as the observer can discover the user of V2Ray is accessing a uncommon site. In both case, the surveillance system can detect unusual event and could trigger an alert to authority. With the use of certificate harvested, government might think twice before block our connection.

@v2ray
Copy link
Collaborator

v2ray commented Aug 2, 2016

If I understand correctly, this proposal is similar to tls1.2_ticket_auth in SSR, with more options in domains and encryption keys.

There are 2 concerns with this approach:

  1. The server can't perform a real TLS handshake. It is easily detectable by others, by just asking for a standard TLS handshake.
  2. Performance-wise (speed) it will not be better than a real TLS connection. If a real TLS connection gets blocked, the fake one will also be blocked, and vise-versa.

@xiaokangwang
Copy link
Contributor Author

I didn't considered about active probe. This is a fatal shortcoming of this method.

I believe that the better way to ensure plausible deniability is to implement websocket transport proposed at #83. Which can behave as a ordinary HTTPS server unless client knocked correctly.

@xiaokangwang
Copy link
Contributor Author

xiaokangwang commented Aug 2, 2016

This issue will focus on implement a proxy transport with plausible deniability, not the way to do that I have proposed previously.

@v2ray
Copy link
Collaborator

v2ray commented Aug 2, 2016

I don't think it is necessary to be in the transport layer, but you may draft some design first in order to discuss further.

@xiaokangwang
Copy link
Contributor Author

Websocket transport spec:
Configure :
Stream type : Websocket
Websocket settings, located near tls settings :
Listening address(inbound only) : (string) the path this inbound listening.
Destination url (Outbound only) : (string) the Websocket uri this Outbound is connecting.
Bind address(inbound only) : the tcp address http listener will listen to.

Since Websocket is almost a drop in replacement for tcp what we need to do is very little.

Once listen is called, it will set itself as the handler of corresponding path, and start http server.

The handler will simply pass the connection to the handler listener specified.

Connection reuse should be implemented as the complete handshake could be as expensive as two tls(one at forwarder, the other one will be v2ray tls) , one Websocket over http and one tcp over Internet combined.

This transportation is designed for user that have a regular website which support tls, and live in an area that the Internet is being not only surveillance but also regularly examined by experts. User could be disconnected from the Internet if be discovered to use proxy, or face more severe penitentiary.

Currently, the regular vmess connection will be recognized as unknown by surveillance device(at least we wish it to be recognize as unknown). However if a end user's majority of traffic is unrecognizable, it is very likely to trigger alert if the traffic have been manually reviewed. The most of traffic from a submissive Internet user can be recognized, while a user using v2ray won’t. This could be used to identify to whether a user have used a way to avoid censorship or surveillance.

The user should use balancer(nginx) to forward Websocket traffic to v2ray. The website will show normal content if the url given is not appropriate, and will not be forwarded to v2ray by nginx. This can prevent almost all active probe as it will be very hard to guess the url.

If the network operators detected such a connection it will be impossible for them to know if such a connection is a ordinary https traffic or encapsulated v2ray traffic.

@v2ray
Copy link
Collaborator

v2ray commented Aug 4, 2016

I prefer to do this in HTTP proxy. WebSocket is based on HTTP. Both client and server need to understand HTTP protocol. HTTP proxy is more suitable because it already handles CONNECT. WebSocket is just another a GET request with Upgrade header.

The advantage with a transport is, the transport can carry other format of payload, say socks. However, assuming WebSocket is always used with HTTPS, it doesn't make sense to embed another encrypted format inside.

My plan was to implement the HTTP client proxy after socks client, and then expand it with WebSocket. If you wanna take over the WebSocket part. I can assign the issue to you.

@xiaokangwang
Copy link
Contributor Author

I insist that VMess over Websocket should be implement as transport.

We are not talking about ask V2Ray to relay Websocket connection but asking Websocket to relay a VMess connection.

HTTP proxy and a HTTP server are different. The typical usage of VMess over Websocket will be forwarding the corresponding to the port Websocket is listening. It is unlikely that anyone make a reverse proxy for a HTTP proxy and most of people will prefer to keep HTTP proxy private.

@xiaokangwang
Copy link
Contributor Author

Websocket is similar to KCP not socks.

@xiaokangwang
Copy link
Contributor Author

What's more, Websocket transport can use net.http Golang provided and act as a normal HTTP server not HTTP proxy.

@v2ray
Copy link
Collaborator

v2ray commented Aug 4, 2016

Ok. You are talking about a real (or compatible) WebSocket implementation. Yes that is doable in transport layer. You can continue with your proposal.

However, I don't see any benefit from WebSocket as a transport, in terms of speed and obfuscation. V2Ray will not prevent you from implementing it. It just seems not going to have much usage.

@xiaokangwang
Copy link
Contributor Author

I am not implementing WebSocket, just considering to use Websocket as a transport to discourage recognize. The websocket is already available as a official repo.

@xiaokangwang
Copy link
Contributor Author

I am implementing it as a last resort. If a ISP block all unknown traffic and active probe all unsure service, it will be the very transport to use.

@xiaokangwang
Copy link
Contributor Author

I am thinking about integrate meek into this proposing transport along with websocket, which can provide similar functionality and don't conflict with each other.

@v2ray
Copy link
Collaborator

v2ray commented Aug 12, 2016

@v2ray v2ray closed this as completed Aug 12, 2016
rosebe pushed a commit to rosebe/v2ray-core that referenced this issue Sep 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant