darkk / redsocks

transparent TCP-to-proxy redirector
http://darkk.net.ru/redsocks
3.29k stars 862 forks source link

Example configuration on how to use redsocks as DNS resolver (and logging DNS queries) #66

Closed phuongnd08 closed 9 years ago

phuongnd08 commented 9 years ago

How to config redsocks (and iptables?) so that the machine can act as a DNS resolver (that all DNS queries are handled through redsocks - (before redsocks delegates to some other local dns service)). Would be nice to have all DNS queries logged too

darkk commented 9 years ago

redsocks can't act as DNS resolver. In can only work as fake UDP resolver/rejector that sends truncated reply message to force DNS client to use TCP while sending query to DNS server (and pass through usual TCP redirection chain). Not every DNS client properly supports it.

You may expect redsocks to implement fake resolver that matches every DNS query to some fake IP and codes this IP back to DNS name while redirecting TCP traffic to proxy. E.g.

This feature was never implemented.

So, what setup are you trying to achieve? Are you setting up redsocks at router box that should provide DNS services and TCP connectivity to other clients? Are you setting up local box to go to proxy?

phuongnd08 commented 9 years ago

Right, I'm setting up redsocks like a router box. I was under the impression that redsocks can act as a dns resolver too. Now I'm using bind9 to provide dns service to client.

darkk commented 9 years ago

Nope, redsocks can only be used to enforce DNS-over-TCP in bind9 code to avoid DNS Leak.

I could not find find any way to tell bind to avoid UDP, so I implemented trivial rejector to redirect bind UDP/DNS queries to. I don't know if current bind9 code already has alike option.

phuongnd08 commented 9 years ago

Thank you for getting back. I think all is good now.

cbayle commented 9 years ago

Le 26/08/2015 11:47, Leonid Evdokimov a écrit :

redsocks can't act as DNS resolver. In can only work as fake UDP resolver/rejector that sends /truncated reply/ message to force DNS client to use TCP while sending query to DNS server (and pass through usual TCP redirection chain). Not every DNS client properly supports it.

You may expect redsocks to implement fake resolver that matches every DNS query to some fake IP and codes this IP back to DNS name while redirecting TCP traffic to proxy. E.g.

  • DNS A query google.com → 10.120.156.251
  • connect to 10.120.156.251 → connect to google.com via proxy (both CONNECT and SOCKS5 protocols support this)

This feature was never implemented.

Would really like to have it, any suggestion to implement it ?

So, what setup are you trying to achieve? Are you setting up redsocks at router box that should provide DNS services and TCP connectivity to other clients? Are you setting up local box to go to proxy?

— Reply to this email directly or view it on GitHub https://github.com/darkk/redsocks/issues/66#issuecomment-134926786.

darkk commented 9 years ago

I have no reason to implement the feature at the moment.

Here are some common traffic destinations for transparent redirection with Redsocks.

Tor – you can do it for TCP and DNS without Redsocks.

ssh -D – if your DNS is public, you're OK unless you use ssh due to privacy reasons. If your DNS is not public, you can get real DNS reply using bind9 that has DNS-over-TCP support.

Ordinary Socks5 server should support UDP, so DNS-over-Socks5 case is OK too.

Downside of fake DNS resolver is quite obvious – it makes proxy less transparent and debugging network issues more hard.

Please, can you explain, why do you think this feature worth implementing?

cbayle commented 9 years ago

Hi,

Le 06/09/2015 18:27, Leonid Evdokimov a écrit :

I have no reason to implement the feature at the moment.

Here are some common traffic destinations for transparent redirection with Redsocks.

Tor – you can do it for TCP and DNS without Redsocks.

ssh -D – if your DNS is public, you're OK unless you use ssh due to privacy reasons. If your DNS is not public, you can get real DNS reply using bind9 that has DNS-over-TCP support.

Ordinary Socks5 server should support UDP, so DNS-over-Socks5 case is OK too.

Downside of fake DNS resolver is quite obvious – it makes proxy less transparent and debugging network issues more hard.

Please, can you explain, why do you think this feature worth implementing? In some private network there is no dns access, all access are done through proxy Even if you have got a DNS, some proxy refuse http query on IP adresses, especially for https where certificate are associated with names, not ip adresses.

http/https trafic is exclusively available through http proxy and socks proxy is very limited to few protocols and destinations.

I made a small patch locally that read if there is a /var/lib/redsocks/ file containing a name and replace ip with name, and I was wondering what would be for you the way to implement this ?

Cheers

Christian

— Reply to this email directly or view it on GitHub https://github.com/darkk/redsocks/issues/66#issuecomment-138097779.

darkk commented 9 years ago

In some private network there is no dns access

Yes, that is possible, but this network is quite limited. E.g. XMPP may fail without ability to send SRV query.

Do you have real example of such a network?

Even if you have got a DNS, some proxy refuse http query on IP adresses,

That's true. That is why Redsocks implements simple http-relay mode. If you need more complex rules – Squid is good way to go.

especially for https where certificate are associated with names, not ip adresses.

Does proxy try to validate https certificate after connect?

what would be for you the way to implement this ?

I would implement fake DNS server that responds to any A and AAAA query with fake IP address from unused region. IPv6 region can have sane default, IPv4 region should be configured by user. IP address should be cached for some TTL. And connection to this address should be redirected to proxy using original DNS name.

There are several open questions:

TTL can be replaced or combined with LRU cache to avoid DoS.

cbayle commented 9 years ago

On 06/09/2015 23:19, Leonid Evdokimov wrote:

In some private network there is no dns access

Yes, that is possible, but this network is quite limited. E.g. XMPP may fail without ability to send SRV query.

sure, almost everything is forbidden, and socks can probably not work with a proper DNS, or a dns that resolve socks allowed hosts Do you have real example of such a network?

yes, and I think it's very common that the only way to go outside the network is to set a proxy, which is quite easy in browsers, using often more or less complex proxy scripts (e.g. https://www.websense.com/content/support/library/web/v76/pac_file_best_practices/PAC_file_sample.aspx)

the problem with this is that except browsers, many software don't propose any way to setup proxy, or do this badly

Eclipse for example is unable to be parametred with both http and socks proxy correctly, as it consider that when you setup socks, http/https trafic is supposed to go thru socks, but if your net admin decided that your socks proxy don't allow http/https you have to change config often.

With a transparent proxy you can easily work around this kind of problem.

My experience is that many software, even if they propose proxy setup, often forget that some command like gpg --recv-key, also need to take in account that there is a proxy on the way ...

Even if you have got a DNS, some proxy refuse http query on IP adresses,

That's true. That is why Redsocks implements simple http-relay mode. If you need more complex rules – Squid is good way to go.

especially for https where certificate are associated with names, not ip adresses.

Does proxy try to validate https certificate after connect?

no this proxy just refuses url with ip adresses

what would be for you the way to implement this ?

I would implement fake DNS server that responds to any A and AAAA query with fake IP address from unused region. IPv6 region can have sane default, IPv4 region should be configured by user. IP address should be cached for some TTL. And connection to this address should be redirected to proxy using original DNS name.

There are several open questions:

  • what TTL should be used? It depends on default behavior of application as getaddrinfo() interface does not provide TTL information to the application, so applications implement different policies that should be researched.

TTL can be replaced or combined with LRU cache to avoid DoS.

  • how should be queries besides A and AAAA handled? Is SERVFAIL good enough for XMPP clients sending SRV queries? Should SMTP connections be dropped by default due to lack of MX queries?
  • is it egough to reply to AAAA queries? Are there any useful applications behind Redsocks redirector that can't speak IPv6?
  • how will fake DNS interact with search resolv.conf option? Will it connect to facebook.com.enterprise.com instead of facebook.com? I see, there is often an internal dns, so in some case forwarding has to be done, but even if the DNS is forwarding to internet, you still have to use fake as there can be dns aliasing that make that several name can return the same ip, and that you have to reatribute the good name to the proxy, isn't it ?

I see this is quite a complex task with many questions :-( As a first step I was thinking of reusing a dns server like bind or a dns proxy and make it write /var/lib/redsocks/ files at every query only using fake ip when encountering aliases, only considering the case where I have a proper DNS

Cheers

Christian

cbayle commented 9 years ago

Hello,

find attached the experimental patch I use on redsocks 0.4 debian package it looks for a /var/lib/redsocks/%s file or eventually tries to make a reverse dns lookup

Cheers

Christian

Le 08/09/2015 00:19, Christian BAYLE a écrit :

On 06/09/2015 23:19, Leonid Evdokimov wrote:

In some private network there is no dns access Yes, that is possible, but this network is quite limited. E.g. XMPP may fail without ability to send SRV query.

sure, almost everything is forbidden, and socks can probably not work with a proper DNS, or a dns that resolve socks allowed hosts Do you have real example of such a network?

yes, and I think it's very common that the only way to go outside the network is to set a proxy, which is quite easy in browsers, using often more or less complex proxy scripts (e.g. https://www.websense.com/content/support/library/web/v76/pac_file_best_practices/PAC_file_sample.aspx)

the problem with this is that except browsers, many software don't propose any way to setup proxy, or do this badly

Eclipse for example is unable to be parametred with both http and socks proxy correctly, as it consider that when you setup socks, http/https trafic is supposed to go thru socks, but if your net admin decided that your socks proxy don't allow http/https you have to change config often.

With a transparent proxy you can easily work around this kind of problem.

My experience is that many software, even if they propose proxy setup, often forget that some command like gpg --recv-key, also need to take in account that there is a proxy on the way ...

Even if you have got a DNS, some proxy refuse http query on IP adresses, That's true. That is why Redsocks implements simple http-relay mode. If you need more complex rules – Squid is good way to go.

especially for https where certificate are associated with names, not ip adresses.

Does proxy try to validate https certificate after connect?

no this proxy just refuses url with ip adresses

what would be for you the way to implement this ? I would implement fake DNS server that responds to any A and AAAA query with fake IP address from unused region. IPv6 region can have sane default, IPv4 region should be configured by user. IP address should be cached for some TTL. And connection to this address should be redirected to proxy using original DNS name.

There are several open questions:

  • what TTL should be used? It depends on default behavior of application as getaddrinfo() interface does not provide TTL information to the application, so applications implement different policies that should be researched.

TTL can be replaced or combined with LRU cache to avoid DoS.

  • how should be queries besides A and AAAA handled? Is SERVFAIL good enough for XMPP clients sending SRV queries? Should SMTP connections be dropped by default due to lack of MX queries?
  • is it egough to reply to AAAA queries? Are there any useful applications behind Redsocks redirector that can't speak IPv6?
  • how will fake DNS interact with search resolv.conf option? Will it connect to facebook.com.enterprise.com instead of facebook.com? I see, there is often an internal dns, so in some case forwarding has to be done, but even if the DNS is forwarding to internet, you still have to use fake as there can be dns aliasing that make that several name can return the same ip, and that you have to reatribute the good name to the proxy, isn't it ?

I see this is quite a complex task with many questions :-( As a first step I was thinking of reusing a dns server like bind or a dns proxy and make it write /var/lib/redsocks/ files at every query only using fake ip when encountering aliases, only considering the case where I have a proper DNS

Cheers

Christian

RoganDawes commented 7 years ago

I realise this is a very old issue, and likely am necromancing this thread. However, I wanted to point out one more use case where this makes sense, in the hope of getting a usable solution.

In the course of assessing network applications, one task is often to intercept TCP traffic, analyse/modify it, and send it on. It's easy enough for unencrypted traffic, and redsocks makes it even easier, thank you!

However, intercepting SSL connections is a different beast, as this usually entails acting as either an HTTP CONNECT intercept, or possibly a SOCKS intercept, determining the hostname from the CONNECT request, then generating a matching certificate, and signing it with a private CA. If the private CA cert is installed on the client, then validation is successful, and interception can be achieved.

I recognise that SNI (Server Name Indicator) does make this somewhat easier in the cases where redsocks is purely passing on the IP address of the desired end point, however, not all clients implement SNI (and many intercepting proxies don't either!)

So, being able to configure a DNS implementation with a range of IP addresses (e.g. RFC1918 addresses unused on the client network, or even a random netblock that the clients are unlikely to connect to during legitimate traffic), that redsocks will then use to transform intercepted TCP connections back into "CONNECT hostname:port" requests would be really valuable.

One approach that springs to mind is a custom DNS server implemented as part of the redsocks server, that accepts DNS requests for A and AAAA records, and resolves them from an upstream server, storing the results in an in-memory LRU list of configurable size, that is queried on receiving a TCP connection on port 12345, and translated back into a suitable "CONNECT hostname:port" request. Non-A or AAAA requests can simply be passed through, perhaps, in a first implementation.

Problems with different hostnames resolving to the same IP address can then be addressed at the upstream DNS server (e.g. a dnsmasq instance) by hardcoding name/address mappings where necessary. (Logging a warning might help folks to identify this edge case, and take appropriate action). (Ninja edit: Problems with resolv.conf search orders can also be addressed at the upstream DNS instance, and need not be considered within redsocks itself)