Bastion+ with Dedicated Portal and External DB

Overview of a Bastion+ WebSocket setup with an external PostgreSQL database hosted by a third party.

Prerequisites

Retrieve the following Ansible roles:

reemo-infra
reemo-provision
reemo-relayws

Have a license key.

Architecture

../../_static/images/infra/bastion_ws_postgres.png

Overview of the infrastructure for a Bastion+ installation with a Dedicated Portal and External DB

Flow Matrix

DESCRIPTION

TRANSPORT

SOURCE IP

SOURCE PORT

DESTINATION IP

DESTINATION PORT

SERVICES

Portal -> API

TCP

10.1.1.1 | 10.1.1.2 | 10.1.1.3

1024:65535

10.3.1.1 | 10.3.1.2 | 10.3.1.3

443

HTTPS

API -> PROVISION

TCP

10.3.1.1 | 10.3.1.2 | 10.3.1.3

1024:65535

10.4.1.1 | 10.4.1.2 | 10.4.1.3

8443

HTTPS

API -> RELAY

TCP

10.3.1.1 | 10.3.1.2 | 10.3.1.3

1024:65535

10.2.1.1 | 10.2.1.2 | 10.2.1.3

443,8443

HTTPS

API -> PostgreSQL

TCP

10.3.1.1 | 10.3.1.2 | 10.3.1.3

1024:65535

10.7.1.1

5432

PostgreSQL

Infra Admin -> PostgreSQL

TCP

10.5.1.1 | 10.5.1.2

1024:65535

10.7.1.1

5432

PostgreSQL

Infra Admin -> Provision

TCP

10.5.1.1 | 10.5.1.2

1024:65535

10.4.1.1 | 10.4.1.2 | 10.4.1.3

8443

HTTPS

Admin -> Infra Admin

TCP

10.6.1.0/24

1024:65535

10.5.1.1 | 10.5.1.2

443

HTTPS

PROVISION -> Internet Portal

TCP

10.4.1.0/24

1024:65535

10.1.1.1 | 10.1.1.2 | 10.1.1.3

8443

HTTPS

PROVISION -> RELAY

TCP

10.4.1.0/24

1024:65535

10.2.1.1 | 10.2.1.2 | 10.2.1.3

443

HTTPS

INTERNET -> RELAY

TCP

WAN

1024:65535

10.2.1.1 | 10.2.1.2 | 10.2.1.3

443

HTTPS

INTERNET -> INFRA

TCP

WAN

1024:65535

10.1.1.1 | 10.1.1.2 | 10.1.1.3

443

HTTPS

Initialization

On all three environments, run the following command to initialize Docker Swarm:

docker swarm init

In multi-node environments, link the different nodes with the docker swarm join commands.

Infra Environment: Swarm Manager Provision Environment: Swarm Manager + Worker Relay Environment: Swarm Manager

Ansible Inventory File

all:
    vars:
        INIT_TYPE: "bastion"
        DOCKER_VERSION: preprod
        API_LICENSE: "ewogICAg ... Uw5NXhGVDF0NFU2TkxOdjQvZU53PT0iCiAgICC9Cn0="
        HMACSECRET: "Taikohshugh8tahb2m"
    portal_manager:
        children:
            portaluser_manager:
                vars:
                    PORTAL_SWARM_ADVERTISE_ADDR: "10.1.1.1"
                    PORTAL_URL: "user.domain.tld"
                    PORTAL_TYPE: "user"
                    TRAEFIK_SSL_CERTS:
                      - cert_file: "/localpath/to/cert_domain.tld.crt"
                        key_file: "/localpath/to/key_domain.tld.key"
                    API_IP:
                        - ip: "10.3.1.1"
                        - ip: "10.3.1.2"
                        - ip: "10.3.1.3"
                hosts:
                    portaluser1:
                        ansible_host: "10.1.1.1"
                    portaluser2:
                        ansible_host: "10.1.1.2"
                    portaluser3:
                        ansible_host: "10.1.1.3"

    infra_manager:
        vars:
            PORTAL_URL: "admin.domain.local"
            PORTAL_TYPE: "admin"
            DB_USER: "reemo"
            DB_USER_PASSWORD: "reemo"
            DB_NAME: "reemo"
            DB_HOST: "10.7.1.1"
            DB_PORT: "5432"
            DB_DIALECT: "postgresql"
            DB_SSL_REQUIRE: "true"
            DB_SSL_CRT_LOCALPATH: "/localpath/to/postgresql_ssl.crt"
            DB_SSL_KEY_LOCALPATH: "/localpath/to/postgresql_ssl.key"
            DB_SSL_CA_LOCALPATH: "/localpath/to/postgresql_ssl.ca"
            CRON_ENABLE: "false"
            TRAEFIK_SSL_CERTS:
                - cert_file: "/localpath/to/admin_domain.local.crt"
                  key_file: "/localpath/to/admin_domain.local.key"
            PROVISION_IP:
                - ip: "10.4.1.1"
                - ip: "10.4.1.2"
                - ip: "10.4.1.3"
        children:
            infra_manager1:
                hosts:
                    admin1:
                        ansible_host: "10.5.1.1"
            infra_manager2:
                hosts:
                    admin2:
                        ansible_host: "10.5.1.2"


    api_manager:
        vars:
            DB_USER: "reemo"
            DB_USER_PASSWORD: "reemo"
            DB_NAME: "reemo"
            DB_HOST: "10.7.1.1"
            DB_PORT: "5432"
            DB_DIALECT: "postgresql"
            DB_SSL_REQUIRE: "true"
            DB_SSL_CRT_LOCALPATH: "/localpath/to/postgresql_ssl.crt"
            DB_SSL_KEY_LOCALPATH: "/localpath/to/postgresql_ssl.key"
            DB_SSL_CA_LOCALPATH: "/localpath/to/postgresql_ssl.ca"
            RELAYS_URL: "relay.domain.tld"
            API_SWARM_ADVERTISE_ADDR: "10.3.1.1"
            PROVISION_SIGNAL_IP:
                - ip: "10.1.1.1"
                - ip: "10.1.1.2"
                - ip: "10.1.1.3"
            PROVISION_IP:
                - ip: "10.4.1.1"
                - ip: "10.4.1.2"
                - ip: "10.4.1.3"
            RELAYS_IP:
                - ip: "10.2.1.1"
                - ip: "10.2.1.2"
                - ip: "10.2.1.3"
        hosts:
            api1:
                ansible_host: "10.3.1.1"
            api2:
                ansible_host: "10.3.1.2"
            api3:
                ansible_host: "10.3.1.3"

    provision:
        vars:
            PROVISION_SWARM_ADVERTISE_ADDR: "10.4.1.1"
        children:
            provision_manager:
                hosts:
                    provision_manager1:
                        ansible_host: "10.4.1.1"
                    provision_manager2:
                        ansible_host: "10.4.1.2"
                    provision_manager3:
                        ansible_host: "10.4.1.3"
            provision_worker:
                hosts:
                    provision_worker1:
                        ansible_host: "10.4.1.4"
                    provision_worker2:
                        ansible_host: "10.4.1.5"
                    provision_worker3:
                        ansible_host: "10.4.1.6"
                    provision_worker4:
                        ansible_host: "10.4.1.7"
                    provision_worker5:
                        ansible_host: "10.4.1.8"

    relayws_manager:
        vars:
            RELAYWS_SWARM_ADVERTISE_ADDR: "10.2.1.1"
            TRAEFIK_SSL_CERTS:
                - cert_file: "/localpath/to/cert_domain.tld.crt"
                  key_file: "/localpath/to/key_domain.tld.key"
        hosts:
            relayws_manager1: 
                ansible_host: "10.2.1.1"
            relayws_manager2: 
                ansible_host: "10.2.1.2"
            relayws_manager3: 
                ansible_host: "10.2.1.3"

Installation

Prerequisites

Have the following Ansible roles:

  • reemo-infra

  • reemo-provision

  • reemo-relayws

Have the following playbooks:

reemo-infra.yml

- name: Reemo Infra Server Installation
  hosts: infra_manager,portal_manager,api_manager
  gather_facts: yes

  roles:
      - role: reemo-infra
        become: yes

reemo-provision.yml

- name: Deploy Reemo Provision environment in swarm cluster
  hosts: provision,provision_manager
  gather_facts: yes

  roles:
      - role: reemo-provision
        become: yes

reemo-relayws.yml

- name: Reemo Relay WebSocket Installation
  hosts: relayws_manager
  gather_facts: yes

  roles:
      - role: reemo-relayws
        become: yes

With Internet

If hosts have Internet access and you want to automate Docker installation and Swarm initialization, use:

ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit api_manager --extra-vars "INIT_DB=true" --extra-vars "INSTALL_DOCKER=true" --extra-vars "API_SWARM_ADVERTISE_ADDR=10.3.1.1"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit portaluser_manager --extra-vars "INSTALL_DOCKER=true" --extra-vars "PORTAL_SWARM_ADVERTISE_ADDR=10.1.1.1"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager1 --extra-vars "INSTALL_DOCKER=true" 
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager2 --extra-vars "INSTALL_DOCKER=true"
ansible-playbook -i inventory.yml playbooks/reemo-provision.yml --extra-vars "PROVISION_INSTALL_DOCKER=true" --extra-vars "PROVISION_SWARM_ADVERTISE_ADDR=10.4.1.1"
ansible-playbook -i inventory.yml playbooks/reemo-relayws.yml --extra-vars "RELAYWS_INSTALL_DOCKER=true" --extra-vars "RELAYWS_SWARM_ADVERTISE_ADDR=10.2.1.1"

If you want to specify a network interface instead of an IP for Swarm initialization:

ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit api_manager --extra-vars "INIT_DB=true" --extra-vars "INSTALL_DOCKER=true" --extra-vars "API_SWARM_ADVERTISE_ADDR=eth0"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit portaluser_manager --extra-vars "INSTALL_DOCKER=true" --extra-vars "PORTAL_SWARM_ADVERTISE_ADDR=eth0"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager1 --extra-vars "INSTALL_DOCKER=true" 
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager2 --extra-vars "INSTALL_DOCKER=true"
ansible-playbook -i inventory.yml playbooks/reemo-provision.yml --extra-vars "PROVISION_INSTALL_DOCKER=true" --extra-vars "PROVISION_SWARM_ADVERTISE_ADDR=eth0"
ansible-playbook -i inventory.yml playbooks/reemo-relayws.yml --extra-vars "RELAYWS_INSTALL_DOCKER=true" --extra-vars "RELAYWS_SWARM_ADVERTISE_ADDR=eth0"

Without Internet

If there is no Internet access, install Docker on all hosts and initialize Docker Swarm before running the roles.

ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --extra-vars "TARBALL_GENERATE=true" --extra-vars "TARBALL_PATH=/opt/reemo/images" --tags tarball_generate
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit api_manager --extra-vars "INIT_DB=true" --extra-vars "TARBALL_PATH=/opt/reemo/images" --extra-vars "LOAD_IMAGE=true"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit portaluser_manager --extra-vars "TARBALL_PATH=/opt/reemo/images" --extra-vars "LOAD_IMAGE=true"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager1 --extra-vars "TARBALL_PATH=/opt/reemo/images" --extra-vars "LOAD_IMAGE=true"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager2 --extra-vars "TARBALL_PATH=/opt/reemo/images" --extra-vars "LOAD_IMAGE=true"
ansible-playbook -i inventory.yml playbooks/reemo-provision.yml
ansible-playbook -i inventory.yml playbooks/reemo-relayws.yml --extra-vars "TARBALL_PATH=/opt/reemo/images" --extra-vars "LOAD_IMAGE=true"

Automatic Docker Swarm Initialization

If you have no Internet access and want the roles to initialize your Docker Swarm environment:

Add the option SWARM_INIT=true to the different installation commands.

ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit api_manager --extra-vars "INIT_DB=true" --exra-vars "SWARM_INIT=true"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit portaluser_manager --exra-vars "SWARM_INIT=true"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager1 --exra-vars "SWARM_INIT=true"
ansible-playbook -i inventory.yml playbooks/reemo-infra.yml --limit infra_manager2 --exra-vars "SWARM_INIT=true"
ansible-playbook -i inventory.yml playbooks/reemo-provision.yml --exra-vars "SWARM_INIT=true"
ansible-playbook -i inventory.yml playbooks/reemo-relayws.yml --exra-vars "SWARM_INIT=true"

Update

Run the following command to load all new images on the different components of the architecture:

ansible-playbook -i inventory.yml playbooks/reemo-infra-images.yml

Connect to a manager of each environment and run the update command for the service to upgrade. For example, to update the API:

docker service update reemo_api --force

Warning

Docker Swarm will stop services one by one and redirect traffic to available nodes. No service interruption.