Open mal19992 opened 1 month ago
This improvement feature is easy to implement
Such claims should come with actual code that shows that "it is easy to implement".
I will try to look,but I am not very familiar with OpenVPN codebase
I agree with @cron2, however I believe this is an interesting feature and would be nice to have.
I reviewed the concept
#engine = pkcs11
foreground = yes
[service]
#engine = auto
#engineId = pkcs11
client = yes
accept = 127.0.0.5:7999
sni = proxy.xxxxxxxxxx.com
connect = proxy.xxxxxxxxxx.com:443
debug = 7
# uncomment to enable SSL remote server certificate verification
#CAfile = /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
#verify = 2
#verifyChain = yes
# to match sni
#checkHost = proxy.xxxxxxxxxx.com
and run it as stunnel stunnel.conf
This example creates SSL connection to remote http proxy behind SSL proxy.xxxxxxxxxx.com:443, the unencrypted stream is then available locally at 127.0.0.5:7999. OpenVPN http proxy is now set to 127.0.0.5:7999
The result -- the ISP sees only regular https connection (from stunnel) to proxy.xxxxxxxxxx.com:443, the OpenVPN TCP goes under this TLS link. The ISP does not recognize this traffic as being from OpenVPN and does not throttle it. No problem whatsoever. This solution is the best to VPN traffic identification https://community.openvpn.net/openvpn/wiki/TrafficObfuscation among several I tried. It really works and is completely separate from OpenVPN internals. All it requires -- run apache http proxy behind SSL. Just one extra line with letsencrypt config.
It is very inconvenient to run an extra tunnel. It is much easier to include to OpenVPN an ability to work with http proxy behind SSL.
I think the best option would be not a separate proxy setting that I originally described in the first post, but, instead, a single boolean config flag
http_proxy_over_ssl = true
which makes to open TLS connection before opening http proxy. This is somewhere in
--- a/src/openvpn/socket.c
+++ b/src/openvpn/socket.c
@@ -2068,8 +2068,15 @@ phase2_tcp_client(struct link_socket *sock, struct signal_info *sig_info)
if (sock->http_proxy)
{
+ int proxy_sd=sock->sd
+ if(sock->http_proxy && sock->http_proxy->options && sock->http_proxy->options->http_proxy_over_ssl){
+ // FIXME wrap with SSL
+ // we have connection open to proxy. now wrap it with TLS
+ // proxy_sd= // FIXME open TLS connection to socket sock->sd. The obtained fd gives an unencrypted stream. Pass it as it were a http proxy socket.
+ }
+
proxy_retry = establish_http_proxy_passthru(sock->http_proxy,
- sock->sd,
+ proxy_sd,
sock->proxy_dest_host,
sock->proxy_dest_port,
sock->server_poll_timeout,
It just replaces fd passed to establish_http_proxy_passthru
in socket.c. With a regular http proxy -- just pass it as is. When http proxy is behind SSL -- it opens SSL connection to proxy destination, then use obtained fd of unencrypted contents is passes through.
Basically a single boolean option http_proxy_over_ssl
is sufficient for this feature. I would add a few more options affecting the TLS connection to http proxy --- just for convenience (and as a replacement to http basic auth)
# Enable http proxy over SSL
http_proxy_over_ssl = true
# SSL host name to verify, do not verify host name if empty. The same name is used as SNI for server request
http_proxy_over_ssl_server_SNI = proxy.xxxxxxxxxx.com
# Client certificate for proxy auth. Optionally use it instead of basic proxy auth
http_proxy_over_ssl_client_auth_cert = /etc/client.pem
# http_proxy server SSL certificate to verify locally
http_proxy_over_ssl_server_cert = /etc/proxyserver.pem
# Set Host: name for proxy. In virtual host environment often set the same as http_proxy_over_ssl_server_SNI
# The same host is used for sni and for http Host: to work with multiple virtual http servers on port 443
http_proxy_over_ssl_CONNECT_Host = proxy.xxxxxxxxxx.com
Actually only a single option http_proxy_over_ssl = true
is important, the other controls are to auth the proxy connection, this is a glorified "basic auth" for proxy sever. The options http_proxy_over_ssl_CONNECT_Host
sets Host: field for http proxy when doing CONNECT, see #635
http_proxy_over_ssl_CONNECT_Host
this is not specific to httpS. However, in #635 it was found out that Host:
should contain the target hostname, no?
It may be very beneficial to violate existing "traditions" for CONNECT and Host: having identical information. For example -- if a http proxy over TLS is running in a multi-host environment on a single IP port 443.
Then OpenVPN TLS link to is IP:443 may need to put "non-traditional" Host: from the parameter http_proxy_over_ssl_CONNECT_Host to help web server to identify specific virtual host (the proxy one) to use. If the parameter http_proxy_over_ssl_CONNECT_Host is absent -- the Host: is "traditionally" matching to CONNECT. If a user wants specific Host: to select a virtual server on a web server -- this option may be very handy. It is not needed if a TLS http proxy has its own IP or port, but useful in virtual host environment. By default it is not set and thus does not affect anything. If set --- it would allow to run multiple TLS http proxy on the same IP port 443. It has its own use cases.
In a multi-host virtual server environment this parameter need to be the same as http_proxy_over_ssl_server_SNI for apache httpd to identify the proper virtual host with a proxy server to use.
The parameters http_proxy_over_ssl_server_SNI
(to send SNI and the same name to verify SSL certificate) and http_proxy_over_ssl_CONNECT_Host
(the parameter to send Host: in HTTP header) must be identical in virtual host server setup with SSL (many web sites and proxies on a single IP port 443), otherwise the following error is possible:
[Error] Hostname example.com provided via SNI and hostname www.example.com provided via HTTP are different
There is no such issues for a proxy server running on its own IP adderess
Currently openvpn --http-proxy option only allows a HTTP proxy, i.e. it directly issues the CONNECT command to http proxy. There is no option to connect to a HTTP proxy not directly, but via TLS/SSL, a so called https-proxy option, a regular HTTP proxy behind TLS/SSL, it is rather easy to setup such with apache or nginx. This suggested --http-proxy-over-TLS option has three very important benefits:
This is a request for improvement. Tested on openvpn-2.6.12 and earlier, none support a HTTP proxy over TLS/SSL. This improvement feature is easy to implement and it does not affect other OpenVPN functionality.