Building home OpenBSD router – Part 6

December 6, 2008 6:07 pm

Start at Part 1

The Multi Router Traffic Grapher (MRTG)

Reference: Tobi Oetiker’s MRTG – The Multi Router Traffic Grapher

To borrow a phrase from Tobi Oetiker, “You have a router, you want to know what it does all day long? Then MRTG is for you.” The goal here is to track the actions of the OpenBSD router over time. This practice is important for detecting trends in traffic, helpful for finding bottlenecks, and even identify a baseline to recognize abnormal changes in traffic.

So let’s get on with it. For this example, I use OpenBSD’s MRTG package. I’ll also install two packages required for IPv6, OpenBSD MRTG package requires them:

mschenck ~# sudo pkg_add http://mirror.rit.edu/pub/OpenBSD/4.3/packages/i386/mrtg-2.15.2p1.tgz
mschenck ~# sudo pkg_add http://mirror.rit.edu/pub/OpenBSD/4.3/packages/i386/p5-Socket6-0.19.tgz
mschenck ~# sudo pkg_add http://mirror.rit.edu/pub/OpenBSD/4.3/packages/i386/p5-IO-INET6-2.01p0.tgz

I should point out that you need an snmp daemon running for MRTG to pole stats from your router. The enable this first you must add the following to “/etc/rc.conf.local”:

snmpd_flags=""          # for normal use: ""

This will enable snmpd to automatically start on reboot. In the meantime, lets start it ourself

mschenck ~#  sudo  /usr/sbin/snmpd

By default, OpenBSD’s snmp daemon (snmpd(8)) only listens on localhost and the default community string is “public“.  You can change these settings by modifying ” /etc/snmpd.conf” (see snmpd.conf(5)), however for this example we’ll stick with these default settings.

Now lets get an http daemon running to display these graphs.  OpenBSD come with Apache, lets enable and start it up. Add the following line to /etc/rc.conf.local:

httpd_flags=""          # for normal use: "" (or "-DSSL" after reading ssl(8))

Again, lets avoid the reboot and just start the daemon manually:

mschenck ~# sudo /usr/sbin/httpd

Now, lets backup to original document root for apache and create a new one for displaying our mrtg graphs:

mschenck ~# sudo mv /var/www/htdocs /var/www/htdocs-orig
mschenck ~# sudo mkdir -p /var/www/htdocs/cfg

So now that we have MRTG and, the perl modules it requires, and an snmp daemon running and an http daemon up to display our graphs; we’re ready to start configuring.

mschenck ~# sudo cfgmaker --global 'WorkDir: /var/www/htdocs'  \
          --global 'Options[_]: bits,growright' \
          --output /var/www/htdocs/cfg/mrtg.cfg    \
           public@localhost

Now lets schedule the polling of our NICs’ stats for the mrtg graphs. I’m going to put the task to root’s crontab:

mschenck ~# sudo crontab -u root -e

And then add the following cron schedule:

*/5 * * * *  /usr/local/bin/mrtg /var/www/htdocs/cfg/mrtg.cfg --logging /var/log/mrtg.log

Now, just watch the data start collecting.

OpenSolaris HTPC: xorg.conf 1080p

October 19, 2008 8:05 pm


So today I decided to utilize my OpenSolaris/ZFS file server as an HTPC. I recently picked up a Sony Bravia KDL-42V4100 42″ (1080p) LCD TV. I have an NVidia GeForce 6200 LE with 256 MB 16x PCI-E video card which is fully support by OpenSolaris including nVidia control panel; seen here:

Here is my /etc/X11/xorg.conf configuration:

Section "ServerLayout"
    Identifier     "X.org Configured"
    Screen      0  "Screen0" 0 0
    InputDevice    "Mouse0" "CorePointer"
    InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "Files"
    RgbPath      "/usr/X11/lib/X11/rgb"
    ModulePath   "/usr/X11/lib/modules/amd64"
    FontPath     "/usr/X11/lib/X11/fonts/TrueType/"
    FontPath     "/usr/X11/lib/X11/fonts/Type1/"
    FontPath     "/usr/X11/lib/X11/fonts/Type1/sun/"
    FontPath     "/usr/X11/lib/X11/fonts/F3bitmaps/"
    FontPath     "/usr/X11/lib/X11/fonts/misc/"
    FontPath     "/usr/X11/lib/X11/fonts/100dpi/"
    FontPath     "/usr/X11/lib/X11/fonts/75dpi/"
EndSection

Section "Module"
    Load  "IA"
    Load  "dbe"
    Load  "extmod"
    Load  "record"
    Load  "xtrap"
    Load  "GLcore"
    Load  "glx"
    Load  "dri"
    Load  "xtsol"
    Load  "freetype"
EndSection

Section "InputDevice"
    Identifier  "Keyboard0"
    Driver      "kbd"
EndSection

Section "InputDevice"
    Identifier  "Mouse0"
    Driver      "mouse"
    Option        "Protocol" "auto"
    Option        "Device" "/dev/mouse"
    Option        "ZAxisMapping" "4 5 6 7"
EndSection

Section "Monitor"
    Identifier    "Monitor0"
    VendorName    "Monitor Vendor"
    ModelName    "Monitor Model"

    HorizSync 30-80
    VertRefresh 60
    Option "DPMS"

    ModeLine "1920x1080" 148.50 1920 2008 2052 2200 1080 1084 1089 1125 +hsync +vsync

EndSection

Section "Device"
    Identifier  "Card0"
    Driver      "nvidia"
    VendorName  "nVidia Corporation"
    BoardName   "NV44 [GeForce 6200 LE]"
    BusID       "PCI:4:0:0"

        Option      "RenderAccel" "true"
        Option      "AllowGLXWithComposite" "true"

EndSection

Section "Screen"
    Identifier "Screen0"
    Device     "Card0"
    Monitor    "Monitor0"
    DefaultDepth 24

    SubSection "Display"
        Viewport   0 0
        Depth     1
        Modes    "1920x1080"
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     4
        Modes    "1920x1080"
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     8
        Modes    "1920x1080"
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     15
        Modes    "1920x1080"
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     16
        Modes    "1920x1080"
    EndSubSection
    SubSection "Display"
        Viewport   0 0
        Depth     24
        Modes    "1920x1080"
    EndSubSection
EndSection

Section "DRI"
        Mode         0666
EndSection

Then I had to fix gdm to play well with opensolaris
/etc/X11/gdm/gdm.conf

SystemMenu=true
RebootCommand=/usr/sbin/init 6
HaltCommand=/usr/sbin/init 5

I Switched from dtlogin to gdm for graphical login

# /usr/dt/bin/dtconfig -d
# svccfg
svc:> select gdm
svc:/application/graphical-login/gdm> setprop general/enabled = boolean: "true"
svc:/application/graphical-login/gdm> listprop general/enabled
general/enabled  boolean  true
svc:/application/graphical-login/gdm>
# usr/dt/bin/dtconfig -d
# /usr/dt/bin/dtconfig -d & svcadm enable gdm2-login

Add the following to /etc/X11/gdm/custom.conf under the “[daemon]” to enable auto-login for “media” user account
# sudo vi /etc/X11/gdm/custom.conf

AutomaticLoginEnable=true
AutomaticLogin=media

I had to add the following to the end of /etc/pam.conf to allow user “media” to be allowed local graphical auto-login

gdm-autologin auth required pam_unix_cred.so.1
gdm-autologin auth sufficient pam_allow.so.1
gdm-autologin account sufficient pam_allow.so.1
gdm-autologin session sufficient pam_allow.so.1
gdm-autologin password sufficient pam_allow.so.1

Add the following to the end of ~media/.dmrc to let gdm know the default window manager for user “media”

[Desktop]
Session=gnome

Building home OpenBSD router – Part 5

August 15, 2008 4:56 pm

Start at Part 1

Xbox 360 and File Server access

Reference: The Book of PF

In this post I’ll describe how I accomplished two goals, as well as talk about a little trick for debugging what is blocked. The two goals are allowing my XBox 360 connect to Xbox Live through my OpenBSD firewall, and Port-forward to my file server so I can access my files remotely.

Let’s start with the Xbox 360. This is very minimal change from Part 4. In Part 4 we created two macros for allowed client services, the services we allow hosts on our local network to utilize, see here:

client_tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s, imap,
imaps, 8000, 8080, 5190, 5222 }"
client_udp_services = "{ domain, bootps, 67 }"

The Xbox 360 uses TCP port 3074, and UDP ports 88 and 3074 so we just need to add these to those macros, seen here:

client_tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s, imap, imaps, 8000, 8080, 5190, 5222, 3074 }"
client_udp_services = "{ domain, bootps, 67, 88, 3074  }"

Next, I set up NAPT or Network Address Port Translation. I redirect port 5022 on the external interface of my OpenBSD router to port 22 of my file server. This will allow me to SSH, SFTP and RSYNC to/from it when I’m away from home. To do this I need to add a single PF RDR rules, seen here:

# file server
rdr on $ext_if proto { tcp, udp } from any to $ext_if port 5022 -> $file_server port 22

Now I just reload my rules, first checking with pfctl -nf /etc/pf.conf as previously described, then loading with pfctl -f /etc/pf.conf.

One last thing is to describe a method for debugging why connections might be failing. In Part 4 I described blocking all unintended traffic with “block all”. For debugging I’m going to change this to “block log all”.

Now, when ever connectivity issues occur, debugging is simple running the following tcpdump:

# tcpdump -netvvi pflog0

As log as no other lines are configured to log, all output from this command will just describe traffic being blocked.

Our final /etc/pf.conf for this part of the project:

# Interface Globals
ext_if = "rl0"
int_if = "xl0"
wifi_if = "rum0"

# Static machines
file_server = "192.168.0.2"
xbox = "192.168.0.3"

# Protocol Globals
router_daemons = "{ ssh, domain, ntp, bootps, 8080, 5022 }"
client_tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s, imap, imaps, 8000, 8080, 5190, 5222, 3074 }"
client_udp_services = "{ domain, bootps, 67, 88, 3074  }"

# Provide NATing for my local subnets
nat on $ext_if from $wifi_if:network to any -> ($ext_if) static-port
nat on $ext_if from $int_if:network to any -> ($ext_if)

# file server
rdr on $ext_if proto { tcp, udp } from any to $ext_if port 5022 -> $file_server port 22

block log all
set skip on lo

# Allowed Client traffic
pass out on $ext_if proto tcp to any port $client_tcp_services
pass out on $ext_if proto udp to any port $client_udp_services

# Router services
pass proto icmp
pass quick inet proto { tcp, udp } to any port $router_daemons

Continue to Step 6.

Building home OpenBSD router – Part 4

August 10, 2008 12:46 pm

Start at Part 1

… Let there be Traffic


Reference: The Book of PF

First I want to enable my router to forward my traffic. This is going to give me a baseline configuration of no filtering nor NATing. So to enable this I run:

sysctl net.inet.ip.forwarding=1
sysctl net.inet6.ip.forwarding=1

Next I uncomment the following two lines in /etc/sysctl.conf to make this reboot-safe.

net.inet.ip.forwarding=1        # 1=Permit forwarding (routing) of IPv4 packets
net.inet6.ip6.forwarding=1      # 1=Permit forwarding (routing) of IPv6 packets

The Book of PF recommends using tests through out building up your environment, this is a good time to get baseline proof of functionality for these tests.

Next, I’m going to set up some macros in pf.conf to ease configuration changes in the future. First my routers interfaces.

# Interface Globals
ext_if = "rl0"
int_if = "xl0"
wifi_if = "rum0"

Next, I want to make variables for the two boxes that I setup MAC association in my DHCPD configs, My file server and my xbox, because they have special TCP and UDP port needs.

# Static machines
file_server = "192.168.0.2"
xbox = "192.168.0.3"

Lastly, I’m defining which services sections. I want to allow access to a few daemons running on the router itself, as well as allowing the hosts on my local subnets to utilize certain protocols themselves (as clients).

# Protocol Globals
router_daemons = "{ ssh, domain, ntp, bootps, 8080, 5022 }"
client_tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s, imap,
imaps, 8000, 8080, 5190, 5222 }"
client_udp_services = "{ domain, bootps, 67 }"

Now it’s time to start off blocking everything so I add the statement to start off blocking all traffic, and add an exception to filtering on the loopback interface.

block all
set skip on lo

The location of this line is important. All NAT/RDR lines will occur before this line, and all firewalling rules will occur after this line, so keep that in mind for future configurations.

Now I’m going to allow all traffic, from initiated from hosts on my local subnets, be sent out to the internet (their sessions are kept as well).

To do this I tell my router to NAT for my local subnets:

# Provide NATing for my local subnets
nat on $ext_if from $wifi_if:network to any -> ($ext_if) static-port
nat on $ext_if from $int_if:network to any -> ($ext_if)

And then set which protocols are allowed to be passed out to the internet:

# Allowed Client traffic
pass out on $ext_if proto tcp to any port $client_tcp_services
pass out on $ext_if proto udp to any port $client_udp_services

And I can’t forget about my router itself, so I’ll allow access to its daemons from both my local subnets as well as the outside world.

# Router services
pass proto icmp
pass quick inet proto { tcp, udp } to any port $router_daemons

The last step is enable pf:

pfctl -e

And To make it reboot safe by uncommenting the following two lines in /etc/rc.conf

pf=YES                  # Packet filter / NAT
pf_rules=/etc/pf.conf           # Packet filter rules file

At this point, the file server cannot be access by the outside world, and connecting to xbox live isn’t going to happen. These will be covered in the next part of my OpenBSD router project.


Our final /etc/pf.conf for this part of the project:

# Interface Globals
ext_if = "rl0"
int_if = "xl0"
wifi_if = "rum0"

# Static machines
file_server = "192.168.0.2"
xbox = "192.168.0.3"

# Protocol Globals
router_daemons = "{ ssh, domain, ntp, bootps, 8080, 5022 }"
client_tcp_services = "{ ssh, smtp, domain, www, pop3, auth, https, pop3s, imap, imaps, 8000, 8080, 5190, 5222 }"
client_udp_services = "{ domain, bootps, 67 }"

# Provide NATing for my local subnets
nat on $ext_if from $wifi_if:network to any -> ($ext_if) static-port
nat on $ext_if from $int_if:network to any -> ($ext_if)

block all
set skip on lo

# Allowed Client traffic
pass out on $ext_if proto tcp to any port $client_tcp_services
pass out on $ext_if proto udp to any port $client_udp_services

# Router services
pass proto icmp
pass quick inet proto { tcp, udp } to any port $router_daemons

Continue to Step 5.

Building home OpenBSD router – Part 3

August 3, 2008 4:51 pm

Start at Part 1

Configuring DHCPD


Reference: DHCPD(8) DHCPD.CONF(5)

I will start off by telling dhcp that I would like to advertise on both local network interfaces. On OpenBSD this information is kept in /etc/dhcpd.interfaces. The syntax is very simple, you merely state which interfaces you want, whether space-separated on the same line or just give each their own line in the file (like I did). Here’s my /etc/dhcpd.interfaces:

xl0
rum0

Now, lets set configure /etc/dhcpd.conf. As I stated in Part 1 I’ll be supporting two separate subnets, which I’ll create like this:

shared-network LOCAL-WIRELESS {
}
shared-network LOCAL-WIRED {
}

Nothing too crazy here, just two logical areas each labeled for ease of readability.

Since the local wireless section is pretty straight forward, I’ll do this one first. I’m going to start off with a global (subnet-wide) optional configuration, which is my domain name server list. I’d like to out that I’m using OpenDNS in this example, and openly invite you to do the same. So to make this configuration I’ll add the following line to the local wireless subnet area:

option domain-name-servers 208.67.222.222, 208.67.220.220;

Next I want everyone in the subnet to know which address to use for a gateway, so I’ll provide that configuration, seen here:

option routers 192.168.1.1;

Next is to set up the subnet which, as describe previously, is 192.168.0.1/24 and configured as follows:

subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.32 192.168.1.127;
}

Here I’ve provided the range of offered IPs to be 192.168.1.32 up to and including 192.168.1.127, as well as provided gateway information to be given with the DHCP advertisements.

So now this whole subnet configuration will look like this:

shared-network LOCAL-WIRELESS {
option domain-name-servers 208.67.222.222, 208.67.220.220;
option routers 192.168.1.1;
 subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.32 192.168.1.127;
}
}

Now lets set up to local wired subnet. For the most part it’s going to be the same. Which appears like this:

shared-network LOCAL-WIRED {
option domain-name-servers 208.67.222.222, 208.67.220.220;
option routers 192.168.0.1;
 subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.2 192.168.0.127;
}
}

However, on this subnet I have two systems in which I’ll static map IPs to based on their MAC address, my xbox 360 and my opensolaris file server. So in this subnet setting, I’m creating a “group” and filling it in with the two hsots:

group {
host vault {
hardware ethernet 00:1a:92:e2:32:e1;
fixed-address 192.168.0.2;
}
host xbox {
hardware ethernet 00:12:5a:b6:92:1b;
fixed-address 192.168.0.3;
}
}

To start dhcpd, just run sudo dhcpd and you’re be all set. Lastly, to make this reboot safe we just need to edit /etc/rc.conf and set the dhcpd_flags to “” like this:

/etc/rc.conf:dhcpd_flags=""             # for normal use: ""

Full /etc/dhcpd.conf:

shared-network LOCAL-WIRELESS {
    option domain-name-servers 208.67.222.222, 208.67.220.220;
    option routers 192.168.1.1;
    subnet 192.168.1.0 netmask 255.255.255.0 {
        range 192.168.1.32 192.168.1.127;
    }
}
shared-network LOCAL-WIRED {
    option domain-name-servers 208.67.222.222, 208.67.220.220;
    option routers 192.168.0.1;

    subnet 192.168.0.0 netmask 255.255.255.0 {
        range 192.168.0.2 192.168.0.127;
    }
    group {
        host vault {
        hardware ethernet 00:1a:92:e2:32:e1;
        fixed-address 192.168.0.2;
    }
    host xbox {
        hardware ethernet 00:12:5a:b6:92:1b;
        fixed-address 192.168.0.3;
    }
}
}

Continue to Step 4.