<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ever on and on &#187; OpenWRT</title>
	<atom:link href="http://www2.kaufmanfamily.net/blog/category/tech-topics/openwrt/feed" rel="self" type="application/rss+xml" />
	<link>http://www2.kaufmanfamily.net:8080/blog</link>
	<description>The Road goes ever on and on</description>
	<lastBuildDate>Thu, 13 May 2010 12:11:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Improving on the Auto-connecting Cisco VPN</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2010/05/improving-on-the-auto-connecting-cisco-vpn</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2010/05/improving-on-the-auto-connecting-cisco-vpn#comments</comments>
		<pubDate>Tue, 11 May 2010 12:08:07 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=151</guid>
		<description><![CDATA[In my first post in this series I described an auto-connecting setup for Cisco VPNs using OpenWRT and vpnc, and in my second post I showed the details of how I did it. To wrap it up, here are some thoughts about future improvements.
One thing that bugs me about this setup is that I hardcoded [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.kaufmanfamily.net/blog/2010/05/auto-connecting-cisco-vpn-for-openwrt">first post</a> in this series I described an auto-connecting setup for Cisco VPNs using <a href="http://www.openwrt.org">OpenWRT</a> and <a href="http://www.unix-ag.uni-kl.de/~massar/vpnc/">vpnc</a>, and in my <a href="http://www.kaufmanfamily.net/blog/2010/05/how-to-auto-connect-a-cisco-vpn-with-openwrt">second post</a> I showed the details of how I did it. To wrap it up, here are some thoughts about future improvements.</p>
<p>One thing that bugs me about this setup is that I hardcoded some IP addresses. This is a really bad idea, in fact half the reason DNS exists is to stop people from doing this. Someday the VPN administrators could decide to renumber their gateway, and then I would have to connect to each and every WRT and update the configuration, or all my customers would be cut off from the VPN.</p>
<p>I could stop hardcoding the VPN gateway pretty easily, by having it auto-update whenever the WRT boots. Look up the correct IP address and write it to <code>/etc/hosts</code>. (You need to be careful not to trigger the VPN autoconnect when you do the lookup, of course.)</p>
<p>The DNS servers are a little harder to fix. To look them up, we need to actually connect the VPN, and then pull out the nameservers that the VPN tells us to use. But this could be done automatically each time the VPN is connected, and it would make the whole setup more robust. Don&#8217;t forget to restart <code>dnsmasq</code> after you reconfigure it.</p>
<p>Another thing that bothers me is that there are a lot of gyrations before the VPN gets connected: a packet goes to a private IP address, matches on the <code>vpn_trigger</code> rule, which queues a message for the <code>ulog</code> daemon, which writes to a file, which causes the file to exist, and also causes <code>tail</code> to create some output, which finally causes the script to start <code>vpnc</code>. Whew!</p>
<p>One suggestion is to use <code>inotify</code> to watch the file, which is a good idea but still requires a file. (Also I don&#8217;t see <code>inotify</code> in the OpenWRT Kamikaze package list.) Another possibility would be to write a <code>ulog</code> plugin so that I can omit the file altogether. That might make VPN startup quicker, which would be a good thing.</p>
<p>Finally, if a customer wanted it, there are more sophisticated setups possible. It might be useful to connect to more than one VPN (either serially or at the same time), or to have the different LAN ports on the OpenWRT connect to different VPNs. All of these are possible if the scenario warrants it.</p>
<p>What are your ideas?</p>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2010/05/improving-on-the-auto-connecting-cisco-vpn/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to auto-connect a Cisco VPN with OpenWRT</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2010/05/how-to-auto-connect-a-cisco-vpn-with-openwrt-2</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2010/05/how-to-auto-connect-a-cisco-vpn-with-openwrt-2#comments</comments>
		<pubDate>Thu, 06 May 2010 19:37:30 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=195</guid>
		<description><![CDATA[In my last post I outlined a design for auto-connecting Cisco VPNs using OpenWRT and the vpnc client. In this post I&#8217;ll share the code, and highlight a couple of details. Finally, in my next post, I&#8217;ll share some thoughts on improving these scripts.
This process requires some knowledge about your VPN setup. To keep my [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www2.kaufmanfamily.net:8080/blog/2010/04/auto-connecting-cisco-vpn-for-openwrt">my last post</a> I outlined a design for auto-connecting Cisco VPNs using <a href="http://www.openwrt.org">OpenWRT</a> and the <a href="http://www.unix-ag.uni-kl.de/~massar/vpnc/">vpnc</a> client. In this post I&#8217;ll share the code, and highlight a couple of details. Finally, in my next post, I&#8217;ll share some thoughts on improving these scripts.</p>
<p>This process requires some knowledge about your VPN setup. To keep my post from getting too long, I&#8217;m assuming that you know your VPN domain name and IP address range, that you can quickly figure out the IP addresses of hosts and DNS servers, and that you have a working vpnc config file.</p>
<p>The first step is installing additional packages on OpenWRT. You can install these from the web interface, or using <code>opkg install</code> at the OpenWRT shell:</p>
<ol>
<li>vpnc, the Cisco VPN client</li>
<li>ulogd-mod-extra, which pulls down the ulog daemon</li>
<li>kmod-ipt-ulog, kernel modules for iptables and ulog</li>
<li>iptables-mod-ulog, part of the tool for adding rules to iptables</li>
</ol>
<p>Next, we need to make sure you can always reach the VPN gateway host. So we configure it into <code>/etc/hosts</code>. Look up the IP address (using <code>nslookup</code>, <code>dig</code>, or a similar tool) and add a line to /etc/hosts like:<br />
<code><br />
aaa.bbb.ccc.ddd vpn.example.org<br />
</code></p>
<p>Now that we know we can reach the VPN gateway, we will redirect dnsmasq to always use the internal servers for the VPN&#8217;s domain. Look up the domain nameservers using <code>nslookup</code> or <code>dig</code> from inside the VPN, or just look at the nameservers in <code>/etc/resolv.conf</code> when you&#8217;re connected from your PC. Then edit <code>/etc/config/dhcp</code> on OpenWRT and add lines like this:<br />
<code><br />
       # EXAMPLE.ORG private servers<br />
       list server             '/example.org/aaa.bbb.ccc.ddd'<br />
       list server             '/example.org/aaa.bbb.ccc.eee'<br />
</code></p>
<p>Now, we need the script that will manage the VPN connection. Cut and paste this code into <code>/usr/bin/autostart-vpn.sh</code>:</p>
<pre>
#!/bin/sh
#
# Autostart vpnc
#
# From http://www.kaufmanfamily.net/blog/2010/05/how-to-auto-connect-a-cisco-vpn-with-openwrt
# DHK 4/17/2010

MYPID=/var/run/autostart-vpnc.pid
LOGFILE=/var/log/ulogd.syslogemu
PIDFILE=/var/run/vpnc/pid

is_vpn_connected() {
        connected=0
        if [ -s $PIDFILE ]; then
                ps=`ps | awk -v pid=\`cat $PIDFILE\` '$1 == pid &#038;&#038; $5 == "vpnc" { print $0 }'`
                if [ -n "$ps" ]; then
                        connected=1
                fi
        fi
}

# Fill in our PID file
echo $$ > $MYPID

# Loop, monitoring the VPN
while true; do
	is_vpn_connected

	if [ $connected -eq 0 ]; then
		# VPN is not connected. Wait for a request, then start it

		# Wait for a log message, denoting that someone is trying to connect
		while [ ! -e $LOGFILE ]; do
			sleep 10
		done
		pkt=`tail -0 -f $LOGFILE | head -1`
		logger "autoconnect[$$] connecting due to $pkt"

		# Start the vpn
		date >> /tmp/autoconnect-vpnc.log
		vpnc >> /tmp/autoconnect-vpnc.log

		# Let the VPN settle
		sleep 2
	else
		# VPN is connected. Wait for it to drop, then clean up

		# Wait for the VPN to disconnect
		while [ $connected -eq 1 ]; do
			is_vpn_connected

			# sleep 10 seconds, check again
			sleep 10
		done
		logger "autoconnect[$$] disconnected"

		# Clean up route table
		if [ -f /var/run/vpnc/defaultroute ]; then
			outsidegw=`awk '{print $3}' /var/run/vpnc/defaultroute`
			currentgw=`netstat -rn | awk '$1 == "0.0.0.0" &#038;&#038; $4 == "UG" {print $2}'`
			if [ "X$outsidegw" != "X$currentgw" ]; then
				if [ "X$currentgw" != "X" ]; then
					route delete default gw $currentgw
				fi

				# Restore exactly what was saved, except vpnc syntax is slightly wrong
				route add `sed -e 's/via/gw/;' /var/run/vpnc/defaultroute`
			fi
		fi

		# Clean up resolv.conf
		resolvconf -d
	fi
done
</pre>
<p>We&#8217;re almost there. Cut and paste the following code into <code>/etc/init.d/autostart-vpn</code>; this is the startup script that creates the iptables rules and starts the last script at boot time. Make sure you edit the script to list the correct networks for your VPN, and check that the locations (hardcoded, unfortunately) for inserting <code>vpn_trigger</code> in the <code>FORWARD</code> and <code>OUTPUT</code> rulesets makes sense:</p>
<pre>
#!/bin/sh /etc/rc.common
#
# From http://www.kaufmanfamily.net/blog/2010/05/how-to-auto-connect-a-cisco-vpn-with-openwrt
# DHK 4/17/2010
#
# Start after dnsmasq
START=80

VPN_NETWORKS="10.0.0.0/8 192.152.0.0/16"
EXT_IF="eth0.1"

check_firewall_rules() {
	trigger=`iptables -L vpn_trigger 2>/dev/null`

	if [ "X$trigger" == "X" ]; then
		# Fill in vpn_trigger ruleset
		iptables -N vpn_trigger

		for net in $VPN_NETWORKS; do
			iptables -A vpn_trigger -o $EXT_IF --dest "$net" -j ULOG
		done

		# Hook vpn_trigger into OUTPUT and FORWARD rules
		# Ought to do something smarter than hardcoding the position
		iptables -I OUTPUT  4 -j vpn_trigger
		iptables -I FORWARD 4 -j vpn_trigger
	fi
}

start() {
	check_firewall_rules

	/usr/bin/autostart-vpnc.sh &#038;
}

stop() {
	if [ -f /var/run/autostart-vpnc.pid ]; then
		kill `cat /var/run/autostart-vpnc.pid`
	fi
}
</pre>
<p>One detail I skipped last time is that <code>vpnc</code>, as packaged for OpenWRT Kamikaze, will stomp on your resolv.conf file. Its default configuration just doesn&#8217;t work on OpenWRT. (The issue is that OpenWRT puts the WAN resolv.conf details in a non-standard place.) There&#8217;s an easy fix for this, though. Cut and paste the following code into /sbin/resolvconf.  <code>vpnc</code> will find <code>resolvconf</code> and use it to manage <code>/etc/resolv.conf</code> correctly.</p>
<pre>
#!/bin/sh
#
# Simple resolvconf manager to integrate vpnc better with WRT
#
# Update /tmp/resolv.conf.auto, NOT /etc/resolv.conf. This affects the
# DNS resolver operation, which is actually the right thing.
#
# Usage:
#
#   resolvconf -a [if] < new-resolvconf
#
#   resolvconf -d [if
#
# We ignore the [if] argument.
#
# From http://www.kaufmanfamily.net/blog/2010/05/how-to-auto-connect-a-cisco-vpn-with-openwrt
# DHK 4/13/2010

BACKUP=/tmp/resolv.conf.bak
RESOLV=/tmp/resolv.conf.auto

if [ $1 == "-a" ]; then
	# Change resolv.conf

	if [ ! -e $BACKUP ]; then
		cp $RESOLV $BACKUP
	fi

	cat > $RESOLV
fi

if [ $1 == "-d" ]; then
	# Restore original resolv.conf

	if [ -e $BACKUP ]; then
		mv $BACKUP $RESOLV
	fi
fi
</pre>
<p>Now is a good time to make sure you&#8217;ve installed your VPN configuration into <code>/etc/vpnc/default.conf</code>. It&#8217;s a good idea to test out your <code>vpnc</code> config on another machine before running it on OpenWRT.</p>
<p>OK, let&#8217;s enable the services we need. You can do this from the OpenWRT web interface, or the command line:<br />
<code><br />
/etc/init.d/ulogd enable<br />
/etc/init.d/autostart-vpnc enable<br />
</code></p>
<p>Reboot your OpenWRT to get all the services set up. You&#8217;ll want to watch the system message log, so in one ssh connection run the log reader:<br />
<code><br />
logread -f<br />
</code></p>
<p>and in another ssh connection start <code>ping</code>ing a host in the VPN:<br />
<code><br />
ping somehost.example.org<br />
</code></p>
<p>You should see a message in the system log, and after a short delay you&#8217;ll start getting <code>ping</code> responses. Make sure to test the auto-connect from a host plugged in to your OpenWRT&#8217;s LAN port as well as from the shell: if auto-connect works directly from the OpenWRT shell, but not from the LAN, then your iptables OUTPUT rule is correct but your FORWARD rule isn&#8217;t. (If the problem is reversed, then the rules are reversed.)</p>
<p>If auto-connection doesn&#8217;t work, you can check the log at <code>/tmp/autoconnect-vpnc.log</code> and then debug the process step-by-step:</p>
<ol>
<li>First, check that your vpnc configuration works:<br />
    <code>vpnc</code></li>
<li>Then, check that the vpn_trigger iptables rule is being called by looking at the packet counts:<br />
   <code> iptables -L vpn_trigger -v</code></li>
<li>If vpn_trigger is being called, make sure that ulogd is writing to the correct file:<br />
    <code>cat /var/log/ulogd.syslogemu</code></li>
<li>check that the autoconnect script is actually running with <code>ps</code></li>
</ol>
<p>The hardest thing to check is that you have your DNS setup correct. I usually do this by checking the <code>vpn_trigger</code> rules first, then use <code>nslookup</code> to query a behind-the-vpn host.</p>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2010/05/how-to-auto-connect-a-cisco-vpn-with-openwrt-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Auto-connecting Cisco VPN for OpenWRT</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2010/05/auto-connecting-cisco-vpn-for-openwrt</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2010/05/auto-connecting-cisco-vpn-for-openwrt#comments</comments>
		<pubDate>Wed, 05 May 2010 00:00:09 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=148</guid>
		<description><![CDATA[vpnc is an open source client for Cisco VPNs, which is pretty widely used. It&#8217;s intended as a user-driven interface: user decides to connect, user runs vpnc (or one of the many GUI wrappers around it) to connect, user uses remote resources, user disconnects. But for some users, manually connecting &#038; disconnecting the VPN is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.unix-ag.uni-kl.de/~massar/vpnc/">vpnc</a> is an open source client for Cisco VPNs, which is pretty widely used. It&#8217;s intended as a user-driven interface: user decides to connect, user runs vpnc (or one of the many GUI wrappers around it) to connect, user uses remote resources, user disconnects. But for some users, manually connecting &#038; disconnecting the VPN is a burden. I developed an auto-connecting VPNC setup for just such a customer scenario.</p>
<p>I started with <a href="http://www.openwrt.org">OpenWRT</a> (of course!) and vpnc. So far I&#8217;ve deployed this setup using OpenWRT Kamikaze, versions 8.09.1 and 8.09.2. I&#8217;ll describe how the process works first, and then show the details in my next post.</p>
<p>The first thing we need to do is intercept DNS queries for the secure network. (Most secure networks will have a private DNS server behind the firewall, with lots of information that&#8217;s not in the public version.) OpenWRT uses the <a href="http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html">dnsmasq</a> name resolver, and happily dnsmasq provides for exactly this case. So, we configure dnsmasq to know that the servers for the VPN domain are on its private addresses, and not to use the public servers.</p>
<p>Some companies might have the name of the VPN gateway in the same domain as their private, through the VPN environment. This could be a problem: how do we find the IP address for the gateway, if we need the VPN to talk to the domain servers? The easy answer for now is to just hardcode it in /etc/hosts on the OpenWRT.</p>
<p>OK, so we dealt with DNS name resolution, but how do we get the IP packets to go through the VPN? Actually, once vpnc connects, it will set up routing on the OpenWRT for us. So the only tricky bit is starting up vpnc at just the right time.</p>
<p>One way to do this would be to start vpnc whenever the WRT boots. This works, pretty much, but might be considered hostile by the VPN administrators. Instead we want to start the vpn tunnel whenever a user tries to access a machine in the private environment. To do this, we need to capture IP packets being routed to private IP addresses. This sounds like a job for <a href="http://www.netfilter.org/">iptables</a>!</p>
<p>iptables is part of the Linux kernel which lets you define rules for handling IP packets. It does all kinds of cool things &#8211; filtering, QOS, NAT &#8211; but all we need it to do is tell us when someone is trying to connect through the VPN, so that we can start up the VPN tunnel. To do this, I used the iptables &#8220;ULOG&#8221; target: ULOG writes a message to a userspace daemon called <a href="http://rlworkman.net/howtos/ulogd.html">ulogd</a>, which acts like a hub (kind of like syslogd) and routes the messages to other programs. I kept it simple and just wrote the message to a file.</p>
<p>To tie it all together, I wrote a script which monitors the ulog file. The script gets automatically started at boot time: if the VPN isn&#8217;t up yet, it just monitors the ulog file. When a packet trace appears in the ulog file, we know it&#8217;s time to start the VPN up. Once the VPN is connected, the script hangs out, waiting for it to get shut down &#8212; either manually or by an idle timer. If the VPN gets shut down, then the script goes back to watching the ulog file.</p>
<p>OK, so we have DNS requests going to the private servers, and IP traffic causes the VPN to autoconnect. We&#8217;re done, right? Well, almost. It turns out that sometimes vpnc shuts down messily. It can leave the OpenWRT without a default route, or it can leave the resolv.conf file pointing to behind-the-tunnel servers. Either one of these problems is enough to prevent reconnecting the VPN! So I added a cleanup step to my script, which makes sure that vpnc has cleaned up after itself.</p>
<p>Add some logging and a simple web interface, and we&#8217;re all set. Details in my next post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2010/05/auto-connecting-cisco-vpn-for-openwrt/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finishing the Separate LANs Configuration</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2009/09/124</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2009/09/124#comments</comments>
		<pubDate>Mon, 14 Sep 2009 14:00:35 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>
		<category><![CDATA[Tech topics]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=124</guid>
		<description><![CDATA[Last time I wrote about how OpenWRT configures networks at the port level. Once I split the LAN ports into two separate LANs, there was higher-level configuration that also needed to be taught about the LANs.
Once again, I&#8217;ll show the configuration from /etc/config files. The first thing we need to do is define a network [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.kaufmanfamily.net/blog/2009/08/separate-lans-under-openwrt">Last time</a> I wrote about how OpenWRT configures networks at the port level. Once I split the LAN ports into two separate LANs, there was higher-level configuration that also needed to be taught about the LANs.</p>
<p>Once again, I&#8217;ll show the configuration from /etc/config files. The first thing we need to do is define a network for the new LAN (in fact, I renamed the old LAN as well). The type is &#8220;bridge&#8221; so we can bridge it with the wireless LAN, as we noted last time. The interface is eth0.2, which is the new VLAN. This looks something like:<br />
<code><br />
config 'interface' 'homelan'<br />
        option 'type' 'bridge'<br />
        option 'ifname' 'eth0.2'<br />
</code></p>
<p>Finally I wrote some iptables rules to prevent forwarding between the two LANs, and to prevent access to the router itself.<br />
Then we need to add a section to the dhcp configuration. In this case we don&#8217;t want to run DHCP on this interface, so I set &#8220;ignore&#8221; to 1.<br />
<code><br />
config 'dhcp'<br />
        option 'interface' 'homelan'<br />
        option 'ignore' '1'<br />
</code></p>
<p>Finally, and this is key, we need to add some sections to the firewall config file. First we need to define a &#8220;zone&#8221;, which is an OpenWRT concept. This (typical) zone allows packets to be transmitted or received on the homelan interface, but not to be forwarded between interfaces:<br />
<code><br />
config 'zone'<br />
        option 'name' 'homelan'<br />
        option 'input' 'ACCEPT'<br />
        option 'output' 'ACCEPT'<br />
        option 'forward' 'REJECT'<br />
</code></p>
<p>Then we configure forwarding from the homelan into the WAN:<br />
<code><br />
config 'forwarding'<br />
        option 'src' 'homelan'<br />
        option 'dest' 'wan'<br />
        option 'mtu_fix' '1'<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2009/09/124/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Separate LANs under OpenWRT</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2009/08/separate-lans-under-openwrt</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2009/08/separate-lans-under-openwrt#comments</comments>
		<pubDate>Mon, 31 Aug 2009 14:00:26 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=83</guid>
		<description><![CDATA[A friend runs two separate subnets at home: one is for home computing/entertainment, and the other is work-related. It's important to keep the entertainment users off the work LAN. Here's how we set up separate LANs under OpenWRT.]]></description>
			<content:encoded><![CDATA[<p>A friend runs two separate subnets at home: one is for home computing/entertainment, and the other is work-related. It&#8217;s important to keep the entertainment users off the work LAN. We recently replaced his aging firewall with an ASUS WL-520gU running OpenWRT, so I had to work out how to create separate LANs under OpenWRT.</p>
<p>We picked the the 520gU because it has 1 WAN port, 4 LAN ports, and a USB port, and becuase it runs OpenWRT well. We set up the root filesystem on an external USB stick (see <a href="/blog/2009/08/pivotroot-intro">previous</a> <a href="/blog/2009/08/a-better-pivotroot">posts</a>). Then we had to work out how to have two separate networks on the LAN side.</p>
<p>OpenWRT sets up networks by tying together ports into VLANs (see fuller discussion on the OpenWRT site). Each of these groups of ports becomes a separate sub-interface of the master ethernet interface. For example, the standard configuration on a 520gU has (as I said) 1 WAN port and 4 LAN ports. But all of those ports are connected to the same switch: the only difference between WAN and LAN is that they&#8217;re on different VLANs, and some labelling onthe outside of the box. The master ethernet interface is eth0; the standard OpenWRT LAN is eth0.0, and WAN is eth0.1.</p>
<p>All of this is set up on the OpenWRT Network / Interfaces configuration page, which manipulates the file /etc/config/network. I&#8217;ll show you the examples in /etc/config/network, partly because it&#8217;s easier to have text examples and partly because there are 2 admin UIs for OpernWRT (LUCI, which comes with OpenWRT, and X-WRT, a parallel project that I use). Here&#8217;s the default setup:</p>
<pre>
config 'switch' 'eth0'
        option 'vlan0' '1 2 3 4 5*'
        option 'vlan1' '0 5'
</pre>
<p>vlan0, as I said, is the standard LAN, and vlan1 is WAN. But wait, I said there were 5 ports (1 WAN and 4 LAN) but the ports here are numbered 0-5. What&#8217;s the 6th port? Well, it&#8217;s the internal switch connected to the CPU, and it&#8217;s included in every group of ports. If it weren&#8217;t then OpenWRT couldn&#8217;t see the packets.</p>
<p>Here&#8217;s the configuration with two different LANs:</p>
<pre>
config 'switch' 'eth0'
        option 'vlan0' '1 2 5*'
        option 'vlan1' '0 5'
        option 'vlan2' '3 4 5'
</pre>
<p>vlan1 is still the WAN port, but now vlan0 is one LAN network, and vlan2 is the other. Next time I&#8217;ll show how we did the firewall rules to complete the job. But before we tackle the firewall rules, I need to set up the WiFi.</p>
<p>WiFi is different, and isn&#8217;t on the 6-port ethernet switch. Instead, WiFi works with its own master interface, and sub-interfaces for each WiFi network that you&#8217;re either a client on, or an access point for.  Then you can bridge the WiFi subinterface to a LAN subinterface, to create a network with both WiFi and LAN access types.</p>
<p>The standard OpenWRT configuration bridges the LAN to wl0, the default and first WiFi subinterface. We were able to use this same configuration to bridge wl0 to the first LAN, eth0.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2009/08/separate-lans-under-openwrt/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Persistent /var for OpenWRT</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2009/08/persistent-var-for-openwrt</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2009/08/persistent-var-for-openwrt#comments</comments>
		<pubDate>Fri, 28 Aug 2009 14:00:06 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=78</guid>
		<description><![CDATA[In <a href="/blog/2009/08/pivotroot-intro">other</a> <a href="/blog/2009/08/a-better-pivotroot">posts</a> I talked about booting my OpenWRT routers off an external USB stick. In this post I'll describe how to make the /var directory tree persistent across reboots.]]></description>
			<content:encoded><![CDATA[<p>In <a href="/blog/2009/08/pivotroot-intro">other</a> <a href="/blog/2009/08/a-better-pivotroot">posts</a> I talked about booting my OpenWRT routers off an external USB stick. In this post I&#8217;ll describe how to make the /var directory tree persistent across reboots.</p>
<p>On a standard OpenWRT system, /var is a link to /tmp. This simplifies setup, but it means that /var gets wiped out on each reboot, because /tmp is a tmpfs (in-memory). Why do I care? Well, when you reboot you lose:</p>
<ol>
<li>The package lists downloaded by opkg update</li>
<li>DHCP leases that OpenWRT handed out</li>
<li>Web pages that polipo, a caching proxy, has already loaded</li>
<li>System-specific Bluetooth configuration, especially paired devices</li>
</ol>
<p>And I care about all of these. Also, the tmpfs is kind of small, which makes web caching harder.</p>
<p>Unfortunately, the assumption that /var is /tmp has leaked into a number of places, so you&#8217;ll need to fix those. Start with the USB Storage howto to setup your external filesystem, and with my pivotroot scripts as well. Make these changes when you&#8217;re booted off internal flash &#8211; don&#8217;t make them to your live filesystem.</p>
<p>I&#8217;ll assume your external USB stick is mounted on /mnt.</p>
<ol>
<li>Undo the link. <code>cd /mnt; rm var; mkdir -p var/etc</code></li>
<li>Fix the bootup scripts. Exceprts are below, but you need to fix references in etc/init.d/syslog and etc/init.d/boot on your USB stick</li>
</ol>
<p>diffs for etc/init.d/boot:</p>
<pre>
--- /etc/init.d/boot    Sun May 10 21:09:45 2009
+++ boot        Sat Jan  1 00:08:59 2000
@@ -38,10 +38,14 @@
        config_load system
        config_foreach system_config system

-       mkdir -p /var/run
-       mkdir -p /var/log
-       mkdir -p /var/lock
-       mkdir -p /var/state
+       mkdir -p /tmp/run
+       [ ! -f /var/run ]   &#038;&#038; ln -s /tmp/run   /var
+       mkdir -p /tmp/log
+       [ ! -f /var/log ]   &#038;&#038; ln -s /tmp/log   /var
+       mkdir -p /tmp/lock
+       [ ! -f /var/lock ]  &#038;&#038; ln -s /tmp/lock  /var
+       mkdir -p /tmp/state
+       [ ! -f /var/state ] &#038;&#038; ln -s /tmp/state /var
        mkdir -p /tmp/.uci
        chmod 0700 /tmp/.uci
        touch /var/log/wtmp
</pre>
<p>diffs for etc/init.d/syslog:</p>
<pre>
--- /etc/init.d/syslog  Fri Jun 12 08:16:26 2009
+++ syslog      Sat Jan  1 00:09:22 2000
@@ -11,7 +11,7 @@
        local cfg="$1"
        local type file size ipaddr port IPCALC_CMD SYSLOG_CMD
        local DEFAULT_type="circular"
-       local DEFAULT_file="/var/log/messages"
+       local DEFAULT_file="/tmp/log/messages"
        local DEFAULT_size=16
        local DEFAULT_ipaddr=""
        local DEFAULT_port=514
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2009/08/persistent-var-for-openwrt/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A better pivotroot for OpenWRT</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2009/08/a-better-pivotroot-for-openwrt</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2009/08/a-better-pivotroot-for-openwrt#comments</comments>
		<pubDate>Wed, 26 Aug 2009 14:00:38 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=65</guid>
		<description><![CDATA[I use OpenWRT for my wireless access point, and for some other projects. I often set up an OpenWRT box running off an external USB stick, instead of its internal flash. Last time I introduced pivotroot scripts; this time I'll discuss my own improvements in this process.]]></description>
			<content:encoded><![CDATA[<p><a href="/blog/2009/08/pivotroot-intro">Last time</a> I introduced pivotroot scripts for OpenWRT. This time I&#8217;ll discuss my improvements.</p>
<p>The standard OpenWRT pivotroot is pretty basic. It needs to know where your USB disk will show up, and it assumes that the filesystem is in good shape. But I have OpenWRT systems with multiple USB ports, plus I&#8217;d like to be able to use USB hubs. And my OpenWRT systems tend to run until the power goes off &#8211; so I want to make sure the filesystem is clean before I boot off it.</p>
<p>In order to make things safer, I choose to run an ext3 filesystem. This is harder on the flash, because of the journal writes, but safer recovery for unclean shutdowns &#8211; which are the norm. A corrupted filesystem only gets worse, though, so I want to run fsck before I use the filesystem. (That means you&#8217;ll need to install e2fsprogs in the flash-based root filesystem.)</p>
<p>Since my USB sticks can move around, I search through all the available disk partitions to find one that looks like an OpenWRT system. That means I may try to mount filesystems and have them fail, but this is pretty safe. Eventually I&#8217;ll find the right filesystem, and if not I&#8217;ll boot off flash. I do assume that the filesystem will be on partition 1, and that it will be an ext3 filesystem.</p>
<p>I hate that the standard pivotroot uses the /mnt mountpoint. I use /flash instead. When I&#8217;m looking for an OpenWRT filesystem I look for /flash (and also /sbin/init). (So I need to mkdir /flash on both the flash-based and USB root filesystems.)</p>
<p>Finally, I want to know what&#8217;s going on &#8211; especially with fsck &#8211; and a way to turn off the pivotroot easily. I put logs in /tmp/pivotroot.log, I make the power LED flash while I&#8217;m fsck&#8217;ing and searching for a root fs, and I have rcS check whether the pivotroot script is executable. A quick chmod -x /flash/etc/init.d/pivotroot, and I can boot off flash.</p>
<p>Enough yakking, here&#8217;s the code. /etc/init.d/pivotroot, first, but there&#8217;s more below:</p>
<pre>#!/bin/sh
# From http://oldwiki.openwrt.org/UsbStorageHowto.html - DHK 7/14/09
#
# Greatly enhanced to select among (maybe) several USB Mass Storage devices
# Assumes that the root fs will be on an ext3 filesystem in partition 1,
# and looks for /flash and /jffs in the root directory. Also assumes that
# mounting and checking each candidate device is harmless. Runs e2fsck
# over partitions before mounting them; note that this causes spurious
# date-related complaints every time, since time has not been synchronized
# yet at the time pivotroot is run.
#
# Output from this script is stashed at /tmp/pivotroot.log.
#
# DHK 7/23/2009

# Set Power LED flashing while we look for OpenWRT root
if [ -f /etc/diag.sh ]; then
  LED=1
  . /etc/diag.sh
  POW=`cat /proc/diag/led/power`
  set_led power f
fi

# install needed modules for usb and the ext3 filesystem
# We could defer loading the filesystem modules until we know there's a useful partition.
# **NOTE** for usb2.0 replace "uhci" with "ehci_hcd"
# **NOTE** for ohci chipsets replace "uhci" with "usb-ohci"
# **NOTE** for WL-500gP usb-uhci not usb-ohci
echo -n "pivotroot loading kernel modules: "
for module in usbcore usb-uhci scsi_mod sd_mod usb-storage ext2 jbd ext3 ; do {
  echo -n "$module "
  insmod $module
}; done
echo
# this may need to be higher if your disk is slow to initialize
sleep 4s

PART1=`find /dev/scsi -name part1`

if [ -z $PART1 ]; then
  echo No partitions, skipping pivotroot
else
  # Look for a mountable USB stick with, maybe, OpenWRT on it
  for dev in `find /dev/scsi -name part1`; do
    echo pivotroot checking $dev
    e2fsck -p $dev
    fsck=$?
    echo fsck status is $fsck
    if [ $fsck -eq 2 ]; then
      echo Corrected errors on $dev, need to reboot
      sleep 5
      reboot
    elif [ $fsck -eq 1 ]; then
      echo Corrected errors on $dev
    elif [ $fsck -gt 2 ]; then
      echo No usable filesystem on $dev
      continue
    fi
    echo Mounting $dev
    mount -t ext3 $dev /flash
    mt=$?
    if [ $mt -eq 0 ]; then
      if [ -x /flash/sbin/init -a -d /flash/jffs -a -d /flash/flash ]; then
        echo Found OpenWRT root on $dev
        # Side-effect - leave /flash mounted
        break;
      else
        echo "Missing /sbin/init, /jffs, or /flash (mount status was $mt)"
        [ -x /flash/sbin/init ] || echo Failed -x /sbin/init
        [ -d /flash/flash ]     || echo Failed -x /flash
        [ -d /flash/jffs ]      || echo Failed -x /jffs
        umount $dev
      fi
    else
      echo mount status is $mt
    fi
  done

  # if everything looks ok, do the pivot root
  [ -x /flash/sbin/init ] &#038;&#038; {
          mount -o move /proc /flash/proc &#038;&#038; \
          pivot_root /flash /flash/flash &#038;&#038; {
                  mount -o move /flash/dev /dev
                  mount -o move /flash/tmp /tmp
                  mount -o move /flash/jffs2 /jffs2 2>&#038;-
                  mount -o move /flash/sys /sys 2>&#038;-
          }
  }
fi

# Restore Power LED to previous state
[ $LED -eq 1 ] &#038;&#038; set_led power $POW
</pre>
<p>Addition to /etc/init.d/rcS (put this before the line LOGGER=&#8221;cat&#8221;):</p>
<pre>
# Improved from http://oldwiki.openwrt.org/UsbStorageHowto.html
# Switch the root filesystem to USB, if present
# DHK 7/14/09
if [ $2 == "boot" -a -x /etc/init.d/pivotroot ] ; then
        /etc/init.d/pivotroot > /tmp/pivotroot.log
fi
</pre>
<p>Finally, I add this line to the bottom of /etc/banner, but on the flash filesystem only. When I ssh in to an OpenWRT box I&#8217;ll know immediately how it booted:</p>
<pre>Booted off internal flash</pre>
<p>Remember, this works for me, but I make no guarantees it will work for you. Make sure you&#8217;ve saved your configuration before fooling with this stuff, and that you know how to reflash your router if you brick it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2009/08/a-better-pivotroot-for-openwrt/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Introducing pivotroot for OpenWRT</title>
		<link>http://www2.kaufmanfamily.net:8080/blog/2009/08/pivotroot-intro</link>
		<comments>http://www2.kaufmanfamily.net:8080/blog/2009/08/pivotroot-intro#comments</comments>
		<pubDate>Mon, 24 Aug 2009 14:00:06 +0000</pubDate>
		<dc:creator>kaufman</dc:creator>
				<category><![CDATA[OpenWRT]]></category>

		<guid isPermaLink="false">http://www2.kaufmanfamily.net:8080/blog/?p=61</guid>
		<description><![CDATA[I use OpenWRT for my wireless access point, and for some other projects. I often set up an OpenWRT box running off an external USB stick, instead of its internal flash. This time I'll intorduce pivotroot scripts, and next time I'll discuss improvements in this process between OpenWRT releases, and then my extensions.]]></description>
			<content:encoded><![CDATA[<p>I use OpenWRT for my wireless access point, and for some other projects. I often set up an OpenWRT box running off an external USB stick, instead of its internal flash. This gives me more storage space &#8211; for software packages but also pictures when I&#8217;m hosting a web site, etc. Another advantage of an external USB stick is that it&#8217;s cheap to replace when you burn out the flash, although I&#8217;ve never actually had this happen to me.</p>
<p>So how do you boot OpenWRT off an external USB stick? Well, midway through the boot process you change the root filesystem from the one on the internal flash to the one on the external stick. That means you need to check first that there&#8217;s a filesystem to boot off of. There&#8217;s <a href="http://oldwiki.openwrt.org/UsbStorageHowto.html">a standard procedure on the OpenWRT wiki,</a> using what&#8217;s called a pivotroot script.</p>
<p>In White Russian (the older OpenWRT release) the procedure was to replace /sbin/init with pivotroot. This is scary, because if you step wrong you&#8217;ve bricked your router &#8211; made it unbootable. In Kamikaze (the newer release), the recommendation has changed, and instead pivotroot is explicitly called from rcS, a very early bootup script. This is a better idea, and when I was done with my changes it was even safer.</p>
<p>What does a pivotroot script need to do? It needs to:</p>
<ol>
<li>Make sure the kernel can recognize your USB stick, by loading kernel modules to support USB and USB storage devices
</li>
<li>Make sure the kernel can recognize the filesystem on your USB stick, by loading more kernel modules. For example, I use the ext3 filesystem on my USB stick, and that&#8217;s not built in to the OpenWRT kernels</li>
<li>Check whether your USB stick is even present</li>
<li>Mount the filesystem on your USB stick</li>
<li>Finally, if everything else is OK, it remounts all the filesystems so that your USB stick is the root filesystem and the flash-based root filesystems are mounted elsewhere</li>
</ol>
<p>Note that this procedure still uses the flash-based root filesystem to get partway booted. Any special software packages you need to boot up &#8211; all those kernel modules, for example &#8211; and the pivotroot script itself need to be on the flash-based root filesystem, and not the root filesystem you see once you&#8217;re booted. This also makes debugging a pivotroot script tricky, because by the time OpenWRT is booted the environment is very different from the one pivotroot sees.</p>
<p>Next time I&#8217;ll outline the changes I made to improve the standard OpenWRT pivotroot.</p>
]]></content:encoded>
			<wfw:commentRss>http://www2.kaufmanfamily.net:8080/blog/2009/08/pivotroot-intro/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
