Domains

How to handle domain names and integrating LEAP with existing services.

Overview

Deploying LEAP can start to get very tricky when you need to integrate LEAP services with an existing domain that you already use or which already has users. Most of this complexity is unavoidable, although there are a few things we plan to do in the future to make this a little less painful.

Because integration with legacy systems is an advanced topic, we recommend that you begin with a new domain. Once everything works and you are comfortable with your LEAP-powered infrastructure, you can then contemplate integrating with your existing domain.

Definitions

provider domain

This is the main domain used to identify the provider. The provider domain is what the user enters in the Bitmask client. e.g. example.org. The full host name of every node in your provider infrastructure will use the provider domain (e.g. dbnode.example.org).

In order for the Bitmask client to get configured for use with a provider, it must be able to find the provider.json bootstrap file at the root of the provider domain. This is not needed if the Bitmask client is “pre-seeded” with the provider’s information (these providers show up in a the initial list of available providers).

webapp domain

This is the domain that runs the leap_web application that allows users to register accounts, create help tickets, etc. e.g. example.org or user.example.org. The webapp domain defaults to the provider domain unless it is explicitly configured separately.

API domain

This is the domain that the provider API runs on. Typically, this is set automatically and you never need to configure it. The user should never be aware of this domain. e.g. api.example.org. The Bitmask client discovers this API domain by reading it from the provider.json file it grabs from the provider domain.

mail domain

This is the domain used for mail accounts, e.g. username@example.org. Currently, this is always the provider domain, but it may be independently configurable in the future.

Generating a zone file

Currently, the platform does not include a dedicated dns service type, so you need to have your own setup for DNS. You can generate the appropriate configuration options with this command:

leap compile zone

A single domain

The easy approach is to use a single domain for provider domain, webapp domain, and email domain. This will install the webapp on the provider domain, which means that this domain must be a new one that you are not currently using for anything.

To configure a single domain, just set the domain in provider.json:

{
  "domain": "example.org"
}

If you have multiple environments, you can specify a different provider domain for each environment. For example:

provider.staging.json

{
  "domain": "staging.example.org"
}

A separate domain for the webapp

It is possible make the webapp domain different than the provider domain. This is needed if you already have a website running at your provider domain.

In order to put webapp on a different domain, you must take two steps:

  1. You must configure webapp.domain for nodes with the webapp service.
  2. You must make the compiled provider.json available at the root of the provider domain.

NOTE: This compiled provider.json is different than the provider.json that you edit and lives in the root of the provider directory.

Step 1. Configuring webapp.domain

In services/webapp.json:

{
  "webapp": {
    "domain": "user.example.org"
  }
}

Step 2. Putting the compiled provider.json in place

Generate the compiled provider.json:

leap compile provider.json
= created files/web/bootstrap/
= created files/web/bootstrap/README
= created files/web/bootstrap/production/
= created files/web/bootstrap/production/provider.json
= created files/web/bootstrap/production/htaccess
= created files/web/bootstrap/staging/
= created files/web/bootstrap/staging/provider.json
= created files/web/bootstrap/staging/htaccess

This command compiles a separate provider.json for each environment, or “default” if you don’t have an environment. In the example above, there is an environment called “production” and one called “staging”, but your setup will probably differ.

The resulting provider.json file must then be put at the root URL of your provider domain for the appropriate environment.

There is one additional complication: currently, the Bitmask client tests for compatibility using some HTTP headers on the /provider.json response. This is will hopefully change in the future, but for now you need to ensure the right headers are set in the response. The included file htaccess has example directives for Apache, if that is what you use.

This step can be skipped if you happen to use the static service to deploy an amber powered static website to provider domain. In this case, the correct provider.json will be automatically put into place.

Integrating with existing email system

If your mail domain already has users from a legacy email system, then things get a bit complicated. In order to be able to support both LEAP-powered email and legacy email on the same domain, you need to follow these steps:

  1. Modify the LEAP webapp so that it does not create users with the same name as users in the legacy system.
  2. Configure your legacy MX servers to forward mail that they cannot handle to the LEAP MX servers, or vice versa.

Step 1. Modify LEAP webapp

In order to modify the webapp to respect the usernames already reserved by your legacy system, you need to modify the LEAP webapp code. The easiest way to do this is to create a custom gem that modifies the behavior of the webapp.

For this example, we will call our custom gem reserve_usernames.

This gem can live in one of two places:

(1) You can fork the project leap_web and put the gem in leap_web/vendor/gems/reserve_usernames. Then, modify Gemfile and add the line gem 'common_languages', :path => 'vendor/gems/reserve_usernames'

(2) Alternately, you can put the gem in the local provider directory files/webapp/gems/reserve_username. This will get synced to the webapp servers when you deploy and put in /srv/leap/webapp/config/customization where it will get automatically loaded by the webapp.

What should the gem reserve_usernames look like? There is an example available here: https://leap.se/git/reserved_usernames.git

This example gem uses ActiveResource to communicate with a remote REST API for creating and checking username reservations. This ensures that both the legacy system and the LEAP system use the same namespace. Alternately, you could write a gem that checks the legacy database directly.

Step 2. Configure MX servers

To be written.