| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | walnut | 
					
						
							|  |  |  | ====== | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Small, light, and secure iot application framework. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-05 14:03:02 -06:00
										 |  |  | ```bash | 
					
						
							|  |  |  | curl https://git.daplie.com/Daplie/daplie-snippets/raw/master/install.sh | bash | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | daplie-install-cloud | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | Features | 
					
						
							|  |  |  | ------ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | * Works with Goldilocks for secure, Let's Encrypt maneged, https-only serving | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | * IOT Application server written in [Node.js](https://nodejs.org) | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | * Small memory footprint (for a node app) | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | * Secure | 
					
						
							|  |  |  |   * Uses JWT, not Cookies\* | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  |   * HTTPS-only (checks for X-Forwarded-For) | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  |   * AES, RSA, and ECDSA encryption and signing | 
					
						
							|  |  |  |   * Safe against CSRF, XSS, and SQL injection | 
					
						
							|  |  |  |   * Safe against Compression attacks | 
					
						
							|  |  |  | * Multi-Tentated Application Management | 
					
						
							|  |  |  | * Built-in OAuth2 & OAuth3 support | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \*Cookies are used only for GETs and only where using a token would be less secure | 
					
						
							|  |  |  | such as images which would otherwise require the token to be passed into the img src. | 
					
						
							|  |  |  | They are also scoped such that CSRF attacks are not possible. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Progress | 
					
						
							|  |  |  | ----------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * HTTPS Key Pinning | 
					
						
							|  |  |  | * Heroku (pending completion of PostgreSQL support) | 
					
						
							|  |  |  | * [GunDB](https://gundb.io) Support | 
					
						
							|  |  |  | * OpenID support | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Structure | 
					
						
							|  |  |  | ===== | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Currently being tested with Ubuntu, Raspbian, and Debian on Digital Ocean, Raspberry Pi, and Heroku. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | /srv/walnut/ | 
					
						
							|  |  |  | ├── setup.sh (in-progress) | 
					
						
							|  |  |  | ├── core | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | │   ├── bin | 
					
						
							|  |  |  | │   ├── boot | 
					
						
							|  |  |  | │   ├── holepunch | 
					
						
							|  |  |  | │   └── lib | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | ├── node_modules | 
					
						
							|  |  |  | ├── packages | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | │   ├── apis | 
					
						
							|  |  |  | │   ├── pages | 
					
						
							|  |  |  | │   └── services | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | └── var | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | * `core` contains all walnut code | 
					
						
							|  |  |  | * `node_modules` is a flat installation of all dependencies | 
					
						
							|  |  |  | * `certs` is a directory for Let's Encrypt (or custom) certificates | 
					
						
							|  |  |  | * `var` is a directory for database files and such | 
					
						
							|  |  |  | * `packages` contains 3 types of packages | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | Will install to | 
					
						
							|  |  |  | --------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | /srv/walnut/core/ | 
					
						
							|  |  |  | /etc/walnut | 
					
						
							|  |  |  | /opt/walnut | 
					
						
							|  |  |  | /var/log/walnut | 
					
						
							|  |  |  | /etc/systemd/system/walnut.service | 
					
						
							|  |  |  | /etc/tmpfiles.d/walnut.conf | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Implementation details | 
					
						
							|  |  |  | ---------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Initialization | 
					
						
							|  |  |  | -------------- | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | needs to know its primary domain | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | POST https://api.<domain.tld>/api/com.daplie.walnut.init | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | { "domain": "<domain.tld>" } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 17:17:55 +00:00
										 |  |  | The following domains are required to point to WALNUT server | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <domain.tld> | 
					
						
							|  |  |  | www.<domain.tld> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | api.<domain.tld> | 
					
						
							|  |  |  | assets.<domain.tld> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cloud.<domain.tld> | 
					
						
							|  |  |  | api.cloud.<domain.tld> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example `/etc/goldilocks/goldilocks.yml`: | 
					
						
							|  |  |  | ```yml | 
					
						
							|  |  |  | tls: | 
					
						
							|  |  |  |   email: domains@example.com | 
					
						
							|  |  |  |   servernames: | 
					
						
							|  |  |  |     - example.com | 
					
						
							|  |  |  |     - www.example.com | 
					
						
							|  |  |  |     - api.example.com | 
					
						
							|  |  |  |     - assets.example.com | 
					
						
							|  |  |  |     - cloud.example.com | 
					
						
							|  |  |  |     - api.cloud.example.com | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | http: | 
					
						
							|  |  |  |   trust_proxy: true | 
					
						
							|  |  |  |   modules: | 
					
						
							|  |  |  |     - name: proxy | 
					
						
							|  |  |  |       domains: | 
					
						
							|  |  |  |         - '*' | 
					
						
							|  |  |  |       address: '127.0.0.1:3000' | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | Resetting the Initialization | 
					
						
							|  |  |  | ---------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Once you run the app the initialization files will appear in these locations | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | /srv/walnut/var/com.daplie.walnut.config.sqlite3 | 
					
						
							|  |  |  | /srv/walnut/config/<domain.tld>.json | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-11-28 07:40:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-19 05:20:09 +00:00
										 |  |  | Deleting those files will rese | 
					
						
							| 
									
										
										
										
											2017-05-19 07:45:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Accessing static apps | 
					
						
							|  |  |  | --------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Static apps are stored in `packages/pages` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | # App ID as files with a list of packages they should load
 | 
					
						
							| 
									
										
										
										
											2017-05-22 17:17:55 +00:00
										 |  |  | # note that '#' is used in place of '/' because files and folders may not contain '/' in their names
 | 
					
						
							|  |  |  | /srv/walnut/packages/sites/<domain.tld#path>          # https://domain.tld/path | 
					
						
							|  |  |  | /srv/walnut/packages/sites/<domain.tld>               # https://domain.tld and https://domain.tld/foo match | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # packages are directories with reverse dns name      # For the sake of debugging these packages can be accessed directly, without a site by
 | 
					
						
							|  |  |  | /srv/walnut/packages/pages/<tld.domain.package>       # matches apps.<domain.tld>/<package-name> and <domain.tld>/apps/<package-name> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Accessing REST APIs | 
					
						
							|  |  |  | ------------------- | 
					
						
							| 
									
										
										
										
											2017-05-19 07:45:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 17:17:55 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | # Apps are granted access to use a package by listing it in the grants file by the name of the app url (domain.tld)
 | 
					
						
							|  |  |  | /srv/walnut/packages/client-api-grants/<domain.tld>   # matches api.<domain.tld>/api/ and contains a list of allowed REST APIs | 
					
						
							|  |  |  |                                                       # the REST apis themselves are submatched as api.<domain.tld>/api/<tld.domain.package> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # packages are directories with reverse dns name, a package.json, and an index.js
 | 
					
						
							|  |  |  | /srv/walnut/packages/rest/<tld.domain.package> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example tree with contents: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here `com.example.hello` is a package with a REST API and a static page | 
					
						
							|  |  |  | and `foobar.me` is a WALNUT-configured domain (smithfam.net, etc). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 17:22:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The packages: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 17:17:55 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | /srv/walnut/packages/ | 
					
						
							|  |  |  | ├── api | 
					
						
							|  |  |  | ├── pages | 
					
						
							|  |  |  | │   └── com.example.hello | 
					
						
							|  |  |  | │       └── index.html | 
					
						
							|  |  |  | │             ''' | 
					
						
							|  |  |  | │             <html> | 
					
						
							|  |  |  | │               <head><title>com.example.hello</title></head> | 
					
						
							|  |  |  | │               <body> | 
					
						
							|  |  |  | │                 <h1>com.example.hello</h1> | 
					
						
							|  |  |  | │               </body> | 
					
						
							|  |  |  | │             </html> | 
					
						
							|  |  |  | │             ''' | 
					
						
							|  |  |  | │ | 
					
						
							|  |  |  | ├── rest | 
					
						
							|  |  |  | │   └── com.example.hello | 
					
						
							|  |  |  | │      ├── package.json | 
					
						
							|  |  |  | │      └── index.js | 
					
						
							|  |  |  | │           ''' | 
					
						
							|  |  |  | │           'use strict'; | 
					
						
							|  |  |  | │ | 
					
						
							|  |  |  | │           module.exports.create = function (conf, deps, app) { | 
					
						
							|  |  |  | │ | 
					
						
							|  |  |  | │             app.use('/', function (req, res) { | 
					
						
							|  |  |  | │               console.log('[com.example.hello] req.url', req.url); | 
					
						
							|  |  |  | │               res.send({ message: 'hello' }); | 
					
						
							|  |  |  | │             }); | 
					
						
							|  |  |  | │ | 
					
						
							|  |  |  | │             return deps.Promise.resolve(); | 
					
						
							|  |  |  | │           }; | 
					
						
							|  |  |  | │ | 
					
						
							|  |  |  | │           ''' | 
					
						
							|  |  |  | │ | 
					
						
							| 
									
										
										
										
											2017-05-22 17:22:32 +00:00
										 |  |  | └── services | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The permissions: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | /srv/walnut/packages/ | 
					
						
							|  |  |  | ├── client-api-grants | 
					
						
							|  |  |  | │   └── cloud.foobar.me | 
					
						
							|  |  |  | │         ''' | 
					
						
							|  |  |  | │         com.example.hello     # refers to /srv/walnut/packages/rest/com.example.hello | 
					
						
							|  |  |  | │         ''' | 
					
						
							|  |  |  | │ | 
					
						
							| 
									
										
										
										
											2017-05-22 17:17:55 +00:00
										 |  |  | └── sites | 
					
						
							|  |  |  |     └── daplie.me | 
					
						
							|  |  |  |           ''' | 
					
						
							|  |  |  |           com.example.hello     # refers to /srv/walnut/packages/pages/com.example.hello | 
					
						
							|  |  |  |           ''' | 
					
						
							| 
									
										
										
										
											2017-05-19 07:45:41 +00:00
										 |  |  | ``` |