Requirements
A machine to which you have ssh access
A user on that machine that has passwordless sudo access for the
/usr/bin/chef-solo
command so that you don't have to login as root (the machine doesn't need to have chef-solo actually installed yet)Ruby 1.9.3 or higher, Berkshelf 3.2.1 and knife-solo 0.4.2 installed on your local machine (the machine which will launch the deploy)
The Primero repository checked out
An SSL certificate and key for the application
An SSL certificate and key for CouchDB (for syncing over the internet)
A JSON attribute node file that corresponds to the node being deployed
To install Berkshelf and Knife-solo on your local machine, you need a working Ruby environment. Then you can run:
$ gem install berkshelf --version 3.2.1
$ gem install knife-solo --version 0.4.2
Try and run this as your normal user. If you get permission errors you will have to run the gem install command as root.
Application SSL
To get the application SSL cert, you must go through a recognized Certificate Authority (CA) or a CA which is trusted by the browsers of the primary users of this Primero deployment. It is currently not possible to run Primero except through HTTPS, nor is it advisable to run any part of Primero except under HTTPS.
CouchDB SSL
The CouchDB SSL cert uses a private CA whose root certificate is distributed automatically to all of the servers to verify communication. To generate a new key and cert, follow the next steps.
Initial Setup
To setup a new root Certificate Authority to sign CouchDB certs, you need to configure your machine as your own certificate authority (CA). Create the next directories and files to save the certificates and keys. You may need to do it as sudo.
$ mkdir /etc/pki/CA
$ cd /etc/pki/CA
$ mkdir certs crl newcerts private
$ chmod 700 private
$ touch index.txt
$ echo 1000 > serial
$ gem install knife-solo --version 0.4.2
Also it is necessary to create a root key and a root certificate, that identifies the certificate authority. To generate the root key with the proper encryption:
$ sudo openssl genrsa -aes256 -out /etc/pki/CA/private/couch_ca.key 4096
Enter pass phrase **for** ca.key.pem: secretpassword
Verifying - Enter pass phrase **for** ca.key.pem: secretpassword
$ sudo chmod 400 /etc/pki/CA/private/couch_ca.key
Open the file /ect/ssl/openssl.cnf
Change the field dir = /etc/pki/CA
on [ CA_default ]. Also make sure the following fields look like
this:
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
basicConstraints=CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ v3_ca ]
# Extensions for a typical CA
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
keyUsage = cRLSign, keyCertSign
To generate the root certificate:
$ sudo openssl req -new -x509 -days 3650 -key /etc/pki/CA/private/couch_ca.key -sha256 -extensions v3_ca -out /etc/pki/CA/certs/couch_ca.cert
$ sudo chmod 444 /etc/pki/CA/certs/ca.cert.pem
You should set up your own config.cnf
file based on your organization's
policy and contact information. See the openssl docs for more info on
how to configure things.
Creating and Signing New Certs
Once you have a CA set up, you can make new keys and certs for individual CouchDB instances. Go to the root directory of your CA.
To create a new key:
openssl genrsa -out < HOST_NAME>.key 2048
To create a Certificate Signing Request with a key:
openssl req -new -key <HOST_NAME>.key -out <HOST_NAME>.csr -config config.cnf
To sign the CSR and make a Cert using the root CA key:
openssl ca -in <HOST_NAME>.csr -config config.cnf
All clients using HTTPS must have trust the root cert in the file couch_ca.crt.
You must configure the node file (see below) to provision this new CA
certificate onto the deployed server so that it can verify remote
connections upon replication. You can either overwrite the file
cookbook/files/couch_ca.crt
with your own root cert or you can move the
cert into another file in that directory and set the
primero.couchdb.root_ca_cert_source
attribute in the node file to
point to that new file. See below for more information on this
attribute.
Node File
Next you will need a node file: a JSON file that defines various deployment attributes. You can copy the file dev-node.json in the root of this repo for a reference to a more or less complete node file for Primero. You can put the node file anywhere you like on your system.
Attributes
The following attributes are of special interest for configuration:
primero.server_hostname
(required): The DNS hostname of the server. The site should be accessed with this host name.primero.git.revision
(default: master): The commit id/tag/branch name to deployprimero.deploy_key
(required): An ssh private key that is configured in the Quoin bitbucket repo (under deployment keys) to allow read-only access to the codeprimero.couchdb.password
(required): The CouchDB password for the admin user--this will replace any existing passwordprimero.couchdb.ssl.cert
(required): The CouchDB SSL certificate, formatted to replace all newlines with '\n'primero.couchdb.ssl.key
(required): The CouchDB SSL secret key, formatted to replace all newlines with '\n'primero.ssl.cert
(required): The app SSL certificate, formatted to replace all newlines with '\n'--the hostname in this cert should match the primero.server_hostname value.primero.ssl.key
(required): The app SSL secret key, formatted to replace all newlines with '\n'primero.couchdb.root_ca_cert_source
(default:couch_ca.crt
): The source path of the Couch CA certificate that is used to verify other CouchDB instances when syncing. This is a path is relative to the files/default directory in this repo. You should add the CA cert there.
You set them by specifying them in JSON in the node file. For example, if you want to set the hostname to example.com, just put the following in your node file:
{
"primero": {
... other attibutes ...
"server_hostname": "example.com",
... other attibutes ...
},
"run_list": [ "recipe[primero::default]" ]
}
`
Runlist
You should set your runlist to [ "recipe[primero::default]" ]
for
any standard deploy.
Deployment
Once you have the requirements installed, you can run the following two commands from the cookbook folder of the repo (cookbook directory must be able to be read by other users):
$ ssh USER@APP_HOST 'which chef-solo' || knife solo prepare --bootstrap-version=11.10.4 USER@APP_HOST
$ knife solo cook USER@APP_HOST NODE_FILE
Replacing USER with the remote user, APP_HOST with the remote machine host, and NODE_FILE with the Chef node json file to use for this deploy. It will take a few minutes to run to completion.
Ports and Firewalls
The main Primero application is just like any other HTTPS enabled web application and runs on ports 80 and 443 for HTTP and HTTPS, respectively. The application server forces the use client to the HTTPS port immediately upon the first request, so port 80 should be accessible to reduce confusion of the users who manually type the URL into the browser.
If you want to be able to sync the CouchDB data between servers, you need to open port 6984 on the target server of the replication configuration. The server that is initiating the sync does not require the CouchDB port to be open.
For debugging and test purposes, you may also wish to expose the CouchDB HTTPS port (6984) and/or the Solr Admin port (8983). The Solr admin should never be exposed to the entire internet under any circumstances, as it contains sensitive data. If you must expose it in your firewall, restrict the source IP to one that you control.
Roving Instances
The roving field instances of Primero have similar firewall/port requires to the above, except that you will be using the Windows firewall combined with Virtualbox's port forwarding settings. When you first installed Primero on Windows, it should have prompted you to approve a Windows Firewall rule to expose port 11443 (or something similar). If you approved this, Primero is accessible on at least your local network through that port.
There are other ports that forwarded from the VM, but they are only bound to localhost on the Windows host, so they will not be accessible on the local network no matter what the Windows firewall settings.
If you are syncing between a roving Primero instance and a central Primero instance, the central Primero instance's database must be exposed (port 6984). Then, you can set up the sync config on the roving instance, pointing to the central server as the target.
Hosted Instances
On hosted instance of Primero, there could be a wide variety of potential firewall solutions available. If it is hosted on a cloud environment like AWS or Azure, those services provide firewall configuration in the management consoles.
In the absence of any simple cloud firewall configuration, you could configure UFW on the same machine as the application. This will configure the machine's packet filtering system for you and is fairly easy to use.