Hey all,
Hopefully this is a valid place to ask about PTs technical details. So n8fr8, uniqx (Michael Pöhn), and I are working to make an easily reproducible obfs4 client and server setup with ansible scripts
uniqx got the setup working with obfs4 connecting to a port on the server side, like a webserver. Weŕe trying to figure out a way to make this obfs4 setup to behave like an SSH port forward, but weŕe banging our heads against the concept.
For example, could the obfs4 server side provide a generic SOCKS proxy? Hereś the use case: wikimedia foundation wants to run their own PTs built into their own client but it needs to support multiple domains, e.g. en.wikipedia.org and commons.wikimedia.org. So we would like to have a generic SOCKS proxy for the client. Then server side, the SOCKS proxy only allows connections to a whitelist of wikimedia servers.
Here are uniqxś PT projects: https://gitlab.com/uniqx/pt-obfs4proxy-minimal-demo https://gitlab.com/uniqx/pt-socks5-over-obfs4proxy https://gitlab.com/uniqx/pt-obfs4proxy-tcp-bridge https://gitlab.com/uniqx/pt-tor-obfs4-bridge-test-vm
.hc
On 1/23/19 10:42 AM, Hans-Christoph Steiner wrote:
uniqx got the setup working with obfs4 connecting to a port on the server side, like a webserver. Weŕe trying to figure out a way to make this obfs4 setup to behave like an SSH port forward, but weŕe banging our heads against the concept.
You don't/can't, with mainline obfs4proxy.
For example, could the obfs4 server side provide a generic SOCKS proxy?
There is no functionality for doing such a thing in mainline obfs4proxy.
What currently will work is any one of:
* Stick a proxy server of your choice behind the obfs4proxy server. From the application end it will essentially be connecting to a (for example) SOCKS5 proxy over another SOCKS5 proxy.
* Connect the obfs4proxy server to a load-balancer or reverse-proxy that re-dispatches requests to the correct location based on the SNI block or `Host` header (depending on how you want to treat TLS).
Regards,
On Wed, Jan 23, 2019 at 11:41:42AM +0000, Yawning Angel wrote:
For example, could the obfs4 server side provide a generic SOCKS proxy?
There is no functionality for doing such a thing in mainline obfs4proxy.
What currently will work is any one of:
- Stick a proxy server of your choice behind the obfs4proxy server.
From the application end it will essentially be connecting to a (for example) SOCKS5 proxy over another SOCKS5 proxy.
- Connect the obfs4proxy server to a load-balancer or reverse-proxy
that re-dispatches requests to the correct location based on the SNI block or `Host` header (depending on how you want to treat TLS).
This is the right answer. Fundamentally you need two layers of proxying: one at the PT layer (obfs4proxy PT interface) and one at your application layer (where you implement problem-specific logic like domain whitelists).
On the server, you will point TOR_PT_ORPORT at a SOCKS server or load balancer, rather than directly at the target web server. The obfs4_server.sh script will work fine for that; you could also try https://github.com/twisteroidambassador/ptadapter. The SOCKS server will have to support a destination whitelist--or you could just put it on a host with an appropriate outgoing firewall. Instead of a SOCKS server, you could use load balancer/reverse proxy like Yawning says. Here are a few that have SNI proxying (I've personally only used sslh): https://www.haproxy.com/blog/enhanced-ssl-load-balancing-with-server-name-in... https://github.com/yrutschle/sslh https://github.com/dlundquist/sniproxy
But you're going to encounter an undesirable feature of this setup: there's a 1:1 relationship between application-layer connections and obfuscation-layer tunnels. That is, if the app makes 2 HTTPS connections to 2 different Wikimedia domains, there will be 2 obfs4 tunnels happening. It will work, but it's more conspicuous and will notionally make website fingerprinting easier. What you may want is a multiplexing protocol that collapses multiple streams into one on the client side (to feed into the obfs4 tunnel) and splits them back apart again on the server side. (In the usual Tor setup, it's the Tor protocol that serves this multiplexing function--you only have one long-lived connection to your guard, not a separate connection for every application-layer stream.) Unfortunately I don't know of any out-of-the-box that does this. You might try https://github.com/xtaci/smux; also lately I've been thinking a lot about applying https://github.com/lucas-clemente/quic-go to this problem.
David Fifield:
On Wed, Jan 23, 2019 at 11:41:42AM +0000, Yawning Angel wrote:
For example, could the obfs4 server side provide a generic SOCKS proxy?
There is no functionality for doing such a thing in mainline obfs4proxy.
What currently will work is any one of:
- Stick a proxy server of your choice behind the obfs4proxy server.
From the application end it will essentially be connecting to a (for example) SOCKS5 proxy over another SOCKS5 proxy.
- Connect the obfs4proxy server to a load-balancer or reverse-proxy
that re-dispatches requests to the correct location based on the SNI block or `Host` header (depending on how you want to treat TLS).
This is the right answer. Fundamentally you need two layers of proxying: one at the PT layer (obfs4proxy PT interface) and one at your application layer (where you implement problem-specific logic like domain whitelists).
On the server, you will point TOR_PT_ORPORT at a SOCKS server or load balancer, rather than directly at the target web server. The obfs4_server.sh script will work fine for that; you could also try https://github.com/twisteroidambassador/ptadapter. The SOCKS server will have to support a destination whitelist--or you could just put it on a host with an appropriate outgoing firewall. Instead of a SOCKS server, you could use load balancer/reverse proxy like Yawning says. Here are a few that have SNI proxying (I've personally only used sslh): https://www.haproxy.com/blog/enhanced-ssl-load-balancing-with-server-name-in... https://github.com/yrutschle/sslh https://github.com/dlundquist/sniproxy
But you're going to encounter an undesirable feature of this setup: there's a 1:1 relationship between application-layer connections and obfuscation-layer tunnels. That is, if the app makes 2 HTTPS connections to 2 different Wikimedia domains, there will be 2 obfs4 tunnels happening. It will work, but it's more conspicuous and will notionally make website fingerprinting easier. What you may want is a multiplexing protocol that collapses multiple streams into one on the client side (to feed into the obfs4 tunnel) and splits them back apart again on the server side. (In the usual Tor setup, it's the Tor protocol that serves this multiplexing function--you only have one long-lived connection to your guard, not a separate connection for every application-layer stream.) Unfortunately I don't know of any out-of-the-box that does this. You might try https://github.com/xtaci/smux; also lately I've been thinking a lot about applying https://github.com/lucas-clemente/quic-go to this problem.
Sounds like these are the right direction. Just to clarify: I was thinking of obfs4 like an SSH port forward, not as the provider of a SOCKS proxy. So "server-side" means running daemon alongside obfs4proxy to do the other bits. What you two have outlined sounds like exactly that.
Is this the same with other PT 1.1 daemons? Or would Snowflake be different? Seems like with obfs4, the load balancer using SNI would probably be the easiest for the wikipedia use case.
.hc
On Fri, Jan 25, 2019 at 12:03:19AM +0100, Hans-Christoph Steiner wrote:
Is this the same with other PT 1.1 daemons? Or would Snowflake be different? Seems like with obfs4, the load balancer using SNI would probably be the easiest for the wikipedia use case.
It will be the same with any other transport. They all have a uniform interface through TOR_PT_ORPORT or TOR_PT_EXTENDED_SERVER_PORT.
Moat uses something basically similar with meek-server, feeding the ORport into the local BridgeDB web server.