Tuesday, November 18, 2003

Reducing your exposure running DVArchive on linux

I recently got a ReplayTV 5040 for a steal on closeout at buy.com and just love it. One of the most attractive features is how it is network-aware by default and that the community has created some great free software for integrating with it. I have been using DVArchive to expand the capacity for recording without having to violate my ReplayTV warranty by hacking the hardware. DVArchive enables your PC to act as a software-based ReplayTV unit for replay, archival, vending photos, as well as playing recorded mpegs remotely on your PC.

However, I was horrified at the suggestion in the DVArchive FAQ that on UNIX "you must launch DVArchive as root" if you want to enable the functionality that allows serving shows back to your ReplayTV, or to other DVArchive programs running on your network. The real reason for this is that DVArchive (due to inflexible ReplayTV design) must bind to port 80 for ReplayTV units to access the HTTP server there that vends out the mpeg files. And to do this, you normally have to be root.

Well, you could just use sudo or worse, log in as root and run DVArchive as root. But, being a security person, this was not a pleasing thought.

So, I came up with a better way that runs DVArchive as an unprivileged user on the system. I do this by using port forwarding to forward connections to port 80 up to an alternate, unprivileged high port.

Fortunately, DVArchive allows you to specify a different TCP port to listen to instead of port 80. Now, it will bark at you that what you are doing is probably going to prevent ReplayTV units from accessing files on your DVArchive server but you can safely ignore these because you've got port forwarding up your sleeve.

1) Set that port to some open high TCP port under File -> DVArchive Properties... -> Server by changing the "Server Port" setting. I used 13198 in this example and in the attached startup script.

2) Install the attached startup script (see the Extended Entry text for the full script) as root to /etc/rc.d/init.d/dvarchiveforward

3) Edit dvarchiveforward and change MYIP to point to your IP address of your DVArchive server and change the IPTABLES binary location, if necessary.

4) On a RedHat 7.x - 9 system (or any other that has chkconfig) you can active this script at boot time by running (still as root):
/sbin/chkconfig --add dvarchiveforward

5) You can then check to make sure that this script was activated by running:
/sbin/chkconfig --list dvarchiveforward
You should see output like:

dvarchiveforward 0:off 1:off 2:on 3:on 4:on 5:on 6:off

6) Now, start this script so you don't have to wait for a reboot for it to work:

/sbin/service dvarchiveforward start

7) Check to see that the port forwarding entries were inserted correctly

/sbin/iptables -t nat -L

Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere yourhostname tcp dpt:http to:192.168.1.1:13198

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere yourhostname tcp dpt:http to:192.168.1.1:13198

8) Now, you can try accessing archived shows on your DVArchive server from your ReplayTV. All should work just fine.

Here is the /etc/rc.d/init.d/dvarchiveforward script:

#!/bin/sh
# dvarchiveforward -- script to enable port forwarding so that I can run DVArchive as
# a non-privileged user. Why doesn't firestarter let you do this kind of portfw
?
# chkconfig: 2345 06 95
# description: DVArchive port forward script by Jason Axley
#
export IPTABLES=/sbin/iptables
export MYIP=192.168.1.1
export MYPORT=13198
case "$1" in
start)
# This forwards local port 13198 to port 80 so that we don't have to run
# DVArchive as root to bind to port 80!
# doing this below doesn't work for connecting to localhost. Use the other entries instead
#$IPTABLES -t nat -A OUTPUT -d $MYIP -p tcp --dport 80 -j REDIRECT --to-ports $MYPORT
#$IPTABLES -t nat -A PREROUTING -d $MYIP -p tcp --dport 80 -j REDIRECT --to-port
s $MYPORT
$IPTABLES -A PREROUTING -t nat -p tcp -d $MYIP --dport 80 -j DNAT --to $MYIP:$MYPORT
$IPTABLES -A OUTPUT -t nat -p tcp -d $MYIP --dport 80 -j DNAT --to $MYIP:$MYPORT
break;
;;
stop)
$IPTABLES -t nat -F
$IPTABLES -t nat -X
break;
;;
reload)
$0 stop;
$0 start;
break;
;;
*)
echo "Usage: $0 {start | stop | reload}"
exit 1
;;
esac

5 comments:

  1. Thanks for a good concept. I've been looking for a way to do something like this, but hadn't happened on such an appropriate mechanism.
    I made a couple changes to the script for my use that you may be interested in:
    1) Get MYIP and MYPORT from DVArchive.XML instead of duplicating that information in the script. They're stored (by DVArchive v2.1, anyhow) at DVArchive/replayServer/IP and DVArchive/replayServer/port/@VALUE, respectively.
    I used a pipeline of xmln and perl, but any XML tools should work.
    MYIP=`$XMLN $DVARCHIVE_XML | perl -lne 'if ( /^\(IP$/ .. /^\)IP$/ ) { print $1 if /^-(.+)/ }'`
    MYPORT=`$XMLN $DVARCHIVE_XML | perl -lne 'if ( /^\(port$/ .. /^\)port$/ ) { print $1 if /^AVALUE\s+(.+)/ }'`
    2) On stop, delete just dvarchiveforward's rules from the nat table, instead of flushing all rules:
    RULE="-p tcp -d $MYIP --dport 80 -j DNAT --to $MYIP:$MYPORT"
    [... use $RULE in start's -A, as well ...]
    $IPTABLES -D PREROUTING -t nat $RULE
    $IPTABLES -D OUTPUT -t nat $RULE

    ReplyDelete
  2. Wow. Ain't open source great!
    Thanks for these changes. I'll roll them into my own copy. They make the script more universal and simplify configuration. Very nice!
    Look for the whole solution to appear in the DVArchive FAQ soon...
    -Jason

    ReplyDelete
  3. Thanks for these instructions. I've recently rebuilt my dvarchive serving linux box and decided I didn't want to run dvarchive as root any more. I found your instructions via the DVA FAQ. They nearly worked on the first try. My only error was forgetting to chmod +x on the dvarchiveforward script before doing service dvarchivefoward start.

    ReplyDelete
  4. Jason,
    I've been using DVArchive with Redhat 9 since 2003. My family loves it. I would like to implement your most excellant dvarchiveforward script but I have failed to figure out where the "attached startup script" is located on this web page referred by DVArchive FAQ. I tried searching the blog with no results. I cannot cut and paste the listing on the web page due to its right hand column cutting off the text. Do you mind inserting a link to the script on the web page or possibly emailing it to me? Thank you.

    ReplyDelete