Main       Comic       Forums       Anime       Tools       Fun       
Categories
Recent Articles
Recent Posts
Buy DSG Items
Like the new DeadGod design?
Do you hate it?
Click here to let us know!
Recent Posts       Popular Articles       Popular Threads       [ View All Recent Posts ]
1. New Server:  Rules Discussion by DranoK -- 10H 21M ago.
2. Unknown by noggin -- 10H 32M ago.
3. New Server:  Rules Discussion by <LCC> -- 15H 23M ago.
4. DeadGod Survival Game - Cycle 11 by DSG -- 18H 48M ago.
 
[ Login | Register ]
 
Viewing 'How to override DNS on a per-user basis'
Jan
24
Wednesday, January 24th, 2007 (16479 Views)
Advanced
DranoK
Prerequisites:
o Familiarity with DNS, /etc/hosts and /etc/nsswitch.conf
   http://en.wikipedia.org/wiki/Name_Service_Switch
o Basic understanding of iptables
   http://www.netfilter.org/
   http://iptables-tutorial.frozentux.net/

Lazy QA/Staging

In the staging of production systems it is often desirable to override DNS to point at a local staging server instead of the production one. For example, you may have a large number of scripts that call "www.xyz.com"; changing all of these to "wwwtest.xyz.com" would be a pain in the ass.

Sure, there are good ways around this if you have a decent QA environment. You can use a special QA network with its own DNS server. To some extent you can use rule-based proxies.

A large number of solutions involve editing your local hosts file (/etc/hosts under UNIX, \system32\drivers\etc\hosts on Windows) to override DNS.

This works due to a file named /etc/nsswitch.conf. This very useful file contains the rules that programs use to resolve host names and other directory services (sendmail aliases, autofs, etc).

Basically, when a program wants to connect to "www.xyz.com" it makes a call to gethostbyname(), which consults /etc/nsswitch.conf.

A common /etc/nsswitch.conf might contain the following line:

Listing 1:
hosts:          files dns

This tells gethostbyname() to consult local files first (ie., /etc/hosts). If it can't find what it's looking for there it will consult DNS.

NOTE: Not all programs respect /etc/resolv.conf. For example, the "nslookup", "dig" and "host" commands will return DNS information regardless of what is in /etc/hosts.

Usually this works fine. You'll resolve www.xyz.com normally with the entry commented out in /etc/hosts and resolve it to the staging IP with the entry present.

The problem comes in when you want certain users to use DNS, and certain users to use the overrides in /etc/hosts.

Per-user DNS overrides

The important thing to remember about configuration files in /etc (/etc/hosts, /etc/nsswitch.conf, etc.) is that they are considered system-level confs. That is, they apply to all users. gethostbyname() doesn't care which user called it--it just blindly returns results based on the system-level rules in /etc.

The trick to making this work is understanding how /etc/nsswitch.conf works. Let's take a closer look at our above example, which specifies the search order as "files dns". This means it consults /etc/hosts first, and only if it fails or doesn't find an entry will it try DNS.

The key is, "if it fails."

It's highly unlikely /etc/hosts will ever fail--it's just a flat file. It is possible for DNS to fail, however. In fact, since this requires network access, we can make it fail.

Our goal is for some users to resolve www.xyz.com publicly, while forcing other users to hit staging. We can do this by providing public information via DNS and the staging IPs via /etc/hosts.

Change /etc/nsswitch.conf to consult DNS first, only falling back on /etc/hosts if that fails:

Listing 2:
hosts:          dns files

Now any entry we put into /etc/hosts for "www.xyz.com" will be ignored unless the DNS server fails to respond. The next step is to force DNS to fail for certain users.

Let's say user jdoe has a uid of 503. We want Joe to hit staging. using the "-m owner" feature of iptables we can block him from hitting udp/tcp port 53 (DNS).

Listing 3:
/sbin/iptables -A OUTPUT -p tcp --dport 53 -m owner --uid-owner 503 -j REJECT
/sbin/iptables -A OUTPUT -p udp --dport 53 -m owner --uid-owner 503 -j REJECT

User jdoe will now be unable to make DNS requests since udp/tcp port 53 outgoing is blocked. gethostbyname() will fail and thus fall back to /etc/hosts due to the options in /etc/nsswitch.conf. We can similarly add iptables rules for any user we want to hit staging.

You may need to restart your nscd service depending on how it's configured. nscd is a caching daemon that runs by default on some systems (Solaris, SuSE, etc.). More information can be found below:

http://linuxmanpages.com/man8/nscd.8.php

There is one problem with this method--all hosts must be in /etc/hosts. If jdoe gets bored of QAing and wants to visit slashdot.org, he can't do so unless this is in /etc/hosts or he removes the iptables rule.

Packet filtering with iptables is very powerful and robust. To learn more about it visit the two links provided above in the prerequisites section, as it is a must-have utility for any Linux professional.
Permalink - Forum Thread - Reply to this - Subscribe!Social Bookmark Button



0 Comments -- Post a Comment



Post a Comment
Name (Required)
Register an account to gain access to all the great features of DeadGod.Net! It's fast, and free. Register now!

You may use BBCode in your post.


Older Articles
 
 
DeadGod.Net - Cute Evil Atheists
Encouraging critical thought and general enjoyment since 2001.
Want to join our community? Have suggestions or comments?
Contact Us or Visit our forums.