# [[OpenNDS]] Forwarding [[Authentication]] Service (FAS)
## Notes
### Implementation via webserver / daemon run on router
- Option 1: Use `fasremoteip` to set ip and `fasport` to set port
- Option 2: Use `fasremotefqdn` (Fully Qualified Domain Name) to point to webserver (e.g. `<daemonname>.local`)
### Implementation via script on router
- Use `faspath` path from the FAS Web Root to the FAS login page
### Shared Hosting Server
Sounds like it's what we need?
![[#Using a Shared Hosting Server for a Remote FAS]]
### Trying the default scripts
#### Differentiation
- [[#fas-hid.php]]: for low-resource routers
- "fas-hid is specifically targeted at local systems with insufficient resources to run PHP services, yet facilitate remote FAS support without exposing the client token or requiring the remote FAS to somehow access the local ndsctl."
- [[#fas-aes php]]: example webserver also run locally on the router, using [[AES]] to encrypt the client token while in transmission
- [[#fas-aes-https php]]: example webserver that can be run remotely in addition to locally on the router; use of [[HTTPS]] is enforced.
- We probably want to use this one due to the use of [[HTTPS]]. But try to get [[#fas-aes php]] working first.
# Docs
https://opennds.readthedocs.io/en/stable/fas.html
## Overview
openNDS (NDS) has the ability to forward requests to a third party authentication service (FAS). This is enabled via simple configuration options.
These options are:
1. `fasport`. This enables Forwarding Authentication Service (FAS). Redirection is changed from the default ThemeSpec to a separate FAS. The value is the IP port number of the FAS.
2. `fasremoteip`. If set, this is the remote ip address of the FAS, if not set it will take the value of the NDS gateway address.
3. `fasremotefqdn` If set, this is the remote fully qualified domain name (FQDN) of the FAS
4. `faspath`. This is the path from the FAS Web Root (not the file system root) to the FAS login page.
5. `fas_secure_enabled`. This can have four values, “0”, “1”, “2” or “3” providing different levels of security.
6. `faskey` Used in combination with fas_secure_enable level 1, 2 and 3, this is a key phrase for NDS to encrypt data sent to FAS.
### Note
FAS (and Preauth/FAS) enables pre authentication processing. NDS authentication is the process that openNDS uses to allow a client device to access the Internet through the Firewall. In contrast, Forward Authentication is a process of “Credential Verification”, after which FAS, if the verification process is successful, passes a request to NDS for access to the Internet to be granted for that client.
## Using FAS
Note: All addresses (with the exception of `fasremoteip`) are relative to the client device, even if the FAS is located remotely.
When FAS is enabled, [[OpenNDS]] automatically configures firewall access to the FAS service.
The FAS service must serve a splash page of its own to replace the openNDS served output of the default ThemeSpec script. For `fas_secure_enable` “0”, “1”, and “2” this is enforced as http. For `fas_secure_enable` level “3”, it is enforced as https.
- [ ] We will need to enable [[HTTPS]]
Typically, the FAS service will be written in PHP or any other language that can provide dynamic web content.
FAS can then generate an action form for the client, typically requesting login, or self account creation for login.
The FAS can be on the same device as openNDS, on the same local area network as NDS, or on an Internet hosted web server.
## Security
**If FAS Secure is enabled** (Levels 1 (default), 2 and 3), the client authentication token is kept secret at all times. Instead, faskey is used to generate a hashed id value (hid) and this is sent by openNDS to the FAS. The FAS must then in turn generate a new return hash id (rhid) to return to openNDS in its authentication request.
- **If set to “0”** The FAS is enforced by NDS to use **http** protocol. The client token is sent to the FAS in clear text in the query string of the redirect along with authaction and redir. This method is easy to bypass and useful only for the simplest systems where security does not matter.
- **If set to “1”** The FAS is enforced by NDS to use **http** protocol. A base64 encoded query string containing the hid is sent to the FAS, along with the clientip, clientmac, gatewayname, client_hid, gatewayaddress, authdir, originurl, clientif and custom parameters and variables.
- Should the sha256sum utility not be available, openNDS will terminate with an error message on startup.
- **If set to “2”** The FAS is enforced by NDS to use **http** protocol.
- clientip, clientmac, gatewayname, client_hid, gatewayaddress, authdir, originurl and clientif are encrypted using faskey and passed to FAS in the query string.
- The query string will also contain a randomly generated initialization vector to be used by the FAS for decryption.
- The cipher used is “AES-256-CBC”.
- The “php-cli” package and the “php-openssl” module must both be installed for fas_secure level 2.
- openNDS does not depend on this package and module, but will exit gracefully if this package and module are not installed when this level is set.
- The FAS must use the query string passed initialisation vector and the pre shared fas_key to decrypt the query string. An example FAS level 2 php script (fas-aes.php) is stored in the /etc/opennds directory and also supplied in the source code. This should be copied the the web root of a suitable web server for use.
- **If set to “3”** The FAS is enforced by openNDS to use **https** protocol. Level 3 is the same as level 2 except the use of https protocol is enforced for FAS. In addition, the “authmon” daemon is loaded. This allows the external FAS, after client verification, to effectively traverse inbound firewalls and address translation to achieve NDS authentication without generating browser security warnings or errors. An example FAS level 3 php script (fas-aes-https.php) is pre-installed in the /etc/opennds directory and also supplied in the source code. This should be copied the the web root of a suitable web server for use.
- **Option faskey has a default value.** It is recommended that this is set to some secret value in the config file and the FAS script set to use a matching value, ie faskey must be pre-shared with FAS.
## Example FAS Query strings
(See docs)
### Example scripts
Full details of how to use FAS query strings can be seen in the example scripts, fas-hid.php, fas-aes.php and fas-aes-https.php
## Custom Parameters
Custom Parameters are primarily intended to be used by remote configuration tools and are generally useful for passing static information to a remote FAS.
A list of Custom Parameters can be defined in the configuration file. Once a custom parameter is defined in the configuration, its value will be fixed.
Parameters must be of the form param_name=param_value and may not contain white space or single quote characters.
Custom parameters are added to the base64 encoded query string when FAS level 1 is set or the basic login option is used. Note the basic login option is a special case of FAS level 1 running a ThemeSpec script.
Custom parameters are added to the encrypted query string when FAS levels 1, 2 and 3 are set.
The fas_custom_parameters_list option in the configuration file is used to set custom parameters. This is detailed in the default configuration file.
It is the responsibility of FAS to parse the query string for the custom parameters it requires.
## Network Zones - Determining the Interface the Client is Connected To
(See docs)
## After Successful Verification by FAS
If the client is successfully verified by the FAS, FAS will send the return hash id (rhid) to openNDS to finally allow the client access to the Internet.
## Post FAS processing
(See docs)
## Manual Access of NDS Virtual URL
If the user of an already authenticated client device manually accesses the NDS Virtual URL, they will be redirected back to FAS with the “status” query string.
This will be of the form:
`http://fasremoteip:fasport/faspath?clientip=[clientip]&gatewayname=[gatewayname]&status=authenticated`
FAS should then serve a suitable error page informing the client user that they are already logged in.
## Running FAS on your openNDS router
FAS has been tested using uhttpd, lighttpd, ngnix, apache and libmicrohttpd.
### Running on OpenWrt with uhttpd/PHP
- A FAS service may run quite well on uhttpd (the web server that serves Luci) on an OpenWrt supported device with 8MB flash and 32MB ram but shortage of ram will be an issue if more than two or three clients log in at the same time.
- For this reason a device with a **minimum** of 8MB flash and 64MB ram is recommended.
- A device with 16MB flash or greater and 128MB ram or greater is recommended as a target for serious development.
- Although port 80 is the default for uhttpd, it is reserved for Captive Portal Detection so cannot be used for FAS. uhttpd can however be configured to operate on more than one port.
- We will use port 2080 in this example.
- Install the module php7-cgi. Further modules may be required depending on your requirements.
- To enable FAS with php in uhttpd you must add the following lines to the /etc/config/uhttpd file in the config uhttpd ‘main’ or first section.
- `list listen_http 0.0.0.0:2080`
- `list interpreter ".php=/usr/bin/php-cgi"`
- The two important NDS options to set will be:
1. `fasport`. We will use port 2080 for uhttpd
2. `faspath`. Set to, for example, /myfas/fas.php, your FAS files being placed in /www/myfas/
## Using a Shared Hosting Server for a Remote FAS
A typical Internet hosted **shared** server will be set up to serve multiple domain names.
To access yours, it is important to configure the two options:
1. fasremoteip = the **ip address** of the remote server **AND**
2. fasremotefqdn = the **Fully Qualified Domain name** of the remote server
## Using a CDN (Content Delivery Network) Hosted Server for a Remote FAS
(Not needed)
## Using the FAS Example Scripts (fas-hid, fas-aes.php and fas-aes-https.php)
These three, fully functional, example FAS scripts are included in the package install and can be found in the /etc/opennds folder. To function, they need to be copied to the web root or a folder in the web root of your FAS http/php server.
### fas-hid.php
**You can run the FAS example script, fas-hid.php**, locally on the same device that is running NDS, or remotely on an Internet based FAS server.
The use of http protocol is enforced. fas-hid is specifically targeted at local systems with insufficient resources to run PHP services, yet facilitate remote FAS support without exposing the client token or requiring the remote FAS to somehow access the local ndsctl.
**If run locally on the NDS device**, a minimum of 64MB of ram may be sufficient, but 128MB or more is recommended.
**If run on a remote FAS server**, a minimum of 32MB of ram on the local device may be sufficient, but 64MB or more is recommended.
### fas-aes.php
**You can run the FAS example script, fas-aes.php**, locally on the same device that is running NDS (A minimum of 64MB of ram may be sufficient, but 128MB is recommended), or remotely on an Internet based FAS server. The use of http protocol is enforced.
### fas-aes-https.php
**You can run the FAS example script, fas-aes-https.php**, remotely on an Internet based https FAS server. The use of https protocol is enforced.
On the openNDS device, a minimum of 64MB of ram may be sufficient, but 128MB is recommended.
### Example Script File fas-aes.php
(See docs)
### Example Script File fas-aes-https.php
(See docs)
### Example Script File fas-hid.php
(See docs)
## Changing faskey
The value of option faskey should of course be changed, but must also be pre-shared with FAS by editing the example or your own script to match the new value.