LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Linux Answers > Networking
User Name
Password

Notices


By Kristijan at 2007-02-15 22:08
Assumptions
  • NetBSD is already installed and configured with 2 network cards.
  • Network is already configured and functional.




Network

Here is a link of how my current network looks like - Kristijan's Network
  • homer – This is my desktop which I use everyday for BitTorrent, Trillian etc…
  • lisa – This is my sister’s desktop which she uses for Limewire, MSN etc…
  • bart – My file server.
  • xbox – Xbox :P
  • krusty – My 500Mhz 128MB NetBSD gateway




DHCP

NetBSD comes with ISC implementation of DHCPD already installed; all we need to do is configure it for our network.

Code:
# Server Configuration

authoritative;
ddns-update-style none;
deny client-updates;

# Client Configuration

default-lease-time 604800;
max-lease-time 604800;

subnet 192.168.0.0 netmask 255.255.255.0 {
        range 192.168.0.50 192.168.0.100;
        option subnet-mask 255.255.255.0;
        option domain-name-servers 192.168.0.10;
        option domain-name "in.kristijan.org";
        option routers 192.168.0.10;
}

# Static Hosts

host bart {
        hardware ethernet 00:0f:ea:56:fc:bd;
        fixed-address 192.168.0.1;
}
dhcpd.conf controls the functionality of DHCPD. Let’s go further into the file and find out exactly what each section does.

Server Configuration
  • authoritative: Indicate that the DHCP server should send DHCP-NAK messages to miss configured clients.
  • ddns-update-style: Sets the update style for dynamic DNS to none.
  • deny client-updates: Ignore client updates to the DNS.

Client Configuration
  • default-lease-time: Sets the default lease time (seconds).
  • max-lease-time: Sets the max lease time (seconds).
  • subnet 192.168.0.0 netmask 255.255.255.0: Declares the subnet to use.
  • range 192.168.0.50 192.168.0.100: Declares the range of address to assign to DHCP requests from clients.
  • option subnet-mask: Subnet mask given to clients.
  • option domain-name-servers: DNS address to assign clients.
  • option domain-name: Domain name to assign to client. (This will be configured later on in the DNS section).

Static Hosts
  • host bart: Name of the host.
  • hardware Ethernet: MAC address of the static client.
  • fixed-address: Address to assign the fixed client.

Once this is all configured, you need to create a lease file. You can do this by issuing the following command.

Code:
touch /var/db/dhcpd.leases
/etc/rc.conf

To make sure the DHCP daemon starts on boot, add the following to rc.conf.

Code:
dhcpd=YES
dhcpd_flags="-q fxp0"
**Note: -q fxp0 tells the DHCP daemon which interface to listen for DHCP queries on.




DNS

NetBSD comes with BIND 9.3.0 already installed. Most will argue that using BIND in such a small environment is overkill, and I would agree. However, I’m not only building this gateway for the functional aspect, but also to learn how services like BIND work (I plan on replacing BIND for dnsmasq at some stage).

If you don’t have BIND installed, you can install it from the pkgsrc branch. You can find it in the net/bind9 directory.

named.conf

Code:
# Server Settings

options {
        version "Bind";
        directory "/etc/namedb";
        allow-query { lan; };
        listen-on { lan; };
};

acl lan {
        127.0.0.1;
        192.168.0/24;
};

# Zone Information

zone "." {
        type hint;
        file "root.cache";
};

zone "localhost" {
        type master;
        file "localhost";
};

zone "127.IN-ADDR.ARPA" {
        type master;
        file "127";
};

zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int" {
        type master;
        file "loopback.v6";
};

zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" {
        type master;
        file "loopback.v6";
};

zone "0.168.192.in-addr.arpa" {
        type master;
        file "0.168.192";
};

zone "in.kristijan.org" {
        type master;
        file "in.kristijan.org";
};
named.conf controls the functionality of BIND. Let’s go further into the file and find out exactly what each section does.

options
  • version: Specifies the string that will be returned to a version.bind queried.
  • directory: Absolute path for the server (/etc/namedb in our case).
  • allow-query: IP address(es) which are allowed to issue queries to the server.
  • listen-on: Defines the port and IP address(es) on which BIND will listen for incoming queries.
  • acl lan: Creates an Access Control List of our machine addresses.

zone
  • type: hint - root-servers is defined using a hint zone. master - Server has a master copy of the zone data and provides authoritative answers for the zone.
  • file: Defines the file used by the zone.

/etc/namedb folder

The /etc/namedb folder contains all our zone files.

Code:
krusty# cd /etc/namedb
krusty# ls -l
total 14
-rw-r--r--  1 root  wheel   587 Oct 22 14:47 0.168.192
-rw-r--r--  1 root  wheel   212 Oct 22 14:47 127
-rw-r--r--  1 root  wheel   604 Oct 22 14:48 in.kristijan.org
-rw-r--r--  1 root  wheel   229 Oct 22 14:48 localhost
-rw-r--r--  1 root  wheel   207 Oct 22 14:48 loopback.v6
-rw-r--r--  1 root  wheel  2583 Oct 21 17:58 root.cache
0.168.192 file

Code:
$TTL    3600
@       IN      SOA     krusty.in.kristijan.org. kristijanmilos.gmail.com.  (
                                1               ; Serial
                                3600            ; Refresh
                                300             ; Retry
                                3600000         ; Expire
                                3600 )          ; Minimum
        IN      NS      krusty.in.kristijan.org.
10      IN      PTR     krusty.in.kristijan.org.
1       IN      PTR     bart.in.kristijan.org.
2       IN      PTR     homer.in.kristijan.org.
3       IN      PTR     lisa.in.kristijan.org.
4       IN      PTR     xbox.in.kristijan.org.
Key things to note are the following:
Line 2: krusty.in.kristijan.org. is the name of the server. kristijanmilos.gmail.com. is the contact for the DNS server.
Line 8: The nameserver.
Line 9-13: Mapping of IP addresses to real names (e.g. 3 IN PTR lisa.in.kristijan.org maps 192.168.0.3 to the name lisa.in.kristijan.org)

127 file

Code:
$TTL    3600
@       IN      SOA     krusty.in.kristijan.org. kristijanmilos.gmail.com.  (
                                1               ; Serial
                                3600            ; Refresh
                                300             ; Retry
                                3600000         ; Expire
                                3600 )          ; Minimum
        IN      NS      localhost.
1.0.0   IN      PTR     localhost.
Same as the 0.168.192 file, 1.0.0 is mapped to localhost which points to 127.0.0.1.

in.kristijan.org file

Code:
$TTL    3600
@       IN      SOA     krusty.in.kristijan.org. kristijanmilos.gmail.com.  (
                                1               ; Serial
                                3600            ; Refresh
                                300             ; Retry
                                3600000         ; Expire
                                3600 )          ; Minimum
                IN      NS      krusty.in.kristijan.org.
krusty          IN      A       192.168.0.10
bart            IN      A       192.168.0.1
homer           IN      A       192.168.0.2
lisa            IN      A       192.168.0.3
xbox            IN      A       192.168.0.4
This file points the names to the relevant IP addresses.

localhost file

Code:
$TTL    3600
@       IN      SOA     krusty.in.kristijan.org. kristijanmilos.gmail.com.  (
                                1               ; Serial
                                3600            ; Refresh
                                300             ; Retry
                                3600000         ; Expire
                                3600 )          ; Minimum
                IN      NS      localhost.
localhost.      IN      A       127.0.0.1
                IN      AAAA    ::1
loopback.v6 file

Code:
$TTL    3600
@       IN      SOA     krusty.in.kristijan.org. kristijanmilos.gmail.com.  (
                                1               ; Serial
                                3600            ; Refresh
                                300             ; Retry
                                3600000         ; Expire
                                3600 )          ; Minimum
        IN      NS      localhost.
        IN      PTR     localhost.
The root.cache file lists the root servers for your server to query when it gets requests outside of its own domain. These root servers don’t change that often, but they do change. You can generate and keep the file updated by running this command.

Code:
dig @a.root-servers.net . ns > /etc/named/root.cache
/etc/resolv.conf

On any machines which you are not assigning addresses via DHCP, use the following in the resolv.conf file.

Code:
search in.kristijan.org
nameserver 127.0.0.1
/etc/rc.conf

To make sure the DNS starts on boot, add the following to rc.conf.

Code:
named=YES
Once BIND is restarted, and you have the boxes on your LAN pointing to your new DNS, you should now be able to use host & dig for name resolution.

Exchange updates between DHCP and DNS

So we have the DHCP server sending out addresses to our clients and the DNS server now handling their requests…but there not exactly playing together now, are they?

What we want the DHCP server to do is update the DNS A and PTR records on the DNS server for any new clients that come into our network.

Let’s gets all our necessary files in order, before we start editing the /etc/named.conf file.

rndc-confgen

We need to create the necessary rndc files so DHCP and DNS can communicate.

Code:
rndc-confgen –a
This command does two things:
  • It creates the /etc/rndc.key file.
  • It automatically adds the following into the /etc/named.conf file

Code:
controls {
       inet 127.0.0.1 allow { localhost; } keys { rndckey; };
};

include "/etc/rndc.key";
Now for some reason unknown to me, the configuration generated by rndc-confgen names the key ”rndckey” in the controls section; but when it’s included, it gets included as rndc-key.

Just change the following line in /etc/named.conf, so it reads like this:

Code:
inet 127.0.0.1 allow { localhost; } keys { rndc-key; };
We now need to tell DNS which records it will accept updates from the DHCP server.

The following line will need to be manually added to the 0.168.192.in-addr.arpa zone and the in.kristijan.org zone - allow-update { key rndc-key; };

The modified sections should look like this:

Code:
zone "0.168.192.in-addr.arpa" {
        type master;
        file "0.168.192";
        allow-update { key rndc-key; };
};

zone "in.kristijan.org" {
        type master;
        file "in.kristijan.org";
        allow-update { key rndc-key; };
};
This takes care of DNS; we now need to tell DHCP to actually make these changes.


In the /etc/dhcpd.conf, change the following:

Code:
ddns-update-style none;
deny client-updates;

to

ddns-update-style interim;
allow client-updates;

key "rndc-key" {
        algorithm hmac-md5;
        secret "uiReDjf230mc2=fm";
};
**Note: The secret in the key definition must match the one in /etc/rndc.key

The following zone information will need to be added to the configuration:

Code:
zone 0.168.192.in-addr.arpa. {
        primary 127.0.0.1;
        key rndc-key;
}

zone in.kristijan.org. {
        primary 127.0.0.1;
        key rndc-key;
}
This defines which zones DHCP will update, the location of the DNS server, and which key to exchange when requesting these changes via DNS.

Restart both BIND and DHCP and you should see something similar in your /var/log/messages log.

Code:
Oct 25 21:03:23 krusty named[17405]: command channel listening on 127.0.0.1#953
This verifies that the command channel between DHCP and DNS was established.

Make a DHCP request via a client and you should see the following:

Code:
Oct 25 21:10:38 krusty dhcpd: DHCPOFFER on 192.168.0.98 to 00:11:24:db:f9:b2 (newclient) via fxp0
Oct 25 21:10:39 krusty named[17405]: client 127.0.0.1#64581: updating zone 'in.kristijan.org/IN': adding an RR at 'newclient.in.kristijan.org' A
Oct 25 21:10:39 krusty named[17405]: client 127.0.0.1#64581: updating zone 'in.kristijan.org/IN': adding an RR at 'newclient.in.kristijan.org' TXT
Oct 25 21:10:39 krusty named[17405]: journal file in.kristijan.org.jnl does not exist, creating it
Oct 25 21:10:39 krusty dhcpd: Added new forward map from newclient.in.kristijan.org to 192.168.0.98
Oct 25 21:10:39 krusty named[17405]: client 127.0.0.1#64580: updating zone '0.168.192.in-addr.arpa/IN': deleting rrset at '98.0.168.192.in-addr.arpa' PTR 
Oct 25 21:10:39 krusty named[17405]: client 127.0.0.1#64580: updating zone '0.168.192.in-addr.arpa/IN':adding an RR at '98.0.168.192.in-addr.arpa' PTR
Oct 25 21:10:39 krusty named[17405]: journal file 0.168.192.jnl does not exist, creating it
Oct 25 21:10:39 krusty dhcpd: added reverse map from 98.0.168.192.in-addr.arpa. to newclient.in.kristijan.org
You should now be able to ping and query the new host via the DNS server.




Firewall (pf)

**Note: I trust all users who use my network (family mostly), I have no wireless, and the only physical way to gain access to my network is to plug into the switch in my room.

Enable pf and IP forwarding

Before we get started on the pf configuration file, we first need to setup our NetBSD box to load the pf kernel module and forward packets.


The following files will be modified:
  • /etc/lkm.conf
  • /etc/sysctl.conf
  • /etc/rc.conf

/etc/lkm.conf – Add the following:

Code:
/usr/lkm/pf.o   -               -               -               -               BEFORENET
he BEFORENET loads the module before networking is started. This can only work if the /usr file system can be loaded at that time.

/etc/sysctl.conf – Add the following:

Code:
net.inet.ip.forwarding=1
This enables IP forwarding.

/etc/rc.conf – Add the following:

Code:
lkm=YES
Enables dynamic loading/unloading of kernel modules.

Editing the above 3 files will make this all available at the next boot. We can however move on without rebooting the system. Load the kernel module and enable IP forwarding with the following two commands:

Code:
modload /usr/lkm/pf.o
sysctl -w net.inet.ip.forwarding=1
/etc/pf.conf

With pf and IP forwarding enabled, we can now move onto writing our rule set.

This is what is currently required for my home network.
  • Let anything originating from the internal network out onto the Internet, and a state is kept so that it’s allowed back in.
  • BitTorrent is allowed inbound and forwarded to my machine (homer).
  • SSH is allowed inbound from the Internet.
  • Everything else inbound is blocked.

A very good guide can be found on the OpenBSD website @ http://www.openbsd.org/faq/pf I suggest reading this before attempting to write any pf rules.

For a clearer understanding of how the rule set works, I have provided an image of how the firewall will interact with the rest of my network at a very basic level -

Let’s begin…

Macros

Code:
ext_if="ppp0"
int_if="fxp0"

homer="192.168.0.2"

nonroutable="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"
A few basic macros will make writing and marinating the rule set much easier.
  • ext_if & int_if – The two network interfaces on my NetBSD box.
  • homer – The IP address of my desktop box.
  • nonroutable – Networks which should not be routed by the firewall.

Options

Code:
set block-policy drop
set loginterface $ext_if
  • block-policy – Silently drops any packets which specify the drop action.
  • loginterface – Sets the external interface to gather statistics.

Scrub

Code:
scrub no-df random-id fragment reassemble
  • no-df – Clears the don't fragment bit from the IP packet header.
  • random-id – Replaces the IP identification field of packets with random values to compensate for operating systems that use predictable values.
  • fragment reassemble – Buffers incoming packet fragments and reassembles them into a complete packet before passing them to the filter engine.

Network Address Translation and Port Forwarding (NAT/RDR)

Code:
nat on $ext_if from !($ext_if) to any -> ($ext_if)
rdr on $ext_if proto tcp from any to any port 61980 -> $homer port 61980
rdr on $ext_if proto udp from any to any port 61980 -> $homer port 61980
  • Rule 1 – Preforms NAT for the entire internal network.
  • Rule 2/3 – Redirects TCP and UDP packets bound for port 61980 (My port for BitTorrent) to homer on port 61980.

Filter Rules

Code:
1| pass out quick keep state
2| pass quick on lo0
3| pass in quick on $ext_if proto tcp from any to any port 61980 flags S/SA keep state
4| pass in quick on $ext_if proto udp from any to any port 61980
5| pass in quick on $ext_if proto tcp from any to any port 22 flags S/SA keep state
6| block drop in quick on $ext_if from $nonroutable to any
7| block drop out quick on $ext_if from any to $nonroutable
8| block in quick on $ext_if
**Note: The line numbers are only added into this tutorial as an aid to explanation. Do not add these into your configuration file.
  • Rule 1 – Any traffic travelling from the internal network out will be passed through and the state kept.
  • Rule 2 – Pass in on the local interface.
  • Rule 3/4 – Allow BitTorrent from the internet into the internal network on port 61980.
  • Rule 5 – Allow SSH from the internet into the internal network on port 22.
  • Rule 6/7 – Block any addresses from the nonroutable macro travelling in and out of the external interface.
  • Rule 8 – Block all other traffic travelling into the internal network from the external interface.

/etc/pf.conf all together

Code:
# PF Ruleset - /etc/pf.conf
# Written by Kristijan
#

##########
# Macros #
##########

ext_if="ppp0"
int_if="fxp0"

homer="192.168.0.2"

nonroutable="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"

###########
# Options #
###########

set block-policy drop
set loginterface $ext_if

#########
# Scrub #
#########

scrub no-df random-id fragment reassemble

###########
# NAT/RDR #
###########

nat on $ext_if from !($ext_if) to any -> ($ext_if)

# Azureus
rdr on $ext_if proto tcp from any to any port 61980 -> $homer port 61980
rdr on $ext_if proto udp from any to any port 61980 -> $homer port 61980

################
# Filter Rules #
################

pass out quick keep state
pass quick on lo0

# Azureus
pass in quick on $ext_if proto tcp from any to any port 61980 flags S/SA keep state
pass in quick on $ext_if proto udp from any to any port 61980

# SSH
pass in quick on $ext_if proto tcp from any to any port 22 flags S/SA keep state

# Non routable
block drop in quick on $ext_if from $nonroutable to any
block drop out quick on $ext_if from any to $nonroutable

# Drop All
block in quick on $ext_if
Using pfctl

pfctl is a handy tool which allows you to control the packet filter.

I’ve listed a few of the more common uses of pfctl:
  • pfctl –e enables pf.
  • pfctl –d disables pf.
  • pfctl –F all flushes all the pf rules.
  • pfctl –f /etc/pf.conf loads the rules from /etc/pf.conf
  • pfctl –s all shows all the translation rules, filter rules, states etc…

To start pf and load the rule set, type the following:

Code:
pfctl –e –f /etc/pf.conf
Another tool which I find useful for monitoring pf is pftop. You can find pftop in the pkgsrc branch under sysutils/pftop


  



All times are GMT -5. The time now is 11:40 AM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration