Skip to content

External Network Access

Will Cooke edited this page Apr 4, 2017 · 78 revisions

When you're ready to access MythTV content from outside your home network, you can set up external access according to the steps outlined here.

Contents

Security
Apache HTTP Proxy
SSH Tunneling
Dynamic IP Retrieval
Disclaimer

Security

It goes without saying that security is paramount when exposing media services to the outside world. You'll want to set up access controls before opening any holes in your firewall.

Apache HTTP Proxy

The preferred method for securing access to backend services is to set up digest authentication on an Apache web server and then configure proxying for MythTV services. This way you can access MythTV, Mythling and MythWeb through the same host:port, and although your credentials are passed securely you avoid the overhead of encrypting all HTTP traffic.

The steps for setting up digest authentication and proxying are as follows:

  1. Install Apache on your backend server according to the instructions for your distribution.

  2. Add a user in the httpd-passwords file:

    • If httpd-passwords already exists:
      sudo htdigest /etc/httpd/conf/httpd-passwords MythTV <user>
    • Otherwise:
      sudo htdigest -c /etc/httpd/conf/httpd-passwords MythTV <user>
  3. Configure Apache proxying with digest authentication for the desired MythTV services.*

    • In Apache 2.4 this can be accomplished by adding a proxy.conf file in the directory /etc/httpd/conf.modules.d with the following content. (Note: the ProxyPass paths must be set exactly as illustrated until https://github.com/oakesville/mythling/issues/11 is implemented).
      <IfModule mod_proxy.c>
      ProxyRequests Off
      ProxyTimeout 60
      ProxyStatus On
      ProxyPreserveHost On
      
      <Proxy *>
          Order allow,deny
          Allow from all
          AuthType Digest
          AuthName "MythTV"
          AuthUserFile /etc/httpd/conf/httpd-passwords
          Require valid-user
          Satisfy All
      </Proxy>
      
      ProxyPass /Content http://localhost:6544/Content
      ProxyPass /Dvr http://localhost:6544/Dvr
      ProxyPass /Guide http://localhost:6544/Guide
      ProxyPass /Myth http://localhost:6544/Myth
      ProxyPass /Status http://localhost:6544/Status
      ProxyPass /Video http://localhost:6544/Video
      ProxyPass /StorageGroup http://localhost:6544/StorageGroup
      ProxyPass /mythling-epg http://localhost:6544/mythling-epg
      
    • Test proxy access and authentication in your browser:
      http://<server_ip>/Status/GetStatus
      Currently MythTV services must be proxied at the root path, but there's an upcoming enhancement to support proxying through a subpath: https://github.com/oakesville/mythling/issues/11
  4. If you've set up Mythling Media Services or MythWeb you should secure these as well.

    • Here's an example directive for enforcing digest authentication for general access in /etc/httpd/conf/httpd.conf:*

      <Directory "/var/www/html">
          Order          allow,deny
          Allow          from all
          AuthType       Digest
          AuthName       "MythTV"
          AuthUserFile   /etc/httpd/conf/httpd-passwords
          Require        valid-user
          AllowOverride  None
          Satisfy        All
      </Directory>
      
  5. Test internal access through Mythling with digest authentication.

    • Under Mythling's Connection preferences, set the MythTV Service Port to port 80, or whatever port you've configured Apache to use. If you're hosting Mythling or MythWeb as well, set the Backend Web Server port to the same value.
    • Under Credentials set the MythTV (and optionally the Backend Web) Auth Type to Digest, and enter the user/password you added using htdigest above.
    • View your media in Mythling to verify access.
  6. Once you've confirmed that digest authentication is enforced, the final step is to set up port forwarding on your router.* This opens up your web server to the Internet on the designated port, and forwards traffic to your backend server. The procedure for this should be spelled out in your router's documentation.

SSH Tunneling

SSH Tunneling is another option for allowing Mythling to connect to the service endpoints from outside your firewall. The main reason to consider SSH tunneling would be if you don't have Apache installed. The steps for setting up SSH tunneling between your device and your backend host are as follows.

  1. Make sure SSH is installed and enabled on your backend server.

  2. Configure port forwarding on your router to allow outside traffic on port 22 to be directed to your backend server.*

  3. Install ConnectBot or another SSH client on your device.

  4. Set up a tunneling connection through your SSH client. In ConnectBot:

    • Select "ssh" in the protocol dropdown, and enter the @: for logging in to your backend server. (The SSH port is almost always 22).
    • Acknowledge the server identity disclaimer and enter your password to connect. After successfully connecting, type "exit" to close the session.
    • On the ConnectBot main screen, long-press the new connection and select "Edit port forwards". Tap the menu and select "Add port forward".
    • Enter a nickname, select Local as the type, set the source port to something arbitrary and for destination enter <backend_ip>:6544.
  5. Test access to the MythTV services from a browser on your device:

  6. For access in Mythling, under Network preferences set the External Backend Host to "localhost", and under Connections set the MythTV Service Port to the same port you accessed from your browser in step 5.

  7. If you've installed Mythling Media Services or MythWeb, set up a separate SSH tunneling connection to access them. Then under Network preferences enter localhost as the External Backend, and under Connections enter the Web Port configured for this new SSH tunneling connection.

Dynamic IP Retrieval

If your ISP gives you a dynamically-assigned IP address, you may find that this changes frequently enough to interfere with you ability to stream content externally. When your IP has been changed and you're outside your network there's usually no easy way to determine the new address.

To handle this Mythling allows you to designate a URL where the IP address can be retrieved (see Network preferences). Note: this doesn't work with SSH tunneling since the backend host known to Mythling is "localhost". Mythling expects the return value from a GET request against this URL to be a plain-text string containing a valid IP address.

  • If you have a hosted site that supports Java servlets, one way to implement this is to deploy a simple servlet for getting and setting your IP Address:
package com.example.servlet;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class IpRetrieval extends javax.servlet.http.HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
        if ("true".equals(req.getParameter("update")))
            writeIp(req.getRemoteAddr());
        resp.setContentType("text/plain");
        resp.getWriter().print(readIp());
    }

    protected void writeIp(String ip) throws IOException {
        FileWriter writer = null;
        try {
            writer = new FileWriter(getServletContext().getRealPath(
                "/ip/ip.txt"));
            writer.write(ip);
            writer.flush();
        } finally {
            if (writer != null)
                writer.close();
        }
    }
    
    String readIp() throws IOException {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(getServletContext()
                .getRealPath("/ip/ip.txt")));
            return reader.readLine();
        } finally {
            if (reader != null)
                reader.close();
        }
    }
}
  • Then on your backend server you can schedule a cron job to periodically POST the IP address assigned by your ISP. Here's a wget request against the above servlet that updates the ip (assuming you've mapped the IpRetrievalServlet to /ip/*:
wget http://server:port/ip?update=true

Disclaimer

* Use caution when configuring Apache and allowing public Internet traffic through your router/firewall. The examples posted here are for illustration only. You assume full responsibility for any changes affecting the security of your personal network. If you have doubts about the meaning of the directives in the examples, refer to the [Apache documentation] (http://httpd.apache.org/docs/2.4/mod/core.html). If you're unsure about the port forwarding setup for your router, consult its documentation or enlist guidance from the manufacturer's customer support.