This page describes the architecture of Yona.
High level overview
On network level, this is how it looks like:
Initial support is limited to mobile devices. These devices will access the internet through a VPN tunnel that is terminated on the web traffic classification server (SmoothWall). The server will not filter, in the sense of blocking sites, but just classify the sites. This classification will happen for HTTP and HTTPS traffic, see this page. The requests will be passed on to the target web server. For requests that in categories of interest to Yona, the classification server will post a message on a queue to the Yona server. The Yona server is responsible for maintaining the user and buddy administration and to inform users about events that conflict the goals defined by the users. The Yona app on the device interacts with the Yona server to see buddy events and everything supported by Yona.
Subsequent sections zoom in on the app, the web traffic classification server and the Yona server.
The mobile app is the only user interface provided for Yona. There are no plans to provide a web site. The mobile app has the following high level responsibilities:
- Provide the user interface for all features provided to Yona users
- Configure the VPN connection
- Reconnect the VPN in case it disconnects
- Send a request to the Yona server to inform the buddy in case:
- The user uninstalls
- The user disables the app
- The user disables or otherwise hampers the VPN connection
The app generates and stores a key in the secret storage of the app, that is required for all interactions with the server.
Web traffic classification server
The heart of this server is SmoothWall. Kliksafe uses this product to filter requests. For Yona, it will be deployed as a classification server. The SmoothWall server provides us with the following features:
- VPN server
- Classification engine
- Man-in-the-middle proxy for HTTPS servers. See this page.
Every request passed through the filter engine is logged in the DansGuardian log. Given the constraints of the Linux OS of the SmoothWall server, we will use a Perl script to filter the events that are of relevance to Yona and post these on the queue to the Yona server. The log file (
access.log) is normally written in a file. Instead of the file, we will create a named pipe and have the Perl script read from it. See an example log file parser here. The named pipe approach is chosen for two reasons: it is a very efficient mechanism that does not required disk reads/writes and it prevents from storing sensitive data.
The Perl script will read all SmoothWall log events and match them with a list of Yona-relevant web site categories. If the category is relevant, a message with the relevant data is posted on the queue to the Yona server. Otherwise, the message is discarded.
The Yona server is responsible for:
- Providing the web services that back the mobile app
- Administration of users and buddy relationship
- Producing notifications in case users access websites that conflict their objectives
Given the objective of Yona to help people that "do the very thing they hate" (Romans 7:15), the system by nature stores sensitive information, so security is a prime concern. For an overview of the various design alternatives considered, consult the page Register a goal conflict. These are the design goals:
- Private information about a user (buddies, goals, devices, messages from buddies, messages about goal conflicts, etc.) should be inaccessible to everyone, including those that have administrative access to the systems
- It should be impossible to build a quantitative understanding of how well a user acts against his own goals, even when having administrative access to the systems
The server design uses a combination of public-key encryption and symmetric-key encryption to accomplish these goals. Symmetric-key encryption is used to encrypt all private information of the user: buddies, goals, devices, etc. Public-key encryption is used to implement a secure messaging system to deliver messages from buddies and messages from the web traffic classification. Every user has two "message boxes", comparable to a classic mailbox with lock:
Everyone can drop a message in the box, but you need the key to take a message out of it. Every use has two of these. One is publicly linked to the user account, so it's technically possible to send a message to a user if their identity is known. The other message box is linked indirectly and used for messages related to web traffic. When a user is provisioned, a VPN account is created for them. The user name of this VPN account is a UUID (named accessor ID) that cannot be linked to a user, Through their private key, the user knows what their accessor ID. but without that private key, that link cannot be established. This can be depicted as follows:
The server maintains a little bit of unencrypted user information: their name, mobile number and a reference to their public message box. The other information is encrypted with the key that is stored on in the secure storage of the device (e.g. Android non-exported content provider). This encrypted data includes the buddy relationships, the defined goals and two private keys to access the two message boxes. Writing into the message boxes can be done through the public key (not depicted, to prevent confusion). For reading, the private key is required, which is part of the encrypted data of the user. The message box for direct messages is linked from the public data of the user, so given a user, it is possible to find the direct message box.
The anonymous message box is linked from the private data of the user, so only the user "knows" their anonymous message box. Besides this, the anonymous message box is also linked to the accessor object, which carries the same ID as the VPN user name. Thus the analysis engine (see below) knows where to post messages when a goal conflict is detected for a given VPN account.
The Yona server has a simple layered architecture:
- REST. This layer exposes the RESTful API used by the mobile app. Follows HATEOAS and HAL (see primer here) to provide an efficient and convenient RESTful API. This layer is implemented through Spring HATEOAS.
- Services. The services are independent of the access technology (today REST, yesterday SOAP) and enable creating users, finding goals, etc. Services define the transaction boundaries and can depend on one another to fulfill their task. The services layer take Data Transfer Objects (DTOs) as inputs and outputs. These DTOs are annotated with Jackson annotations, so the REST layer can directly return the DTOs. The services layer is implemented with the Spring Framework.
- Entities. The entities layer hosts the domain model and the repositories. The implementation technology is JPA and Spring Data.