2011/11/30

Mmm, tomatoes...

So I installed TomatoUSB on my Asus RT-N16. The router has 2 USB ports (can be extended with a hub) and firmware has support for block devices & printers. IPv6 support, 1Gbps ethernet, jumbo frames, per-IP QoS... even has a torrent app built in so you can download while your computers are offline.
Anyway, first few hurdles:
  • Found a way to route to DSL modem, same exact script as DD-WRT (how convenient!)
  • Found a way to add a non-root user, altered it to allow public key only and saved to nvram! (didn't know how to do it in dd-wrt, had to manually run the user setup script after each reboot). The only issue was permissions, which is easily fixed/hacked with init script

  • Found a way to enable multiple printers (more on that in a moment)

  • Found a way to send firmware to a printer that needs it (TODO as soon as I get a new USB2.0 hub)

  • Found a way to set up sane to share a scanner! This is what pushed me to choose Tomato over DD-WRT on this router, actually. I'm sure there's a way to do the same thing there, but convenient google result is more convenient :)

For running multiple printers, I have an Epson CX8400 printer/scanner and HP LJ 1018. But there's a minor problem: whichever printer is turned on first, becomes lp0 and is then automagically shared on port 9100. But what if someone turns on both? I don't want to make anyone remember that they first have to turn one, and only then another! Well, turns out there's a hacky way. First, some background
  • the way to share a printer on the next port (9101) is simply run "p910nd -b -f /dev/usb/lp1 1", where "-f /dev/usb/lp1" points it to the lp# device symlink, "1" means I want to use port 9101 (default is 9100 and the only remaining one is 9102), and in this case p910nd executable will rename itself to p9101d
  • Loading Printer's Firmware in Hotplug Script page tells me there's an easy way to trap add/remove action on these guys, even tells me how to find the product ID. But after printing all vars, it's apparent there's no mention of the /dev/*lp# device.
Oops! As luck would have it, though, one of those vars, DEVPATH, corresponds to the same file in /sys -- and the correct subdevice has a symlink to lp0 or lp1!
DEVPATH='/devices/pci0000:00/0000:00:04.1/usb1/1-2/1-2:1.1'
root@rooter:/tmp/home/root# ls -ld /sys/devices/pci0000:00/0000:00:04.1/usb1/1-2/1-2\:1.1/usb\:lp1
lrwxrwxrwx    1 root     root             0 Dec 31  1969 /sys/devices/pci0000:00/0000:00:04.1/usb1/1-2/1-2:1.1/usb:lp1 -> ../../../../../../class/usb/lp1
This is easily parseable by a shell script (hotplug). Said script can immediately create an extra symlink, specific to the printer model -- that one is guaranteed to be the right one! Then, all I need to do is share it -- and there's already a way to do all these things. So, without further stalling for time, here's the hacky script:
if [ $INTERFACE = "7/1/2" ]; then
 f=/sys/${DEVPATH}/usb:*; [ -e $f ] && d=`ls -d $f |sed 's/.*://'`
 if [ $PRODUCT = "3f0/4117/100" ]; then
  l=/dev/usb/HP1018
  if [ $ACTION = "add" ] && [ "n$d" != "n" ]; then ln -sf /dev/${d} $l; p910nd -b -f $l 2
   #TODO: send firmware to the printer
  elif [ $ACTION = "remove" ]; then rm -f $l; killall p9102d 2>/dev/null
  fi
 elif [ $PRODUCT = "4b8/839/100" ]; then
  l=/dev/usb/EpsonCX8400
  if [ $ACTION = "add" ] && [ "n$d" != "n" ]; then ln -sf /dev/${d} $l; p910nd -b -f $l 1
  elif [ $ACTION = "remove" ]; then rm -f $l; killall p9101d 2>/dev/null
  fi
 fi
fi

Not only does it create everything - it cleans up, too! And it can do the firmware trick as well (need usb hub for the thumbdrive - I'll probably need it for optware/sane, so might as well use it for the printer firmware, too, instead of mucking about with built-in flash)

2010/10/19

IP Aliasing (Fedora), Multiple IPs (DD-WRT)

# cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0:1
 .. edit ifcfg-eth0:1 - change UUID and all references to eth0 become eth0:1
# ifup eth0:1

(from http://fedoraforum.org/forum/showthread.php?t=239242)


# Save Startup
WANIF=`nvram get wan_iface`
WANMASK=`nvram get wan_netmask`
ifconfig $WANIF:1 173.X.X.250 netmask $WANMASK broadcast [BROADCAST]
ifconfig $WANIF:2 173.X.X.251 netmask $WANMASK broadcast [BROADCAST]
ifconfig $WANIF:3 173.X.X.252 netmask $WANMASK broadcast [BROADCAST]

# Save Firewall

# WAN .250 -> LAN .15
iptables -t nat -I PREROUTING -d 173.X.X.250 -j DNAT --to 192.168.0.15
iptables -t nat -I POSTROUTING -s 192.168.0.15 -j SNAT --to 173.X.X.250
iptables -I FORWARD -d 192.168.0.15 -p tcp --dport 21 -j ACCEPT
iptables -I FORWARD -d 192.168.0.15 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -d 192.168.0.15 -p tcp --dport 5900 -j ACCEPT

# WAN .251 -> LAN .20
iptables -t nat -I PREROUTING -d 173.X.X.251 -j DNAT --to 192.168.0.20
iptables -t nat -I POSTROUTING -s 192.168.0.20 -j SNAT --to 173.X.X.251
iptables -I FORWARD -d 192.168.0.20 -p tcp --dport 21 -j ACCEPT
iptables -I FORWARD -d 192.168.0.20 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -d 192.168.0.20 -p tcp --dport 5900 -j ACCEPT

(from http://www.dd-wrt.com/wiki/index.php/One-to-one_NAT)

Pretty sweet!

2010/10/18

N900 MMS

So I've been having problems getting MMS messages on my phone.
Turns out, I had it set to "polite" mode, though the "proper" mode is the "havoc". Started working instantly... bugger

2010/10/17

SSL certs - self-signing

Basic setup from http://www.yatblog.com/2007/02/27/how-to-create-a-ssl-certificate/

$ openssl genrsa -des3 -out server.key 1024
$ openssl req -new -key server.key -out server.csr
$ cp server.key server.key.org
$ openssl rsa -in server.key.org -out server.key
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Works great and can use it with wildcard subdomains. But there's a caveat when using wildcard -- the cert is only valid for *.domain.com, not for domain.com
There's something called subjectAltName, but getting it to work is tricky (or, rather, it was tricky finding out how to get it to work...)

Finally found it here http://lists.mandriva.com/cooker-server/2004-01/msg00189.php

Instead of the last command, do this:
$ cat >ext.cnf <<EOF
[ alt_name ]
subjectAltName = DNS:domain.com,DNS:*.domain.com
EOF
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -extfile ext.cnf -extensions alt_name

2010/10/15

Cool bash trick

# yum install bash-completion

2010/07/20

RAID -- downgraded to Oops

As planned, I reverted the chunk size back to 64. Meanwhile, it occurred to me to try the same operation in a sandbox. So I made 4 10m files and tried to make an array out of them. That failed, since files are not block devices. Next I tried /dev/ram## devices and the array was up. I copied some files to it and played around trying to replicate the same actions I made on the live array. I was able to shrink it, change chunk size there and back multiple times without any problems. That brought my hopes up, obviously.

So, this morning re-re-chunking finally finished and I tried to resize the array:

# mdadm --grow -z max --backup-file=/root/grow_md0_size_back.bak /dev/md0
mdadm: component size of /dev/md0 has been set to 293033536K
# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sdd1[3] sda4[0] sdc1[2] sdb1[1]
293033472 blocks level 5, 64k chunk, algorithm 2 [4/4] [UUUU]

Uhh.. what? Moshi-mosh..?
Can't do anything, array size is staying too small. Finally, I decide to take a leap of faith: stop the array and reassemble it (normally it's just like unmount/remount, but who knows what would happen with an array this messed up)

# mdadm --stop --scan
...
# mdadm --assemble --scan
mdadm: /dev/md0 has been started with 3 drives (out of 4).
# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sda4[0] sdc1[2] sdb1[1]
879100608 blocks level 5, 64k chunk, algorithm 2 [4/3] [UUU_] 
# mount /raid

Huh.. 3 out of 4, but it mounts. Woohoo! Time for backups...

Meanwhile, investigating:

in /var/log/messages:

Jul 20 09:56:41 slon kernel: md0: detected capacity change  from 0 to 900199022592
Jul 20 09:56:41 slon kernel: md0: unknown  partition table


That looks scary, but is normal. To the kernel, md0 is just a block device like a normal HDD -- and it doesn't have its own partition table. This is OK because ext filesystems don't require a partition table, you can use the entire drive for one.



Eventually, I found 2 errors I've made:
  1. The new partition had type "83 Linux" instead of "fd Linux raid autodetect"
  2. I left out a / in front of /dev/sdf1 in /etc/mdadm.conf -- so when mdadm looked at /dev/sdf1 it thought it wasn't part of my array

No idea if one of these was the cause of the resizing problem, but everything is up and running now.

2010/07/19

RAID -- Oh shit!

I wanted to add a 4th drive to the RAID box. That was easy enough:

mdadm --add /dev/md1 /dev/sdb3
mdadm --grow --raid-devices=4 --backup-file=/root/grow_md0.bak /dev/md0


Normally, at this point you're supposed to resize the FS to use the whole capacity (otherwise it keeps using the old size, only spread out over 1 more drive).

Then I decided to try 512k chunks because of some pages claiming it gives better performance.
Cue Trouble.


# cat /proc/mdstat 
Personalities : [raid6] [raid5] [raid4] 
md0 : active raid5 sdd1[3] sda4[0] sdc1[2] sdb1[1] 
      879100608 blocks level 5, 64k chunk, algorithm 2 [4/4] [UUUU]
# mdadm --grow -z 293033472  --backup-file=/root/grow_md0_size.bak /dev/md0
mdadm: component size of /dev/md0 has been set to 293033472K
# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] 
md0 : active raid5 sdd1[3] sda4[0] sdc1[2] sdb1[1] 
      293033472 blocks level 5, 64k chunk, algorithm 2 [4/4] [UUUU]

mdadm --grow -z 293033472 --backup-file=/root/grow_md0_size.bak /dev/md0

mdadm --grow -c 512 --backup-file=/root/grow_md0_rechunk.bak /dev/md0

Of course, I didn't notice that the -z command changed the total array size to the number of blocks I specified, instead of setting it per-drive (as the man page says). So, thinking that I took off 64k from end of each drive (which should've been empty because FS was not resized yet), I kept on g[r]owing:

# mdadm --grow -c 512 --backup-file=/root/grow_md0_rechunk.bak /dev/md0

Since it was taking a whole day to do this, I thought I'd remount the FS and keep using it. No such luck:

# mount -oro /raid/
mount: wrong fs type, bad option, bad superblock on /dev/md0,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

# dmesg|tail
[...]
EXT4-fs (md0): bad geometry: block count 146516768 exceeds size of device (73258368 blocks)

# vim /var/log/messages
[...]
Jul 18 12:00:44 slon kernel: md0: detected capacity change from 900199022592 to 300066275328
Jul 18 12:00:44 slon kernel: md0: unknown partition table 

After re-chunking process finished, I set it to resize the chunks back the way they were before. When that is done, I'll try to resize the array back to the old size.
I don't think I'm THAT lucky, but there's a chance it'll work.

A major fuckup, indeed.