Sunday, February 14, 2016

Port Forwarding in Mythbuntu

My MythTV setup recently broke in an "interesting" way, and the fix I came up with is a bit involved ... so be warned, what follows is a major kludge.

Setup


Before explaining the pathology (and fix), I need to describe the setup. I have Mythbuntu installed on a PC whose only function is to serve as a digital video recorder (DVR). The PC connects to my home WiFi LAN, but the connection is occasionally unstable. I'm not sure if the problem lies with the USB WiFi modem, a driver, or some obscure setting.

Both the lone MythTV back end and the lone MythTV front end run on the PC, with the back end configured to use a static IP address. When watching recordings, I use MythMote on my (Android) phone as a remote control. MythMote connects to the back end via WiFi. Whatever the issue is with the WiFi connection on the PC, it has generally not affected MythMote.

Problem


I booted the machine one day and discovered that two recordings scheduled for the previous night had not occurred. Moreover, the front end was repeatedly telling me that the back end was off line ... even after I restarted the back end. Apparently the WiFi connection had flaked out (despite the network being up and the IP address being valid). With the MythTV box off line, the front end could not communicate with the back end, even though they're on the same machine.

Solution


A DVR that cannot be depended upon to record is not much of a DVR, so the top priority was to eliminate the reliance on the uncertain WiFi connection. I switched the IP address for the back end to the localhost address (127.0.0.1). As long as the PC manages to wake up in time, the back end should (hypothetically) start and record.

The one problem with this change is that it effectively disconnects MythMote. The answer to that is port-forwarding, which I implemented as follows:
  1. Download and install the rinetd package from the Canonical repositories.
  2. Edit the configuration file (/etc/rinetd.conf) to forward traffic on the static IP address to localhost. More specifically, I added the following forwarding rule (editing the file as root):

    192.168.1.68 6546 127.0.0.1 6546

    This forwards incoming traffic on port 6546 (the port used by the back end) at address 192.168.1.68 (the fixed IP address assigned to the MythTV machine in my LAN) to the same port on the local host address (where the back end is now listening).
  3. The installer adds the rinet daemon to the set of programs that load automatically at boot. In my case, it showed up in /etc/rc1.d. Unfortunately, even though the daemon started, it failed to redirect MythMote traffic until it was restarted from a terminal. I suspect that it was loading before something else when it needed to load after that something else, though I have no idea what the something else was. My next step was to delete the line that automatically loads it at boot. On my box, this meant running

    sudo rm /etc/rc1.d/K20rinetd

  4. I then created a two-line script to manually run the daemon:
    #!/bin/bash
    gksudo /etc/init.d/rinetd restart
    The specific name for the script (I used restart_rinetd.sh) and location are unimportant. I probably could have used the "start" command rather than the "restart" command, but this works (and maybe defends against the possibility that the daemon is already running but for some reason not connecting). I made the script executable with

    chmod +x restart_rinetd.sh

  5. Finally, I set the script up to start whenever I log in. Starting from the Applications menu (the main menu in Mythbuntu), I navigated to Applications > Settings > Session and Startup > Applications Autostart, clicked the Add button, typed in a rather arbitrary name and description, and used the file chooser to locate and select my new script file. After that, it was OK, Close and restart the machine to test it.

Result


So far, at least, it works. When the machine boots up, I'm presented with a password input box. Whether I respond or not, the back end starts, so timed recordings should still work even if I'm not using the front end at recording time (and therefore not present to answer the password challenge). Once I supply my password (and sit through a small but harmless delay recognizing it), I'm into the front end, and MythMote is able to connect and function properly.

Update: That was stupid of me. The rinetd program can be executed by any user, not just root, so the use of gksudo (and ensuing password entry) was utterly pointless. I edited gksudo out of the script, and now startup works as it originally did: the back end and front end both start automatically, and I wind up in the front end without any intervention on my part.


Although I only have one front end (on the same machine), this should hypothetically allow someone to use the 127.0.0.1 address for the back end and still connect a remote front end, provided that they can figure out a way either to answer the password challenge or to get the script to run with root privileges without needing a password. One possibility (which I have not tested, since I don't have a remote front end) would be to have a script on the remote front end machine connect to the back end via ssh and start the daemon.