summaryrefslogtreecommitdiff
path: root/pages/docs
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2015-06-19 00:36:27 -0700
committerelijah <elijah@riseup.net>2015-06-19 00:36:27 -0700
commit702b9e594b616637326760623c8b9d2e9ea4e0de (patch)
tree76b3523b29dc91e8f8031b811aa8e545b555736b /pages/docs
parent32cc0dd47c5998804fc4f0c77f603b2800e3310d (diff)
added platform/services documentation, removed /services (/services text is better on bitmask.net anyway).
Diffstat (limited to 'pages/docs')
-rw-r--r--pages/docs/platform/details/faq.md31
-rw-r--r--pages/docs/platform/details/webapp.md282
-rw-r--r--pages/docs/platform/guide/nodes.md100
-rw-r--r--pages/docs/platform/services/couchdb.md (renamed from pages/docs/platform/details/couchdb.md)32
-rw-r--r--pages/docs/platform/services/en.md83
-rw-r--r--pages/docs/platform/services/monitor.md36
-rw-r--r--pages/docs/platform/services/mx.md12
-rw-r--r--pages/docs/platform/services/openvpn.md49
-rw-r--r--pages/docs/platform/services/soledad.md12
-rw-r--r--pages/docs/platform/services/tor.md32
-rw-r--r--pages/docs/platform/services/webapp.md115
11 files changed, 369 insertions, 415 deletions
diff --git a/pages/docs/platform/details/faq.md b/pages/docs/platform/details/faq.md
index 10cdbe0..7ee20f4 100644
--- a/pages/docs/platform/details/faq.md
+++ b/pages/docs/platform/details/faq.md
@@ -3,29 +3,6 @@
@summary = "Frequently Asked Questions"
@toc = true
-Webapp
-======
-
-How do I set the admins?
-------------------------
-
-Edit your services/webapp.json (or create it, if it doesn't exist) and place something like the following in it:
-
- {
- "webapp": {
- "admins": ["joe"]
- }
- }
-
-
-Nagios
-======
-
-How do I find the login information for nagios?
------------------------------------------------
-
-The login information is in the secrets.json file, under "nagios_admin" (please note: the login name is 'nagiosadmin', not 'nagios_admin').
-
APT
===============
@@ -40,7 +17,13 @@ Puppet
Where do i find the time a server was last deployed ?
-----------------------------------------------------
-The puppet state file on the node indicates the last puppetrun:
+Run:
+
+ leap history FILTER
+
+This will tail the log file `/var/log/leap/deploy-summary.log`.
+
+If that command fails, you can manually check the puppet state file on the node indicates the last puppetrun:
ls -la /var/lib/puppet/state/state.yaml
diff --git a/pages/docs/platform/details/webapp.md b/pages/docs/platform/details/webapp.md
deleted file mode 100644
index 2b078af..0000000
--- a/pages/docs/platform/details/webapp.md
+++ /dev/null
@@ -1,282 +0,0 @@
-@title = 'LEAP Web'
-@summary = 'The web component of the LEAP Platform, providing user management, support desk, documentation and more.'
-@toc = true
-
-Introduction
-===================
-
-"LEAP Web" is the webapp component of the LEAP Platform, providing the following services:
-
-* REST API for user registration.
-* Admin interface to manage users.
-* Client certificate distribution and renewal.
-* User support help tickets.
-* Billing
-* Customizable and Localized user documentation
-
-This web application is written in Ruby on Rails 3, using CouchDB as the backend data store.
-
-It is licensed under the GNU Affero General Public License (version 3.0 or higher). See http://www.gnu.org/licenses/agpl-3.0.html for more information.
-
-Known problems
-====================
-
-* Client certificates are generated without a CSR. The problem is that this makes the web
- application extremely vulnerable to denial of service attacks. This was not an issue until we
- started to allow the possibility of anonymously fetching a client certificate without
- authenticating first.
-
-* By its very nature, the user database is vulnerable to enumeration attacks. These are
- very hard to prevent, because our protocol is designed to allow query of a user database via
- proxy in order to provide network perspective.
-
-Integration
-===========
-
-LEAP web is part of the leap platform. Most of the time it will be customized and deployed in that context. This section describes the integration of LEAP web in the wider framework. The Development section focusses on development of LEAP web itself.
-
-Configuration & Customization
-------------------------------
-
-The customization of the webapp for a leap provider happens via two means:
- * configuration settings in services/webapp.json
- * custom files in files/webapp
-
-### Configuration Settings
-
-The webapp ships with a fairly large set of default settings for all environments. They are stored in config/defaults.yml. During deploy the platform creates config/config.yml from the settings in services/webapp.json. These settings will overwrite the defaults.
-
-### Custom Files
-
-Any file placed in files/webapp in the providers repository will overwrite the content of config/customization in the webapp. These files will override files of the same name.
-
-This mechanism allows customizing basically all aspects of the webapp.
-See files/webapp/README.md in the providers repository for more.
-
-### Provider Information ###
-
-The leap client fetches provider information via json files from the server. The platform prepares that information and stores it in the webapp in public/1/config/*.json. (1 being the current API version).
-
-Provider Documentation
--------------
-
-LEAP web already comes with a bit of user documentation. It mostly resides in app/views/pages and thus can be overwritten by adding files to files/webapp/views/pages in the provider repository. You probably want to add your own Terms of Services and Privacy Policy here.
-The webapp will render haml, erb and markdown templates and pick translated content from localized files such as privacy_policy.es.md. In order to add or remove languages you have to modify the available_locales setting in the config. (See Configuration Settings above)
-
-Development
-===========
-
-Installation
----------------------------
-
-Typically, this application is installed automatically as part of the LEAP Platform. To install it manually for testing or development, follow these instructions:
-
-### TL;DR ###
-
-Install git, ruby 1.9, rubygems and couchdb on your system. Then run
-
- gem install bundler
- git clone https://leap.se/git/leap_web
- cd leap_web
- git submodule update --init
- bundle install --binstubs
- bin/rails server
-
-### Install system requirements
-
-First of all you need to install ruby, git and couchdb. On debian based systems this would be achieved by something like
-
- sudo apt-get install git ruby1.9.3 rubygems couchdb
-
-We install most gems we depend upon through [bundler](http://gembundler.com). So first install bundler
-
- sudo gem install bundler
-
-On Debian Wheezy or later, there is a Debian package for bundler, so you can alternately run ``sudo apt-get install bundler``.
-
-### Download source
-
-Simply clone the git repository:
-
- git clone git://leap.se/leap_web
- cd leap_web
-
-### SRP Submodule
-
-We currently use a git submodule to include srp-js. This will soon be replaced by a ruby gem. but for now you need to run
-
- git submodule update --init
-
-### Install required ruby libraries
-
- cd leap_web
- bundle
-
-Typically, you run ``bundle`` as a normal user and it will ask you for a sudo password when it is time to install the required gems. If you don't have sudo, run ``bundle`` as root.
-
-Configuration
-----------------------------
-
-The configuration file `config/defaults.yml` providers good defaults for most
-values. You can override these defaults by creating a file `config/config.yml`.
-
-There are a few values you should make sure to modify:
-
- production:
- admins: ["myusername","otherusername"]
- domain: example.net
- force_ssl: true
- secret_token: "4be2f60fafaf615bd4a13b96bfccf2c2c905898dad34..."
- client_ca_key: "/etc/ssl/ca.key"
- client_ca_cert: "/etc/ssl/ca.crt"
- ca_key_password: nil
-
-* `admins` is an array of usernames that are granted special admin privilege.
-* `domain` is your fully qualified domain name.
-* `force_ssl`, if set to true, will require secure cookies and turn on HSTS. Don't do this if you are using a self-signed server certificate.
-* `secret_token`, used for cookie security, you can create one with `rake secret`. Should be at least 30 characters.
-* `client_ca_key`, the private key of the CA used to generate client certificates.
-* `client_ca_cert`, the public certificate the CA used to generate client certificates.
-* `ca_key_password`, used to unlock the client_ca_key, if needed.
-
-### Provider Settings
-
-The leap client fetches provider information via json files from the server.
-If you want to use that functionality please add your provider files the public/1/config directory. (1 being the current API version).
-
-Running
------------------------------
-
- cd leap_web
- bin/rails server
-
-You will find Leap Web running on `localhost:3000`
-
-Testing
---------------------------------
-
-To run all tests
-
- rake test
-
-To run an individual test:
-
- rake test TEST=certs/test/unit/client_certificate_test.rb
- or
- ruby -Itest certs/test/unit/client_certificate_test.rb
-
-Engines
----------------------
-
-Leap Web includes some Engines. All things in `app` will overwrite the engine behaviour. You can clone the leap web repository and add your customizations to the `app` directory. Including leap_web as a gem is currently not supported. It should not require too much work though and we would be happy to include the changes required.
-
-If you have no use for one of the engines you can remove it from the Gemfile. Engines should really be plugins - no other engines should depend upon them. If you need functionality in different engines it should probably go into the toplevel.
-
-# Deployment #
-
-We strongly recommend using the LEAP platform for deploy. Most of the things documented here are automated as part of the platform. If you want to research how the platform deploys or work on your own mechanism this section is for you.
-
-These instructions are targeting a Debian GNU/Linux system. You might need to change the commands to match your own needs.
-
-## Server Preperation ##
-
-### Dependencies ##
-
-The following packages need to be installed:
-
-* git
-* ruby1.9
-* rubygems1.9
-* couchdb (if you want to use a local couch)
-
-### Setup Capistrano ###
-
-We use puppet to deploy. But we also ship an untested config/deploy.rb.example. Edit it to match your needs if you want to use capistrano.
-
-run `cap deploy:setup` to create the directory structure.
-
-run `cap deploy` to deploy to the server.
-
-## Customized Files ##
-
-Please make sure your deploy includes the following files:
-
-* public/1/config/*.json (see Provider Settings section)
-* config/couchdb.yml
-
-## Couch Security ##
-
-We recommend against using an admin user for running the webapp. To avoid this couch design documents need to be created ahead of time and the auto update mechanism needs to be disabled.
-Take a look at test/setup_couch.sh for an example of securing the couch.
-
-## Design Documents ##
-
-After securing the couch design documents need to be deployed with admin permissions. There are two ways of doing this:
- * rake couchrest:migrate_with_proxies
- * dump the documents as files with `rake couchrest:dump` and deploy them
- to the couch by hand or with the platform.
-
-### CouchRest::Migrate ###
-
-The before_script block in .travis.yml illustrates how to do this:
-
- mv test/config/couchdb.yml.admin config/couchdb.yml # use admin privileges
- bundle exec rake couchrest:migrate_with_proxies # run the migrations
- bundle exec rake couchrest:migrate_with_proxies # looks like this needs to run twice
- mv test/config/couchdb.yml.user config/couchdb.yml # drop admin privileges
-
-### Deploy design docs from CouchRest::Dump ###
-
-First of all we get the design docs as files:
-
- # put design docs in /tmp/design
- bundle exec rake couchrest:dump
-
-Then we add them to files/design in the site_couchdb module in leap_platform so they get deployed with the couch. You could also upload them using curl or sth. similar.
-
-# Troubleshooting #
-
-Here are some less common issues you might run into when installing Leap Web.
-
-## Cannot find Bundler ##
-
-### Error Messages ###
-
-`bundle: command not found`
-
-### Solution ###
-
-Make sure bundler is installed. `gem list bundler` should list `bundler`.
-You also need to be able to access the `bundler` executable in your PATH.
-
-## Outdated version of rubygems ##
-
-### Error Messages ###
-
-`bundler requires rubygems >= 1.3.6`
-
-### Solution ###
-
-`gem update --system` will install the latest rubygems
-
-## Missing development tools ##
-
-Some required gems will compile C extensions. They need a bunch of utils for this.
-
-### Error Messages ###
-
-`make: Command not found`
-
-### Solution ###
-
-Install the required tools. For linux the `build-essential` package provides most of them. For Mac OS you probably want the XCode Commandline tools.
-
-## Missing libraries and headers ##
-
-Some gem dependencies might not compile because they lack the needed c libraries.
-
-### Solution ###
-
-Install the libraries in question including their development files.
-
-
diff --git a/pages/docs/platform/guide/nodes.md b/pages/docs/platform/guide/nodes.md
index cf22544..5135f3b 100644
--- a/pages/docs/platform/guide/nodes.md
+++ b/pages/docs/platform/guide/nodes.md
@@ -1,106 +1,6 @@
@title = "Nodes"
@summary = "Working with nodes, services, tags, and locations."
-Node types
-================================
-
-Every node has one or more services that determines the node's function within your provider's infrastructure.
-
-When adding a new node to your provider, you should ask yourself four questions:
-
-* **many or few?** Some services benefit from having many nodes, while some services are best run on only one or two nodes.
-* **required or optional?** Some services are required, while others can be left out.
-* **who does the node communicate with?** Some services communicate very heavily with other particular services. Nodes running these services should be close together.
-* **public or private?** Some services communicate with the public internet, while others only need to communicate with other nodes in the infrastructure.
-
-Brief overview of the services:
-
-* **webapp**: The web application. Runs both webapp control panel for users and admins as well as the REST API that the client uses. Needs to communicate heavily with `couchdb` nodes. You need at least one, good to have two for redundancy. The webapp does not get a lot of traffic, so you will not need many.
-* **couchdb**: The database for users and user data. You can get away with just one, but for proper redundancy you should have at least three. Communicates heavily with `webapp`, `mx`, and `soledad` nodes.
-* **soledad**: Handles the data syncing with clients. Typically combined with `couchdb` service, since it communicates heavily with couchdb.
-* **mx**: Incoming and outgoing MX servers. Communicates with the public internet, clients, and `couchdb` nodes.
-* **openvpn**: OpenVPN gateway for clients. You need at least one, but want as many as needed to support the bandwidth your users are doing. The `openvpn` nodes are autonomous and don't need to communicate with any other nodes. Often combined with `tor` service.
-* **monitor**: Internal service to monitor all the other nodes. Currently, you can have zero or one `monitor` service defined. It is required that the monitor be on the webapp node. It was not designed to be run as a separate node service.
-* **tor**: Sets up a tor exit node, unconnected to any other service.
-* **dns**: Not yet implemented.
-
-Webapp
------------------------------------
-
-The webapp node is responsible for both the user face web application and the API that the client interacts with.
-
-Some users can be "admins" with special powers to answer tickets and close accounts. To make an account into an administrator, you need to configure the `webapp.admins` property with an array of user names.
-
-For example, to make users `alice` and `bob` into admins, create a file `services/webapp.json` with the following content:
-
- {
- "webapp": {
- "admins": ["bob", "alice"]
- }
- }
-
-And then redeploy to all webapp nodes:
-
- leap deploy webapp
-
-By putting this in `services/webapp.json`, you will ensure that all webapp nodes inherit the value for `webapp.admins`.
-
-Services
-================================
-
-What nodes do you need for a provider that offers particular services?
-
-<table class="table table-striped">
-<tr>
- <th>Node Type</th>
- <th>VPN Service</th>
- <th>Email Service</th>
- <th>Notes</th>
-</tr>
-<tr>
- <td>webapp</td>
- <td>required</td>
- <td>required</td>
- <td></td>
-</tr>
-<tr>
- <td>couchdb</td>
- <td>required</td>
- <td>required</td>
-<td></td>
-</tr>
-<tr>
- <td>soledad</td>
- <td>not used</td>
- <td>required</td>
-<td></td>
-</tr>
-<tr>
- <td>mx</td>
- <td>not used</td>
- <td>required</td>
- <td></td>
-</tr>
-<tr>
- <td>openvpn</td>
- <td>required</td>
- <td>not used</td>
- <td></td>
-</tr>
-<tr>
- <td>monitor</td>
- <td>optional</td>
- <td>optional</td>
- <td>This service must be on the webapp node</td>
-</tr>
-<tr>
- <td>tor</td>
- <td>optional</td>
- <td>optional</td>
- <td></td>
-</tr>
-</table>
-
Locations
================================
diff --git a/pages/docs/platform/details/couchdb.md b/pages/docs/platform/services/couchdb.md
index 276bfdc..7bf4e7c 100644
--- a/pages/docs/platform/details/couchdb.md
+++ b/pages/docs/platform/services/couchdb.md
@@ -1,7 +1,24 @@
-@title = "CouchDB"
+@title = "couchdb"
+@summary = "Data storage for all user data."
-Rebalance Cluster
-=================
+Topology
+------------------------
+
+`couchdb` nodes communicate heavily with `webapp`, `mx`, and `soledad` nodes. Typically, `couchdb` nodes will also have the `soledad` service.
+
+`couchdb` nodes do not need to be reachable from the public internet, although the `soledad` service does require this.
+
+Configuration
+----------------------------
+
+There are no options that should be modified for `couchdb` nodes.
+
+NOTE: The LEAP platform is designed to support many database nodes. The goal is for you to be able to add nodes and remove nodes and everything should rebalance and work smoothly. Currently, however, we are using a broken CouchDB variant called BigCouch. Until we migrate off BigCouch, you should only have one `couchdb` node. More than one will work most of the time, but there are some bugs that can pop up and that are unfixed.
+
+Manual Tasks
+---------------------
+
+### Rebalance Cluster
Bigcouch currently does not have automatic rebalancing.
It will probably be added after merging into couchdb.
@@ -39,8 +56,7 @@ If you add a node, or remove one node from the cluster,
/srv/leap/couchdb/scripts/couchdb_restoreall.sh
-Re-enabling blocked account
-===========================
+### Re-enabling blocked account
When a user account gets destroyed from the webapp, there's still a leftover doc in the identities db so other ppl can't claim that account without admin's intervention. Here's how you delete that doc and therefore enable registration for that particular account again:
@@ -54,8 +70,7 @@ When a user account gets destroyed from the webapp, there's still a leftover doc
curl -s --netrc-file /etc/couchdb/couchdb.netrc -X DELETE 'http://127.0.0.1:5984/identities/b25cf10f935b58088f0d547fca823265?rev=2-715a9beba597a2ab01851676f12c3e4a'
-How to find out which userstore belongs to which identity ?
-===========================================================
+### How to find out which userstore belongs to which identity ?
/usr/bin/curl -s --netrc-file /etc/couchdb/couchdb.netrc '127.0.0.1:5984/identities/_all_docs?include_docs=true' | grep testuser
@@ -65,8 +80,7 @@ How to find out which userstore belongs to which identity ?
* in this example testuser@example.org uses the database user-665e004870ee17aa4c94331ff3cd59eb
-How much disk space is used by a userstore
-==========================================
+### How much disk space is used by a userstore
Beware that this returns the uncompacted disk size (see http://wiki.apache.org/couchdb/Compaction)
diff --git a/pages/docs/platform/services/en.md b/pages/docs/platform/services/en.md
new file mode 100644
index 0000000..aa4ffc7
--- /dev/null
+++ b/pages/docs/platform/services/en.md
@@ -0,0 +1,83 @@
+@nav_title = "Services"
+@title = "Guide to node services"
+@summary = ""
+@toc = true
+
+# Introduction
+
+Every node (server) must have one or more `services` defined that determines what role the node performs. For example:
+
+
+```
+ cat nodes/stallman.json
+ {
+ "ip_address": "199.99.99.1",
+ "services": ["webapp", "tor"]
+ }
+```
+
+Here are common questions to ask when adding a new node to your provider:
+
+* **many or few?** Some services benefit from having many nodes, while some services are best run on only one or two nodes.
+* **required or optional?** Some services are required, while others can be left out.
+* **who does the node communicate with?** Some services communicate very heavily with other particular services. Nodes running these services should be close together.
+* **public or private network?** Some services communicate with the public internet, while others only need to communicate with other nodes in the infrastructure.
+
+# Available services
+
+<table class="table table-striped">
+<tr>
+ <th>Service</th>
+ <th>VPN</th>
+ <th>Email</th>
+ <th>Notes</th>
+</tr>
+<tr>
+ <td>webapp</td>
+ <td><i class="fa fa-circle"></i></td>
+ <td><i class="fa fa-circle"></i></td>
+ <td>User control panel, provider API, and support system.</td>
+</tr>
+<tr>
+ <td>couchdb</td>
+ <td><i class="fa fa-circle"></i></td>
+ <td><i class="fa fa-circle"></i></td>
+ <td>Data storage for everything. Private node.</td>
+<td></td>
+</tr>
+<tr>
+ <td>soledad</td>
+ <td><i class="fa fa-circle-o"></i></td>
+ <td><i class="fa fa-circle"></i></td>
+ <td>User data synchronization daemon. Usually paired with <code>couchdb</code> nodes.</td>
+<td></td>
+</tr>
+<tr>
+ <td>mx</td>
+ <td><i class="fa fa-circle-o"></i></td>
+ <td><i class="fa fa-circle"></i></td>
+ <td>Incoming and outgoing MX servers.</td>
+</tr>
+<tr>
+ <td>openvpn</td>
+ <td><i class="fa fa-circle"></i></td>
+ <td><i class="fa fa-circle-o"></i></td>
+ <td>OpenVPN gateways.</td>
+</tr>
+<tr>
+ <td>monitor</td>
+ <td><i class="fa fa-dot-circle-o"></i></td>
+ <td><i class="fa fa-dot-circle-o"></i></td>
+ <td>Nagios monitoring. This service must be on the webapp node.</td>
+</tr>
+<tr>
+ <td>tor</td>
+ <td><i class="fa fa-dot-circle-o"></i></td>
+ <td><i class="fa fa-dot-circle-o"></i></td>
+ <td>Tor exit node.</td>
+</tr>
+</table>
+
+Key: <i class="fa fa-circle"> Required</i>, <i class="fa fa-dot-circle-o"> Optional</i>, <i class="fa fa-circle-o"> Not Used</i>
+
+<%= child_summaries %> \ No newline at end of file
diff --git a/pages/docs/platform/services/monitor.md b/pages/docs/platform/services/monitor.md
new file mode 100644
index 0000000..576b36a
--- /dev/null
+++ b/pages/docs/platform/services/monitor.md
@@ -0,0 +1,36 @@
+@title = "monitor"
+@summary = "Nagios monitoring and continuous testing."
+
+The `monitor` node provides a nagios control panel that will give you a view into the health and status of all the servers and all the services. It will also spam you with alerts if something goes down.
+
+Topology
+--------------------------------------
+
+Currently, you can have zero or one `monitor` nodes defined. It is required that the monitor be on the webapp node. It was not designed to be run as a separate node service.
+
+Configuration
+-----------------------------------------------
+
+* `nagios.environments`: By default, the monitor node will monitor all servers in all environments. You can optionally restrict the environments to the ones you specify.
+
+For example:
+
+ {
+ "nagios": {
+ "environments": ["unstable", "production"]
+ }
+ }
+
+Access nagios web
+-----------------------------------------------
+
+*Determine the nagios URL*
+
+ $ leap ls --print domain.name,webapp.domain,ip_address monitor
+ > chameleon chameleon.bitmask.net, demo.bitmask.net, 199.119.112.10
+
+In this case, you would open `https://demo.bitmask.net/cgi-bin/nagios3` in your browser (or alternately you could use 199.119.112.10 or chameleon.bitmask.net).
+
+*Determine the nagios password*
+
+The username for nagios is always `nagiosadmin`. The password is randomly generated and stored in `secrets.json` under the key `nagios_admin_password`. Note that the login is `nagiosadmin` without underscore, but the entry in secrets.json is with underscores.
diff --git a/pages/docs/platform/services/mx.md b/pages/docs/platform/services/mx.md
new file mode 100644
index 0000000..79f1c4e
--- /dev/null
+++ b/pages/docs/platform/services/mx.md
@@ -0,0 +1,12 @@
+@title = "mx"
+@summary = "Incoming and outgoing MX servers."
+
+Topology
+-------------------
+
+`mx` nodes communicate with the public internet, clients, and `couchdb` nodes.
+
+Configuration
+--------------------
+
+There are not values that should be configured for `mx` nodes. \ No newline at end of file
diff --git a/pages/docs/platform/services/openvpn.md b/pages/docs/platform/services/openvpn.md
new file mode 100644
index 0000000..5f15ff0
--- /dev/null
+++ b/pages/docs/platform/services/openvpn.md
@@ -0,0 +1,49 @@
+@title = 'openvpn'
+@summary = "OpenVPN egress gateways"
+
+Topology
+------------------
+
+Currently, `openvpn` service should not be combined with other services on the same node.
+
+Unlike most of the other node types, the `openvpn` nodes do not need access to the database and does not ever communicate with any other nodes (except for the `monitor` node, if used). So, `openvpn` nodes can be placed anywhere without regard to the other nodes.
+
+Configuration
+---------------------
+
+*Essential configuration*
+
+* `openvpn.gateway_address`: The address that OpenVPN daemon is bound to and that VPN clients connect to.
+* `ip_address`: The main IP of the server, and the egress address for outgoing traffic.
+
+For example:
+
+ {
+ "ip_address": "1.1.1.1",
+ "openvpn": {
+ "gateway_address": "2.2.2.2"
+ }
+ }
+
+In this example, VPN clients will connect to 2.2.2.2, but their traffic will appear to come from 1.1.1.1.
+
+Why are two IP addresses needed? Without this, traffic between two VPN users on the same gateway will not get encrypted. This is because the VPN on every client must be configured to allow cleartext traffic for the IP address that is the VPN gateway.
+
+*Optional configuration*
+
+Here is the default configuration:
+
+ "openvpn": {
+ "configuration": {
+ "auth": "SHA1",
+ "cipher": "AES-128-CBC",
+ "fragment": 1400,
+ "keepalive": "10 30",
+ "tls-cipher": "DHE-RSA-AES128-SHA",
+ "tun-ipv6": true
+ },
+ "ports": ["80", "443", "53", "1194"],
+ "protocols": ["tcp", "udp"]
+ }
+
+You may want to change the ports so that only 443 or 80 are used. It is probably best to not modify the `openvpn.configuration` options for now. \ No newline at end of file
diff --git a/pages/docs/platform/services/soledad.md b/pages/docs/platform/services/soledad.md
new file mode 100644
index 0000000..e2700d0
--- /dev/null
+++ b/pages/docs/platform/services/soledad.md
@@ -0,0 +1,12 @@
+@title = 'soledad'
+@summary = 'User data synchronization daemon'
+
+Topology
+--------------------
+
+Currently, the platform is designed for `soledad` and `couchdb` services to be combined (e.g. every `soledad` node should also be a `couchdb` node). `soledad` nodes might work in isolation, but this is not tested.
+
+Configuration
+------------------------
+
+There are no options to configure for `soledad` nodes.
diff --git a/pages/docs/platform/services/tor.md b/pages/docs/platform/services/tor.md
new file mode 100644
index 0000000..e64b0fe
--- /dev/null
+++ b/pages/docs/platform/services/tor.md
@@ -0,0 +1,32 @@
+@title = 'tor'
+@summary = 'Tor exit node or hidden service'
+
+Topology
+------------------------
+
+Nodes with `tor` service will run a Tor exit or hidden service, depending on what other service it is paired with:
+
+* `tor` + `openvpn`: when combined with `openvpn` nodes, `tor` will create a Tor exit node to provide extra cover traffic for the VPN. This can be especially useful if there are VPN gateways without much traffic.
+* `tor` + `webapp`: when combined with a `webapp` node, the `tor` service will make the webapp and the API available via .onion hidden service.
+* `tor` stand alone: a regular Tor exit node.
+
+If activated, you can list the hidden service .onion addresses this way:
+
+ leap ls --print tor.hidden_service.address tor
+
+Then just add '.onion' to the end of the printed addresses.
+
+Configuration
+------------------------------
+
+* `tor.bandwidth_rate`: the max bandwidth allocated to Tor, in KB per second, when used as an exit node.
+
+For example:
+
+ {
+ "tor": {
+ "bandwidth_rate": 6550
+ }
+ }
+
+
diff --git a/pages/docs/platform/services/webapp.md b/pages/docs/platform/services/webapp.md
new file mode 100644
index 0000000..4e0d171
--- /dev/null
+++ b/pages/docs/platform/services/webapp.md
@@ -0,0 +1,115 @@
+@title = "webapp"
+@summary = "leap_web user management application and provider API."
+
+Introduction
+------------------------
+
+The service `webapp` will install the web application [[leap_web => https://leap.se/git/leap_web.git]]. It has performs the following functions:
+
+* REST API for user registration and authentication via the Bitmask client.
+* Admin interface to manage users.
+* Client certificate distribution and renewal.
+* User support help tickets.
+
+Coming soon:
+
+* Billing.
+* Customizable and localized user documentation.
+
+The leap_web application is written in Ruby on Rails 3, using CouchDB as the backend data store.
+
+Topology
+-------------------------
+
+Currently, the platform only supports a single `webapp` node, although we hope to change this in the future.
+
+`webapp` nodes communicate heavily with `couchdb` nodes.
+
+Configuration
+--------------------------
+
+Essential options:
+
+* `webapp.admin`: An array of username that will be blessed with administrative permissions. These admins can delete users, answer help tickets, and so on.
+
+For example, `services/webapp.json`:
+
+ {
+ "webapp": {
+ "admins": ["joehill", "ali", "mack_the_turtle"]
+ }
+ }
+
+By putting this in `services/webapp.json`, all the `webapp` nodes will inherit the same admin list.
+
+Customization
+---------------------------
+
+The provider directory `files/webapp` can be used to customize the appearance of the webapp. All the files in this directory will get sync'ed to the `/srv/leap/webapp/config/customization` directory of the deployed webapp node.
+
+Files in the `files/webapp` can override view files, locales, and stylesheets in the leap_web app:
+
+For example:
+
+ stylesheets/ -- override files in Rails.root/app/assets/stylesheets
+ tail.scss -- included before all others
+ head.scss -- included after all others
+
+ public/ -- overrides files in Rails.root/public
+ favicon.ico -- custom favicon
+ img/ -- customary directory to put images in
+
+ views/ -- overrides files Rails.root/app/views
+ home/
+ index.html.haml -- this file is what shows up on
+ the home page
+ pages/
+ privacy-policy.en.md -- this file will override
+ the default privacy policy
+ terms-of-service.en.md -- this file will override
+ the default TOS.
+
+ locales/ -- overrides files in Rails.root/config/locales
+ en.yml -- overrides for English
+ de.yml -- overrides for German
+ and so on...
+
+To play with these customizations, it is easiest to first modify the contents of the directory `/srv/leap/webapp/config/customization` on the `webapp` node. When doing this, you may need to restart leap_web in order for changes to take effect (`touch /srv/leap/webapp/tmp/restart.txt`).
+
+Sometimes a `rake tmp:clear` and a rails restart is required to pick up a new stylesheet.
+
+Once you have what you want, then copy these files to the local provider directory `files/webapp` so that they will be installed each time you deploy.
+
+Custom Fork
+----------------------------
+
+Sometimes it is easier to maintain your own fork of the leap_web app. You can keep your customizations in that fork instead of in the provider `files/webapp` directory. Or, perhaps you want to add an engine to the application that modifies the app's behavior.
+
+To deploy your own leap_web, modify the provider file `common.json`:
+
+ {
+ "sources": {
+ "webapp": {
+ "revision": "origin/develop",
+ "source": "https://github.com/leapcode/leap_web",
+ "type": "git"
+ }
+ }
+ }
+
+To target only particular environment, modify instead `common.ENV.json`, where ENV is the name of the environment.
+
+See https://github.com/leapcode/leap_web/blob/develop/doc/DEVELOP.md for notes on getting started hacking on leap_web.
+
+Known problems
+---------------------------
+
+* Client certificates are generated without a CSR. The problem is that this makes the web
+ application extremely vulnerable to denial of service attacks. This was not an issue until we
+ started to allow the possibility of anonymously fetching a client certificate without
+ authenticating first.
+
+* By its very nature, the user database is vulnerable to enumeration attacks. These are
+ very hard to prevent, because our protocol is designed to allow query of a user database via
+ proxy in order to provide network perspective.
+