This is how my system is set up. Names and numbers have been altered to protect my innocence! All of the services are provided by one box (a 486!): DHCP server, DNS server, WINS server (Samba) and the firewall.
Firewall stuff (assumes netfilter with connection tracking):
The DNS server must accept port 53 TCP or UDP connections from the local subnet and it's loopback port.
It must be able to send port 53 TCP or UDP to the internet.
The DHCP server must be able to receive UDP port 67 and 68 on the broadcast address and output to port 68 on the local network.
e.g.
# Connection tracking
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# DNS (on 192.168.1.1)
iptables -t filter -A INPUT -i eth0 -s 192.168.1.0/24 -d 192.168.1.1 -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o ppp0 -d [ISP-DNS1] -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o ppp0 -d [ISP-DNS2] -p tcp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -s 192.168.1.0/24 -d 192.168.1.1 -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o ppp0 -d [ISP-DNS1] -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o ppp0 -d [ISP-DNS2] -p udp --dport 53 -j ACCEPT
# DHCP (serving 192.168.1.x)
iptables -t filter -A INPUT -i eth0 -d 192.168.1.255 -p udp --sport 67:68 --dport 67:68 -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -d 192.168.1.255 -p udp --sport 67 --dport 68 -m start --state NEW -j ACCEPT
The rndc control path must also be opened up to allow DHCP to update BIND.
----------------------------------------
//
// named.conf -- bind/DNS configuration file
//
// Created by daveg, January 9, 2002
//
// alias for all "internal" (secure) subnets
acl "internal" { 192.168.1.0/24; };
// Global options
options {
directory "/var/named"; // Working directory
pid-file "/var/run/named.pid";
dump-file "/var/run/named_dump.db";
statistics-file "/var/run/named.stats";
listen-on { // Doesn't listen on internet port!
127.0.0.1; // Loopback for local resolution
192.168.1.1; // localhost port for internal network (eth0?)
}; // Only listen on internal ports
version "N/A"; // Don't give any help
allow-transfer { "localhost"; }; // No external zone transfers
allow-recursion { // Only query for local clients
"internal";
"localhost";
};
allow-query { // Only serve local clients
"internal";
"localhost";
};
};
// See BIND documentation (dnssec-keygen)
// Same key string used in /etc/dhcpd.conf and /etc/rndc.key
key "rndckey" {
algorithm hmac-md5;
secret "like I'm gonna publish that!";
};
// For rndc external DNS control
controls {
inet 127.0.0.1 port 953 allow { localhost; } keys { "rndckey"; };
};
// Reverse mapping for loopback
zone "0.0.127.in-addr.arpa" in {
type master;
file "127.0.0.dns";
};
// Forward master for local net
zone "mydomain.com" in {
type master;
file "mydomaind.com.dns";
allow-update { key "rndckey"; }; // For dynamic DHCP updates
};
// Reverse master for local net
zone "1.168.192.in-addr.arpa" in {
type master;
file "192.168.1.dns";
allow-update { key "rndckey"; }; // For dynamic DHCP updates
};
// Root zone - forward everything, no hint file
zone "." in {
type forward;
forward only;
forwarders {
212.74.114.193; // DNS1 from ISP
212.74.112.66; // DNS2 from ISP
};
};
----------------------------------------
The root zone is set to forward all queries to the ISP's servers and cache the results. The "standard" setup uses a root "hints" file that will cause BIND to start querying all over the internet. Why chew up your own bandwidth?
The "standard" setup also assumes that all the required "glue" records are in place to correctly delegate "mydomain.com" from ".com".
Also check /etc/resolv.conf and /etc/nsswitch.conf on the name server machine.
And for dynamic DHCP
----------------------------------------
#
# dhcpd.conf -- DHCP 3.0 server configuration file
#
# Created by daveg, January 24, 2003
#
# Global parameters
authoritative;
server-identifier 192.168.1.1;
default-lease-time 86400; # 1 day
max-lease-time 259200; # 3 days
# Global declarations
# Internal (secure) subnet
subnet 192.168.1.0 netmask 255.255.255.0 {
# Subnet declarations
range 192.168.1.32 192.168.93.64; # Dynamic addresse allocation range
deny bootp;
deny client-updates; # Keep it simple
default-lease-time 259200; # 3 day
max-lease-time 604800; # 7 days
# Subnet dhcp options
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.1; # Firewall box
option domain-name "mydomain.com";
option domain-name-servers 192.168.93.1; # Name server box
# Subnet WINS options
option netbios-name-servers 192.168.93.1, 192.168.93.1; # Samba/NT WINS server
option netbios-node-type 2; # Hybrid
}
# DDNS glue
ddns-update-style interim;
# For debugging, logging, etc.
# update-optimization off;
key rndckey {
algorithm hmac-md5;
secret "like I'm gonna publish that!";
};
zone mydomain.com. {
primary 127.0.0.1; # Just happens to be on the same box
key rndckey;
}
zone 1.168.192.in-addr.arpa. {
primary 127.0.0.1; # Just happens to be on the same box
key rndckey;
}
----------------------------------------
One day I'll get round to putting this all on a web page or two!
The DNS-HOWTO was a good starting point but doesn't cover the dynamic updates.
The DHCP mini-HOWTO was also useful. See
http://www.tlpd.org
Hope it helps!