README.md 10.5 KB
Newer Older
cyberta's avatar
cyberta committed
1 2
# Getting started

3
Currently, you need at least two different remote machines for the installation process. These can be bare-metal, or virtual machines (eg. KVM). They should have a minimal Debian Buster installation and be reachable by ssh. The machines should be considered to be fully managed by this framework when things have been deployed. It will modify the system-level configuration, install packages, start services, etc. However, it assumes that certain functionality is present, either managed manually or with some external mechanism. Network configuration, partitions, file systems, and logical volumes must be externally (or manually) managed. SSH access and configuration must be externally managed _unless_ you explicitly set enable_ssh=true (and add SSH keys to your admin users), in which case deployment will take over the SSH configuration.
4

5
One of the hosts will be a reverse proxy and the VPN gateway. *** You will need two publicly addressable IP addresses for this machine ***. The second machine will run the LEAP web API, its gateway selection service, and the infrastructure that provides monitoring and alerting. 
6

7
The float platform will manage DNS hostnames and Let's Encrypt certificates for all of its services it handles. You should pick a subdomain and delegate its DNS for the system to manage. For example, if your domain is `example.com`, then you could delegate, for example, the subdomain `float.example.com`. You would do this by adding a `NS` record for `float.example.com` that points to `ns1.example.com` and then an `A` record for `ns1.example.com` that points to the IP address you use for the reverse proxy host (note: not the gateway IP).
cyberta's avatar
cyberta committed
8 9 10 11 12 13 14 15

You need to run the following commands ***locally on your computer*** in order to install and deploy the LEAP platfrom on the remote machines.

## 0. Install the float and LEAP platform pre-requisites

You'll need ansible < 2.10 and python3 for the installation process. This installation guide is tested on Debian buster. 
Other Linux distributions might need additional steps to install all requirements in the correct version.

cyberta's avatar
cyberta committed
16
```shell
cyberta's avatar
cyberta committed
17 18 19 20
sudo apt-get install golang bind9utils python3-pysodium python3-jinja2 python3-netaddr python3-openssl python3-yaml python3-six python3-crypto ansible git
go get -u git.autistici.org/ale/x509ca
go get -u git.autistici.org/ale/ed25519gen
go get git.autistici.org/ai3/go-common/cmd/pwtool
cyberta's avatar
cyberta committed
21
export PATH=$PATH:$HOME/go/bin
cyberta's avatar
cyberta committed
22 23 24 25 26 27 28 29 30
```

Make sure `$ ansible --version | grep "ansible 2"` shows a version < 2.10.
Make sure `$ ansible --version | grep "python version" shows a python 3 version.

## 1. Clone the float repository

...and enter it

cyberta's avatar
cyberta committed
31
```shell
kwadronaut's avatar
kwadronaut committed
32
git clone https://0xacab.org/leap/container-platform/lilypad
kwadronaut's avatar
kwadronaut committed
33
cd lilypad
cyberta's avatar
cyberta committed
34 35 36 37 38 39
```
    
## 2. Initialize the ansible vault

... by creating a password file:

cyberta's avatar
cyberta committed
40
```shell
cyberta's avatar
cyberta committed
41 42 43 44 45
tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 26 > .ansible_vault_pw
```

_Optionally_: gpg encrypt this file, so only trusted admins can read it. If you do *not* encrypt this file, then this repository should not be shared anywhere public:

cyberta's avatar
cyberta committed
46
```shell
47 48 49 50
(echo '#!/usr/bin/gpg -d'; gpg -a -e .ansible_vault_pw) \
    > .ansible_vault_pw.gpg
chmod +x .ansible_vault_pw.gpg
rm .ansible_vault_pw
cyberta's avatar
cyberta committed
51 52
```

53
The resulting `.ansible_vault_pw.gpg` will be automatically decrypted by Ansible at runtime (use of an agent, such as `gpg-agent` is advised).
54

cyberta's avatar
cyberta committed
55 56
Configure your local environment to know where the ansible vault password is located:

cyberta's avatar
cyberta committed
57
```shell
cyberta's avatar
cyberta committed
58 59 60 61 62 63
export ANSIBLE_VAULT_PASSWORD_FILE=.ansible_vault_pw
```

_NOTE:_ if you performed the optional encryption step above, you will
need to add .gpg to the end of the file name below:

cyberta's avatar
cyberta committed
64
```shell
cyberta's avatar
cyberta committed
65 66 67 68 69 70 71 72 73 74 75
export ANSIBLE_VAULT_PASSWORD_FILE=.ansible_vault_pw.gpg
```

This environment variable will only be set for this shell, you will need to add it to your shell environment initialization file so it will be set automatically everytime.

## 3. Customize the environment 

Open _hosts.yml_ and change `floatapp1` to your app host's hostname, and specify the `ansible_host` and `ip` values to be the IP addresses for that host. If you have more than one app server, then you would just create a copy of this block, modifying the values, being sure to keep the 'backend' group assigned to each one.

Configure the front-end reverse proxy with in the same way, change the `floatrp1` hostname to your hostname, and the `ansible_host` and `ip` to the IP it should have, and set the  `location` value to where this server is located. For the gateway_address, put the secondary gateway ip.

76 77 78
Then edit _group_vars/all/config.yml_ and set your `domain_public` to the subdomain name that you delegated (eg. `float.example.com`), the `domain` can be set to `infra.example.com` as this is the internally managed domain. 

The _config.yml_ contains a list of admins, a default hashed password and a set of ssh keys that will be able to connect to the system as root. If you do not change this password, then the user 'admin' and password 'password' are used. To change the hashed password you can run 
cyberta's avatar
cyberta committed
79
```shell
cyberta's avatar
cyberta committed
80 81
pwtool <type-here-your-password>
``` 
82 83
and paste the output into the `password` variable. Have a look at [the common operators playbook](https://git.autistici.org/ai3/float/-/blob/master/docs/playbook.md#adding-an-admin-account) for additional options, such as setting up OTP or U2F tokens.

kwadronaut's avatar
kwadronaut committed
84 85
This _config.yml_ also contains the credentials for an updated geoip database. The `geoip_account_id` and `geoip_license_key` values must be changed, you can register for an account on maxmind.com to obtain these. The geoip service helps clients to choose a gateway near them (usually faster).

86
Then edit _group_vars/all/gateway_locations.yml_, _group_vars/all/provider_config.yml_ to match your environment. 
cyberta's avatar
cyberta committed
87 88 89 90 91 92

## 4. Generate credentials 

... by running the init-credentials playbook. This will ansible-vault-encrypt the resulting secret files under _credentials/_. 
_Note:_ this is not the built-in float init-credentials, rather this is the LEAP provided one, which will instantiate the float init-credentials when it is finished.

cyberta's avatar
cyberta committed
93
```shell
cyberta's avatar
cyberta committed
94 95 96 97 98
float/float run playbooks/init-credentials
```

***You should not see any red text*** in this process, if you do, stop now.

99 100
This will generate service-level credentials, which are automatically managed by the toolkit and are encrypted with ansible-vault. These include the internal X509 PKI for TLS service authentication, a SSH PKI for hosts, and application credentials. 

cyberta's avatar
cyberta committed
101 102
## 5. Consider comitting the generated credentials 

103
... to git, and pushing them to a repository. All auto-generated credentials are stored in the _credentials_dir_ - you will want to ensure that these are properly encrypted, checked into a git repository and kept private. The secret material is encrypted with ansible-vault, so it cannot be read without the access to the _.ansible_vault_pw_. If you commit these files, and push them to a respository, then you can share them with other admins, but be aware that these are secrets that should not be shared with anyone but trusted admins. If you gpg encrypted the _.ansible_vault_pw_, then that file is also encrypted and could also be committed.
cyberta's avatar
cyberta committed
104 105 106 107 108 109 110

## 6. Ensure SSH access
Be sure you can ssh to the hosts as root with a public key that will not be prompting you for a password every time; you should have also verified and accepted the correct host key.

## 7. Deploy the configuration 

Run: 
cyberta's avatar
cyberta committed
111
```shell
cyberta's avatar
cyberta committed
112
float/float run site.yml 
cyberta's avatar
cyberta committed
113 114 115 116 117 118 119
```
This will take some time to finish, as it needs to download packages and Docker images and configure everything.

## 8. Update servers

Run:

120
```shell
cyberta's avatar
cyberta committed
121 122 123
float/float run float/playbooks/apt-upgrade.yml
```

124
Congratulations. You have successfully installed and deployed the LEAP platform! You should [read the documentation about how to perform common operations](https://git.autistici.org/ai3/float/-/blob/master/docs/playbook.md).
cyberta's avatar
cyberta committed
125

126 127 128 129
## Testing

Certificate authority from provider: `leap.ca`

cyberta's avatar
cyberta committed
130
Make a CSR/key
131

cyberta's avatar
cyberta committed
132
sign cert against CA
133

cyberta's avatar
cyberta committed
134
make sure the x509 v3 extensions exist: x509.ExtKeyUsageClientAuth x509.KeyUsageDigitalSignature
135 136

```shell
kwadronaut's avatar
kwadronaut committed
137
/usr/sbin/openvpn --client --remote-cert-tls server --tls-client --remote 37.218.241.84 1194 --proto tcp --verb 3 --auth SHA1 --keepalive 10 30 --tls-version-min 1.2 --dev tun --tun-ipv6 --ca ./ca.pem --cert ./testopenvpn.crt --key ./testopenvpn.key
138
```
cyberta's avatar
cyberta committed
139 140 141

Reference: https://0xacab.org/leap/vpnweb/blob/master/certs.go#L37

142 143 144 145 146
        ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
        KeyUsage:    x509.KeyUsageDigitalSignature,
        CommonName: UNLIMITED
        subjectkeyID: random
        serial: random
cyberta's avatar
cyberta committed
147

148
### Integration Testing
cyberta's avatar
cyberta committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
Integration tests can be run to:
            * check that public endpoints for built-in services are reachable
            * check that no Prometheus alerts are firing

These tests can be run from your Ansible directory using the *float*
command-line tool:

```shell
/path/to/float/float run integration-test
```

The test suite requires a small amount of configuration in order to
run on a non-test environment, as it needs admin credentials in order
to automatically test SSO-protected services. This is stored in a YAML
file, you can point the test suite at your own test parameters using
the `TEST_PARAMS` environment variable, e.g.:

```shell
env TEST_PARAMS=my-params.yml /path/to/float/float run integration-test
```

The built-in test parameters configuration uses the credentials for
the default admin user used in test environments (*admin*/*password*):

```yaml
---
priv_user:
  name: admin
  password: password
```

180
### Testing float
cyberta's avatar
cyberta committed
181

182 183 184 185 186 187 188
```shell
    apt install qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils vagrant vagrant-libvirt
    adduser micah libvirt
    adduser micah libvirt-quemu
    float create-env --vagrant --num-hosts 2 test
    cd test; vagrant up
```
cyberta's avatar
cyberta committed
189

190
### FAQ
cyberta's avatar
cyberta committed
191

192
***Why is there a '[openvpn]' group, but no host attached to it?***
cyberta's avatar
cyberta committed
193

194
You might have noticed that site.yml has a hosts parameter with roles assigned to them, and the actual hosts defined in site.yml are connected to the hosts.yml groups parameter. The hosts.yml has floatrp1 with the groups: `[frontend]`, but there is no host which has the `[openvpn]` group attached to it.
cyberta's avatar
cyberta committed
195

196
For the 'openvpn' service, there is a scheduling_group, which sets the *scope* of the possible hosts that the service will be scheduled onto. Float will create automatically a 'openvpn' group, containing just the hosts that 'openvpn' is running on. We did not define an 'openvpn' group in the hosts.yml ansible inventory, yet such a group is automatically created by float, and you can use it in Ansible. This 'openvpn' group is a subset of the scheduling_group.
cyberta's avatar
cyberta committed
197

198
***"where can I run openvpn"*** -> scheduling_group (frontend) 
cyberta's avatar
cyberta committed
199

200
***"where is openvpn actually running"**** -> "openvpn" group
cyberta's avatar
cyberta committed
201