Tinc App

User interface

The application is shipped with a graphical user interface for convenient network selection, network state monitoring and configuration bootstrapping. It is not meant to replace textual configuration file editing.

Start screen

The start screen lists all configured tinc networks within the application's directory, allowing the user to easily connect to any of those. Permission and passphrase entry dialogs may appear upon network selection, if such input is necessary.

Configuration screen

Paths to the application's configuration and log directories, as well as tinc binaries are displayed on top of the configuration screen. It also allows creating new named tinc networks, joining existing ones via invitation URLs, and facilitates key management by providing a way to protect tinc private keys using an optional passphrase.

Status screen

The status screen displays the currently active network and its interface configuration, and lists all known nodes and subnets within said network. Selecting a node shows more detailed information about it and its current reachability.

Log screen

The log screen shows the activity of the currently running tinc daemon in real time, displaying the last logged events.


The configuration directory, located on the world-readable external storage of the device at the path displayed on the configuration screen, contains the configuration of the underlying tinc daemon, alongside network interface configuration files. Each tinc network with its network interface configuration file (network.conf) must be contained within its own subdirectory.

The overall directory structure is as follows:

[configuration directory]
└── [netname...]
    ├── network.conf
    ├── tinc.conf
    ├── rsa_key.priv
    ├── ed25519_key.priv
    └── hosts
        └── [host config files...]

tinc daemon

The tinc daemon and networks can be configured as they would be on other platforms through the same files, nonetheless with some specificities to the Android platform, which are as follows:

  • The tinc daemon will be unable to listen for incoming connections on the standard port (655). Another unprivileged port (>1023) must therefore be chosen with the Port parameter in the current host's file in the hosts directory. This is indeed automatically done when generating a new configuration with the tinc control command.

  • The underlying virtual networking device is automatically set dynamically by the Android API. Hence, no Device or DeviceType must be set in the configuration.

  • This underlying network interface operates on the Internet layer and will only accept IP packets. The tinc daemon must therefore be configured with Mode = router.

  • The startup nets.boot file is ignored. Tinc VPN connections can be controlled via Android Intents instead.

  • No hook script (i.e. {tinc,host,subnet}-{up,down}) can be executed. Network configuration must be done statically through the network.conf file.

Network interface

The network.conf file is used to configure the network interface, allowing to set parameters such as the IP address, routes and DNS servers to use. Android applications authorised/forced to use/bypass the VPN can also be specified in this file.

The configuration is done at VPN connect time, and it is not possible to alter the parameters of the network interface while the VPN is active. This is a major difference with hook scripts used by tinc on other platforms.

The file consists of assignment lines in the form of Key = value pairs, which can be repeated multiple times in order to specify multiple values. Lines beginning with # are treated as comments.

Configuration keys (exposed from the underlying API) are:

Address = [CIDR formatted IP address]
Adds a network address to the VPN interface. Both IPv4 and IPv6 addresses are supported. At least one address must be set. Adding an address implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to be routed over the VPN.
Route = [CIDR formatted IP range]
Adds a network route to the VPN interface. Both IPv4 and IPv6 routes are supported. Adding a route implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to be routed over the VPN.
DNSServer = [IP address]
Adds a DNS server to the VPN connection. Both IPv4 and IPv6 addresses are supported. If none is set, the DNS servers of the default network will be used. Adding a server implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to be routed over the VPN.
SearchDomain = [domain]
Adds a search domain to the DNS resolver.
AllowApplication = [application package name]
Adds an application that are allowed to access the VPN connection. If this parameter is set, only applications added through this method (and no others) are allowed access. Else, all applications are allowed by default. If some applications are added, other, un-added applications will use networking as if the VPN wasn't running. A VPN may have only a set of allowed applications OR a set of disallowed ones, but not both.
DisallowApplication = [application package name]
Adds an application that are denied access to the VPN connection. By default, all applications are allowed access, except for those denied through this method. Denied applications will use networking as if the VPN wasn't running. A VPN may have only a set of allowed applications OR a set of disallowed ones, but not both.
AllowFamily = [2|10]
Allows traffic from the specified address family. By default, if no address, route or DNS server of a specific family (IPv4 or IPv6) is added to this VPN, then all outgoing traffic of that family is blocked. If any address, route or DNS server is added, that family is allowed. This method allows an address family to be unblocked even without adding an address, route or DNS server of that family. Traffic of that family will then typically fall-through to the underlying network if it's supported. Family must be either AF_INET (for IPv4) or AF_INET6 (for IPv6), for which integer values are respectively 2 and 10.
AllowBypass = [true|false]
Allows all apps to bypass this VPN connection. By default, all traffic from apps is forwarded through the VPN interface and it is not possible for apps to side-step the VPN. If this parameter is set to true, apps may send/receive directly over the underlying network or any other network they have permissions for.
Blocking = [true|false]
Sets the VPN interface's file descriptor to be in blocking/non-blocking mode. By default, the file descriptor is non-blocking.
MTU = [integer value]
Sets the maximum transmission unit (MTU) of the VPN interface. If it is not set, the default value in the operating system will be used.
ReconnectOnNetworkChange = [true|false]
Forces tinc to immediately reconnect to all uplinks on network change. Enabled by default.

Paths and utilities


The log files of the tinc daemon (tinc.$netname.log) and the wrapper application (tincapp.log) are stored on the device's external storage and are accessible to the user. The verbosity of the logging can be set by using the LogLevel configuration option in tinc.conf.

tinc and tincd binaries

The tinc control utility and the tinc daemon executables binaries can be used by a shell user on the device. The control socket file of the running underlying daemon is located within the private directory of the application, and is thus only accessible on debug releases or with root access.

Automatic connection management

Connections to tinc networks can be initiated and stopped automatically on system startup and from other Android applications.

Always-on VPN

The always-on VPN feature available on Android Nougat and newer allows a tinc network connection to be restored after a device restart. This option can be enabled through the system settings, under the "Network & Internet" / "VPN" categories.

Any necessary passphrase for the current network will be saved and will not be asked for again on connection restoration.

If the VPN stops working due to an error or a demand of the user through the application's user interface, and if the feature is enabled, a warning notification will be shown until reconnection.

Intent API

Tinc App allows connections to be managed through Intents, allowing flexible scripting and automation from third-party applications.

A new connection can be instantiated by starting an activity for the action org.pacien.tincapp.intent.action.CONNECT, alongside with an opaque data URI following the pattern tinc:$netname#$passphrase, where $netname is the name of the tinc network to connect to, and $passphrase an optional passphrase to unlock private keys. Connecting to a tinc network will terminate any other existing VPN connection.

If the system VPN permission has not been already granted or has been revoked, a confirmation dialog will be displayed. If the private keys are encrypted but no passphrase has been provided in the Intent data, an input dialog asking for such passphrase will be displayed as well.

A currently active tinc connection can be terminated by starting an activity for the action org.pacien.tincapp.intent.action.DISCONNECT. Disconnecting through an Intent will not drop the system VPN permission.