Archive for category Uncategorized

Enable WOL through a Linksys Router

This is blatent copy-paste job from: http://rotwhiler.wordpress.com/2009/03/24/enable-wake-on-lan-through-linksys-wrt54g/ put here for my own posterity.

This all works very well if the computer sending the Magic Packet is on the same LAN as the sleeping computer, but requires some additional effort to get working over the Internet. Especially if the very common Linksys WRT54G is your wireless router. The WRT54G setup page employs javascript to prevent the user from entering a broadcast address, so there is a work around. Here’s what to do to set this up:

  • Enable WOL on your computer. This is usually a setting in the BIOS. (This may not be possible if you are using a wireless card. Only the very latest cards support Wireless Wake On Lan.)
  • If you don’t already have Firefox, download and install it.
  • Download and install the DOM Inspector Firefox Add-on.
  • Using Firefox, open your Linksys WRT54G admin page (usually 192.168.1.1)
  • Click on Applications & Gaming
  • Add a new entry: Application=”WOL”, Start=”9?, End=”9?, Protocol=”UDP”, IP Address=”200?
  • In Firefox, click on Tools, then DOM Inspector.
  • Use DOM inspector to find the “WOL” entry and change IP Address from 200 to 255. (Firefox will red highlight the areas you have selected in DOM Inspector, this makes it easier to narrow down to the correct element.)
  • Click “Save Changes” on the Applications and Gaming page.
  • Download and install a Magic Packet program that can send a packet over the Internet. I like this one: http://magicpacket.free.fr/

You should now be able to wake your computer up from where ever you are. (Also, I should say that my router has firmware version 8.00.5. I don’t know if this matters, since I don’t have any other router to test it on.)

Note to self: this is probably unsafe and bad. Also, I used firebug.

No Comments

Texmake: a makefile generate for latex projects

texmake is a makefile generator, much like cmake. In fact, it originally started with me looking for ways to make cmake work with latex documents. After a bit of work, I decided the system was too much designed around the c/c++ build process, so I started working on some tools to simplify my life.

Keeping it simple

texmake tries to eliminate as much work as possible from the document writer. It will try to figure out and resolve dependencies, including graphics files which require conversion from their source format. It also allows for out-of-source builds, so that the source directory doesn’t get all cluttered with the intermediate files that latex generates.

Example

Consider this scenario: We have a very long complicated report to write (i.e. software manual, end-of-project report, thesis, how-to-book). We want to generate both a full version, and a simplified quick-start kind of version. The quick start version will contain a subset of the chapters of the full version. The quick start will be published in PDF and HTML (i.e. web-friendly). The long version will probably be a large document and we don’t really want it to be browsed on-line, but it is likely to be printed, so we’ll put it in pdf and dvi format, as well as epub for people who have e-readers.

example project

Example Project Structure

 

In the process of making this document, we’ve generated many image files. Some of them are hand drawn SVGs. Some of them are generated tikz images. Some of them are diagrams drawn in DIA or plots in GNU Plot. Some of these figures are shown in multiple different chapters (because the author does not want to just refer the user back to a previous page, which is unnecessary in an electronic format, but may be more meaningful in a print format).

Furthermore, we have some things that need to only be included in each version. For instance each version should include some kind of header which tells the reader where he can find the other versions online, or where he can order them from.

Now, we can go maintain a makefile structure that manages all of this quite easily, but we will have to build it by hand. Every time we add a new chapter or image or output format, we have to go add a line to a makefile somewhere. Wouldn’t it be nice if all of that work would just happen?

Features

here are a list of features that I have implemented or am working on

  1. don’t rebuild the document unless it needs it
  2. multiple documents in the same project, potentially sharing various pieces of content
  3. monitor documents dependency on package, style, and class files so that document is rebuilt if these are updated
  4. monitor dependencies on all included files, so that if any included file is updated, the document is rebuilt
  5. only run bibtex if needed
    1. one of the database files is updated
    2. there are unresolved citations in the document
  6. rerun latex until it stabilizes
  7. discover and automatically convert graphics source files (like svg) to the kind (pdf)latex(ml) understands (pdf,eps,png)
  8. out of source builds so that sources can be in version control without complicated ignore rules
  9. caches values of environment variables and binary locations so that initial environment does not have to be manually set-up each time the document is built
  10. colorize output to make it clear where and when things get messed up

Usage

texmake relies on the presence of a texmakefile in the directory of the document you want to build. The texmakefile simply lists source files (.tex documents) and the output files that should be built from them. Multiple output files can be built from the same input file, so that the same latex source can be used to generate pdf, dvi, and xhtml versions (so-called single source builds).

texmake init is called from the build directory, accepting a single parameter being the directory that contains the root texmakefile. texmake resolves the absolute path to all the tools it needs (latex, pdflatex, bibtex, latexml, kpsewhich, …), and caches those locations. (TODO: also cache environment variables for latex and search paths for kpsewhich). It generates a makefile in that directory which contains rules for all of the output files registered, and creates directories, if they’re missing, in which the output files will be located.

texmake relies on GNU make to determine when documents need to be rebuilt. This makefile includes several other makefiles (if they exist) containing detailed dependency lists for each of the output files. If the output files have never been built, these included files do not exist, but that’s OK because it is already clear to make that it needs to build the output files.

The output files are built with texmake build. The texmake builder runs (pdf)latex(ml) with all the necessary switches to make sure that the source directory and output directory are searched for required files. The builder also scans the output of latex to build a list of all the files that latex loads (for the dependency graph) as well as all the files that are missing. If the missing files are graphics files, then it generates make rules for how to build those graphics files from similarly graphics files in the source directory (it is assumed the source file has the same name, but a different extension). This way, an svg source file can be used to generate pdf,eps,or png images depending on if the document being built is dvi,pdf, or xhtml (respectively). If the file in the source directory is already compatible with the latex that is being used, then no conversion is necessary. If the missing file is a bibliography file, then bibtex is run to generate the bibliography file. The builder also scans the output of bibtex to add bibliography database files (.bib files) to the dependency graph. Bibtex is also run if there are missing citations reported by latex (this is because bibtex will not include bibliography entries that are not cited in the latex source, so if a new citation is added, bibtex will need to be rerun). The texmake builder also scans the output of latex for rerun suggestions. It will rerun latex if it had to run bibtex, or if latex itself suggested that it be rerun (to get cross references straight, for example).

Major TODO items

  1. cache environment variables in init
  2. use diff to determine if TOC’s get updated (they will get touched by latex so make will always think they’re new) to determine of a rerun is necessary for TOCs
  3. add image generation rules for tikz
  4. consider a more modular design for making intermediates (i.e. run a program, like matlab, to generate intermediates)

Code

The texmake code is in my project tracker.

No Comments

Personal Dynamic DNS in Ubuntu

I finally got around to purchasing a personal server and one of the first things I did was set up a private DNS server for cheshirekow.com. As it turns out, setting it up to be dynamic is quite easy. In this post I’ll go through the steps I took to get it up and running.

I wont bother with all the fun stuff about how dynamic DNS works or how to properly configure everything, but instead I’ll just post my configuration files for posterity.

More detailed information on configuring bind can be found in the Ubuntu Server Guide. A good article on nsupdate and dynamic updates to bind can be found on jeff garzik’s linux pages. I found the information I needed on Network manager hooks from sysadmin’s journey

Why Dynamic DNS?

Mostly because I’m lazy. I have a work laptop, a personal desktop, a netbook, an android tablet, and an android phone. I’m constantly scp’ing files from one to another, and I really hate having to write out the ip address specifically all the time. Since I own the domain cheshirekow.com, I figured it would be really slick to be able to address all of my machines as subdomains. For instance, I could label them as “laptop.cheshirekow.com”, “desktop.cheshirekow.com”, “netbook.cheshirekow.com”, “tablet.cheshirekow.com”, and “phone.cheshirekow.com”. If these dns entries are automatically updated when each of these devices connects to a wifi access point using DHCP, then I can even get files from one machine to another without even being physically near them.

named.conf.local

Following the ubuntu guide, I edited /etc/bind/named.conf.local to look like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//
// Do any local configuration here
//
 
// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";
 
zone "cheshirekow.com" {
	type master;
	file "/var/lib/bind/db.cheshirekow.com";
	allow-transfer { aaa.bbb.ccc.ddd; };
	allow-update { key "user.cheshirekow.com."; };
};

Note that the file is in /var/lib/bind/db.cheshirekow.com not in /etc/bind/db.cheshirekow.com like a lot of tutorials will tell you. This is because ubuntu prevents bind from writing to files in /etc/bind. You can either change the apparmor profile for bind, or, just do as I do, and put the file where you’re supposed to go in /var/lib/bind/ (there’s a note in the bind apparmor profile about this). Putting it in “/etc/bind” is fine if the dns entries are all static, but if there are dynamic entries then bind will try to create a .jnl file in the same directory as the db.xxx file. Since bind can’t write to /etc/bind we need to put the db file somewhere else.

Also, note that aaa.bbb.ccc.ddd is the ip address of my secondary name server for cheshirekow.com. I’m using afraid.org to host my secondary DNS.

The allow-update line allows the user user@cheshirekow.com to update the dns entries (the dynamic part) as verified by a keypair (generating the keypair comes later). Note that I don’t use the literal “user”.

/var/lib/bind/db.cheshirekow.com

The next thing was to create the db.cheshirekow.com file which looks like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ORIGIN .
$TTL 604800	; 1 week
cheshirekow.com		IN SOA	ns1.cheshirekow.com. cheshirekow.gmail.com. (
				9          ; serial
				604800     ; refresh (1 week)
				86400      ; retry (1 day)
				2419200    ; expire (4 weeks)
				604800     ; minimum (1 week)
				)
			NS	ns1.cheshirekow.com.
			A	aaa.bbb.ccc.ddd
			AAAA	::1
$ORIGIN cheshirekow.com.
ns1			A	aaa.bbb.ccc.ddd
www			A	eee.fff.ggg.hhh

Note that aaa.bbb.ccc.ddd is the ipaddress of the name server itself and eee.fff.ggg.hhh is the ip address of my web server (where you are currently reading this). Also note that my email address is cheshirekow@gmail.com but is written in this file as cheshirekow.gmail.com..

You can (should?) also set up reverse dns entries for all these things but I did not as the server is actually sitting in a different physical domain. In other words I don’t own a network of ip-addresses so there’s no reason to expect my server to be queried for reverse dns lookups.

Create Keys

The next thing we need to do is setup a key that we can use to do dynamic updates. This can be done on a separate machine from the name server… it doesn’t matter.

user@ns1:~$ mkdir .bind
user@ns1:~$ cd .bind
user@ns1:~$ dnssec-keygen -a HMAC-MD5 -b 512 -n USER user.cheshirekow.com.

Note that “USER” is a literal string, not a placeholder for something that you create. Also note that “user.cheshirekow.com” is the name of this key, and corresponds to the email address “user@cheshirekow.com”.

This command creates a public and private key.

user@ns1:~/.bind$ ls -l
total 8
-rw------- 1 user user 127 2011-06-10 16:51 Kuser.cheshirekow.com.+157+56713.key
-rw------- 1 user user 229 2011-06-10 16:51 Kuser.cheshirekow.com.+157+56713.private

Install Keys

Now we create a file to store these keys. I put them in /etc/bind/keys.local

1
2
3
4
key "user.cheshirekow.com." {
	algorithm HMAC-MD5;
	secret "2345A/bkd7GDcu9orjzblkj2r37ajglk489DLHD/m987addzjDCadsh8 bbIUOY809glkashDEmPj5alIUoiEeA==";
};

Note that this is not a real key, but random gibberish I pounded out on the keyboard. In reality, this key is copied directly from Kuser.cheshirekow.com.+157+56713.key.

I then added this file to named.conf.local so that it looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the 
// structure of BIND configuration files in Debian, *BEFORE* you customize 
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local
 
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
include "/etc/bind/keys.local";

Restart bind

That’s it for the bind setup so restart

user@ns1:~$sudo /etc/init.d/bind9 restart

Client Update Script

I then created the following update script in /etc/NetworkManager/dispatcher.d/99updatedns. This script is called as a hook from network manager every time an interface goes up or down. It receives two parameters. The first is the name of the interface (i.e. eth0 or wlan0) and the second is the status (i.e. up or down).

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
 
INTERFACE=$1
STATUS=$2
DIRECTORY="/home/user/Codes/shell/dyndns"
 
if [ "$STATUS" = "up" ]; then
    IPADDRESS=`ifconfig $INTERFACE | grep inet | grep -v inet6 | cut -d ":" -f 2 | cut -d " " -f 1`
    cp $DIRECTORY/nsupdate_src.txt /tmp/nsupdate.txt
    sed -i "s/IPADDRESS/$IPADDRESS/" /tmp/nsupdate.txt 
    nsupdate -k /home/user/.bind/Kuser.cheshirekow.com.+157+56713.private -v /tmp/nsupdate.txt
fi

Note that this script requires the nsupdate_src.txt which is here:

1
2
3
4
5
6
server ns1.cheshirekow.com
zone cheshirekow.com
update delete netbook.cheshirekow.com. A
update add netbook.cheshirekow.com. 86400 A IPADDRESS
show
send

The script extracts the ip address from the output of ifconfig for the correct interface, copies the file to /tmp/, replaces IPADDRESS with the actual address of the machine, and then calls nsupdate using the private key and the file. This script is saved as /etc/NetworkManager/dispatcher.d/99updatedns, owned by root and flagged executable. Note that this script accesses the key for my specific user, which is fine in my case because my netbook is a single-user machine. If the machine has multiple users, you may want to store the key and text file in /home/root or something.

Result

The result of this process is that netbook.cheshirekow.com always points to the ip address of my netbook, given that it is connected to a wifi access point. Whenever the netbook (re)connects to an access point, the network manager calls the script, and the dns entry on ns1.cheshirekow.com is updated.

(Update) Better Script

I changed the update script a little bit. Since I use a wired connection on my laptop most of the time, I don’t want the ip address for the wireless connection to supercede that of the wired connection if it is active.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
 
INTERFACE=$1
STATUS=$2
DIRECTORY="/home/user/Codes/shell/dyndns"
 
echo "network interface change hook:"
echo "----------------------------";
 
#first, check to see if eth0 is up and running
ETH0STR=`ifconfig eth0 | grep inet | grep -v inet6`
if [ -z "$ETH0STR" ]
then
    echo "eth0 has no address (probably is down or disconnected)"
    echo "checking interface $INTERFACE whose changed launched this script"
    if [ "$STATUS" = "up" ]
    then
        IPADDRESS=`ifconfig $INTERFACE | grep inet | grep -v inet6 | cut -d ":" -f 2 | cut -d " " -f 1`
        if [ -z "$IPADDRESS" ]
        then
            echo "$INTERFACE has no address, aborting (str = $IPADDRESS)"
        else
            echo "$INTERFACE has address $IPADDRESS"
            cp $DIRECTORY/nsupdate_src.txt /tmp/nsupdate.txt
            sed -i "s/IPADDRESS/$IPADDRESS/" /tmp/nsupdate.txt 
            nsupdate -k /home/user/.bind/Kuser.cheshirekow.com.+157+56713.private -v /tmp/nsupdate.txt            
        fi
    else
        echo "Status is not 'up', aborting"
    fi
else
    IPADDRESS=`echo $ETH0STR | cut -d ":" -f 2 | cut -d " " -f 1`
    echo "eth0 has address $IPADDRESS, ignoring changed interface $INTERFACE"
    cp $DIRECTORY/nsupdate_src.txt /tmp/nsupdate.txt
    sed -i "s/IPADDRESS/$IPADDRESS/" /tmp/nsupdate.txt 
    nsupdate -k /home/user/.bind/Kuser.cheshirekow.com.+157+56713.private -v /tmp/nsupdate.txt
fi

Edit:

For some reason whenever I update db.cheshirekow.com bind refuses to restart correctly. When I do this update, I have to delete the file /var/lib/bind/db.cheshirekow.com.jnl and restart.

1 Comment