ADR
This is base on the template in Documenting architecture decisions - Michael Nygard.
Network-external access to the system
Status
Proposed - This needs to be currently considered for easiness of implementation of app wireframes and API structure, but should only be tackled in sysctl implementation phase. This issue opens the discussion. An eventual decision should be documented in the assets repository inside of the docs/arquitecture_decision_records folder.
Context
Edgebox needs to provide functionality for remote access. This would allow the mobile app to connect to the box when outside of the network where it is attached to.
Other EdgeApps, especially the ones that provide web/api endpoints and services can benefit from this. Conversely, there should be a way to activate and deactivate external access to independent features and services.
Some minimum requirements for easy usability:
- I should be able to access my services from any computer in the world.
- I should be able to punch in an easy-to-remember web address like access.edgebox.io/myserver. This means all standard HTTP/HTTPS ports should be used!
- All transmission of my content should be encrypted.
- Moving houses or ISP's should not break the remote access capabilities.
Problems with home internet connections
When talking about possibly complicated network connections that need to act in a reliable way, we should strive for as few dependencies on external factors as possible. This is our objective here in order for people to be able to consider Edgebox a reliable possible replacement for SaaS services.
Home networks don't help in our quest. Some problems these type of connections have are:
May not have a static IP
Very rarely does a home connection come with a static IP. Getting a static IP typically results in extra charges, and would require updating the DNS record if anything changes. The solution is to use a dynamic DNS service that solves both these issues and is a consideration, but we still end up with some problems to solve.
May not have control of the router
Port forwarding needs to be set up on your router so incoming connections are forwarded to the home server. However, you may not have full control over the router to set up these rules. Many routers will also take the default HTTP/HTTPS ports for their own services, leaving you with non-standard port numbers for everything else.
May not be able to get incoming connections
Finally, once we’ve sorted out everything above, you may not be able to get incoming traffic to reach your house! As a result of the IPv4 address shortage and ISP firewalls, incoming connections don’t always work. Never fear, we can still tunnel traffic through the internet with the help of another computer with a more accessible connection.
So for this, we need to consider an option to allow a direct tunnel between a network-external machine and the box.
Decision
What is the change that we're proposing and/or doing?
Implement a system for remote access that gives as little friction as possible for the user. Considering two options, one for direct access through DDNS techniques, and/or a tinc based option.
Using Tinc to access Edgebox through a tunneled connection
Tunnelling out
![tunneling_out](https://user-images.githubusercontent.com/1270431/100101041-fca04780-2e61-11eb-8631-6ee67390e262.png)
The concept of using a tunnel is pretty simple. We may not be able to get incoming connections to the Edgebox, but the box itself can setup an outgoing tunnel connection with some other machine on the internet. This other machine can be accessed from anywhere and forward connections through the tunnel to get to the home server.
The other machine
To meet these requirements, another machine needs to be involved. There are services dedicated to providing remote access to networks. These work well but require some sort of client software configuration to join this virtual network, which fundamentally might not work in every computer, not meeting one of the requirements above.
Other than that, there are virtual private network (VPN) services that provide port forwarding. However, it’s unlikely you’d be able to use the HTTP and HTTPS ports.
As part of our cloud helper services for Edgebox, this should possibly be built by ourselves, providing frictionless configuration and usability. But still adhering to our openness filosofy, we should provide clear documentation and path for users to be able to implement this themselves without resorting to a cloud service provided by the company operating the development of Edgebox.
The cloud service provided by Edgebox for frictionless setup should basically run multiple versions of the setup described below (one for each Edgebox using the service). This might call for Docker-based management of multiple NGINX + tinc instances running in a scalable solution. It should be possible, but for feasibility effects, we will describe the process with 1 instance.
Reverse SSH Tunnel
A common way to get remote access through a firewall is with a Reverse SSH Tunnel. This is easy to set up and works well, but I discovered that HTTP based services through the tunnel run extremely slow. The most likely reason for this is that both SSH and HTTP use the TCP protocol to transmit data over a network. TCP ensures a reliable connection with built-in error checking and transmission control but this comes at a cost of speed. Running HTTP through the SSH tunnel is performing these error checks twice, resulting in much slower speeds.
The answer is to switch to something UDP based. UDP is much faster because it’s just packets sent straight over the network without error checking or flow control. A UDP based tunneling solution means that only the HTTP layer is performing these extra tasks.
tinc VPN
The tinc VPN software might the answer that meets these requirements. It can be used to create virtual networks between computers. It utilizes UDP so runs quickly, all traffic is encrypted and has a status re-check routine so can work moderately well even on unreliable connections.
tinc is not available originally for arm architecture (which we need for our project on Edgeboxe's side), but there is a docker image (rpi-tinc) that supports Raspberry Pi
Pretty URL’s & Proxying connections
With tinc working, all the services on Edgebox can be accessed through a local IP on the cloud server, like 10.0.0.2:32400 for Plex. Time to turn that into something nice like acess.edgebox.io/myserver/plex!
The subdomains point to the cloud server’s IP address. The cloud server has the NGINX server running with the official NGINX Docker image. NGINX is set up as a proxy server to the home server’s IP address using the NGINX documentation, meaning external traffic is forwarded through the tinc link to Edgebox.
HTTPS should be used to ensure all data transport is encrypted. This requires valid SSL certificates which can be obtained for free with Let’s Encrypt through their automated verification process. To set up Let’s Encrypt to automatically renew certificates, a solution like docker-letsencrypt-manager and shared the volumes with the NGINX containers will work as it was previously tested. A very useful tool when working with HTTPS is SSL Labs’ SSL Test.
Example usage trial with Plex
Finally, setting up something like Plex through the tinc tunnel and as a preliminary test, this Gist was used to help with the NGINX configuration, and set up a custom URL in Plex settings, like https://access.edgebox.io/myserver/plex:443 (the port number must be explicitly defined for it to work). This works well, but sometimes some difficulties arose when Chromecasting from Android while on an external network. Some more tests should then be done but overall this setup seems to work.
[TBD]Using some DDNS service to directly access Edgebox through WAN IP
Following something on the lines of https://github.com/dprandzioch/docker-ddns might be able to provide the same kind of access to the box (but also possibly to other devices in the network), avoiding a whole tunneling setup, but unfortunately still with the need to manage IP records. ** This may also require configuration on the user's router, which is not desirable. **
[TBD] Consequences
What becomes easier or more difficult to do because of this change?
Multiple considerations to be taken, especially in the case of tinc.
Research Links