diff --git a/docs/admin/_category_.yml b/docs/admin/_category_.yml new file mode 100644 index 0000000..fc2a715 --- /dev/null +++ b/docs/admin/_category_.yml @@ -0,0 +1,5 @@ +--- +label: Admin Guide +position: 30 +link: + type: "generated-index" diff --git a/docs/admin/intro.md b/docs/admin/intro.md new file mode 100644 index 0000000..e07d6bb --- /dev/null +++ b/docs/admin/intro.md @@ -0,0 +1,5 @@ +# Introduction + +:::warning[Under construction] +This documentation is a work in progress. Please [get in touch with us](mailto:help@cdr.link) if you have any questions. +::: \ No newline at end of file diff --git a/docs/agent/_category_.yml b/docs/agent/_category_.yml new file mode 100644 index 0000000..c38aca5 --- /dev/null +++ b/docs/agent/_category_.yml @@ -0,0 +1,5 @@ +--- +label: Agent Guide +position: 20 +link: + type: "generated-index" diff --git a/docs/agent/intro.md b/docs/agent/intro.md new file mode 100644 index 0000000..e07d6bb --- /dev/null +++ b/docs/agent/intro.md @@ -0,0 +1,5 @@ +# Introduction + +:::warning[Under construction] +This documentation is a work in progress. Please [get in touch with us](mailto:help@cdr.link) if you have any questions. +::: \ No newline at end of file diff --git a/docs/intro.md b/docs/intro.md index 2ce5bfb..52b92bb 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -5,3 +5,6 @@ sidebar_label: Overview # Documentation Overview +:::warning[Under construction] +This documentation is a work in progress. Please [get in touch with us](mailto:help@cdr.link) if you have any questions. +::: \ No newline at end of file diff --git a/docs/operator/_category_.yml b/docs/operator/_category_.yml index 0014a12..1b8a8ad 100644 --- a/docs/operator/_category_.yml +++ b/docs/operator/_category_.yml @@ -1,4 +1,5 @@ --- label: Operator Guide +position: 40 link: type: "generated-index" diff --git a/docs/operator/architecture.md b/docs/operator/architecture.md index f785630..db89ef0 100644 --- a/docs/operator/architecture.md +++ b/docs/operator/architecture.md @@ -20,7 +20,9 @@ network namespaces. Both [discretionary access controls](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/configuring_basic_system_settings/managing-file-system-permissions_configuring-basic-system-settings) -and SELinux are used to prevent lateral movement between containers should a container be compromised, with particular +and +[SELinux](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html-single/using_selinux/index) +are used to prevent lateral movement between containers should a container be compromised, with particular attention given to the messaging channels WhatsApp and Signal. No container runs its application as the inside "root" user, which is an unprivileged user on the host. @@ -33,7 +35,7 @@ prevent later investigation, and automatically shut down instances where there i ## Components The following diagram shows the dependency relationships between the components of CDR Link. -If you use our [Ansible role](./deploy) for deployment then these will be automatically configured. +If you use our [Ansible role](./deploy.md) for deployment then these will be automatically configured. The Link stack containers are [OCI](https://opencontainers.org/) compliant containers and you can run these with alternatives such as [Docker Compose](https://docs.docker.com/compose/) however we would not be able to provide support for this @@ -48,8 +50,8 @@ The service definitions are in `.container` units within the Quadlet directory a ```mermaid flowchart TD bridge-worker.service --> bridge-postgresql.service - bridge-worker.service --> bridge-whatsapp.service - bridge-worker.service --> signal-cli-rest-api.service + bridge-worker.service -.-> bridge-whatsapp.service + bridge-worker.service -.-> signal-cli-rest-api.service link.service --> bridge-postgresql.service link.service --> bridge-worker.service diff --git a/docs/operator/deploy-host.md b/docs/operator/deploy-host.md new file mode 100644 index 0000000..c8b3228 --- /dev/null +++ b/docs/operator/deploy-host.md @@ -0,0 +1,70 @@ +--- +sidebar_position: 30 +sidebar_label: Deployment Host +--- + +# Deployment Host Setup + +Deployment takes place using [Ansible](https://docs.ansible.com/) which we will install in a +[venv](https://docs.python.org/3/library/venv.html) to allow for careful management of the versions of the software in +use. + +For security, the deployment host must not run any network services listening on an external interface other than a +hardened SSH daemon if being used remotely. Ideally, the deployment host is operated locally via its terminal. + +Begin by creating a directory for the deployment framework to operate from that should be owned by your unprivileged +user and group and have filesystem permissions of `0700`. +On systems with SELinux, a context of `user_home_t` should be appropriate. + +This documentation will assume that you are working in the directory `$HOME/ops/`. + +## Virtual Environment Setup + +Begin by creating and activating a virtual environment: + +```shell +cd $HOME/ops +python3 -m venv venv +source venv/bin/activate +``` + +Then install the dependencies we will require: + +```shell +pip install ansible +pip install bitwarden-sdk # optional: only required for bitwarden secrets manager +``` + +## Install the Ansible collection and role dependencies + +Create `$HOME/ops/requirements.yml`: + +```yaml +--- +collections: + - name: bitwarden.secrets # optional: only required for bitwarden secrets manager + - src: git+https://guardianproject.dev/sr2/ansible-collection-core.git + version: main # optional: only required for our baseline role + - src: git+https://guardianproject.dev/sr2/ansible-collection-apps.git + version: main # required: contains the CDR Link deployment role +roles: + - src: git+https://github.com/ansible-lockdown/RHEL9-CIS.git + version: "2.0.3" # optional: only required for our baseline role +``` + +Install the collections, and roles if required: + +```shell +cd $HOME/ops +ansible-galaxy collection install -r requirements.yml +ansible-galaxy role install -r requirements.yml +``` + +## Create deployment data files and directories + +Create the necessary directories that we will need in the next step: + +```shell +cd $HOME/ops +mkdir {host,group}_vars +``` diff --git a/docs/operator/deploy.md b/docs/operator/deploy.md new file mode 100644 index 0000000..e63006f --- /dev/null +++ b/docs/operator/deploy.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 50 +sidebar_label: Deploy CDR Link +--- + +# Deploy the CDR Link Stack + +## Set up the Ansible inventory and host variables + +Create `$HOME/ops/inventory`: + +```ini +[cdr_link] +example.cdr.link +``` + +Create `$HOME/ops/group_vars/all.yml` if you use our baseline role and integrate with Identity Management: + +```yaml +--- +ipaserver_domain: CHANGEME +ipaserver_realm: CHANGEME +ipaserver_netbios_name: CHANGEME +``` + +Create `$HOME/ops/host_vars/example.cdr.link.yml`: + +```yaml +--- +baseline_second_disk_device: /dev/sdb # This is the device path for the data volume +baseline_home_luks_passphrase: CHANGEME +ipaclient_otp: CHANGEME # This is the OTP generated in the IdM step and is not sensitive after use +podman_link_podman_rootless_user: link_example # This is the user you created in the IdM step +podman_link_postgres_zammad_password: CHANGEME +podman_link_postgres_link_password: CHANGEME +podman_link_postgres_root_password: CHANGEME +podman_link_zammad_redis_password: CHANGEME +podman_link_opensearch_password: CHANGEME +podman_link_nextauth_secret: CHANGEME +``` + +:::warning +Do not store sensitive values in the `host_vars` file in plaintext, use lookup plugins to look up the secret values +using your secrets management solution of choice. +::: + +The variables prefixed with `baseline_` and `ipaclient_` are only applicable if you are using our baseline role with +Identity Management integration. +If you manage your own hardening and use local users and groups you can omit these. +The user you reference in `podman_link_podman_rootless_user` must exist before continuing. + +## Execute the Ansible playbook + +If you are using our baseline role: + +```shell +ansible-playbook -i inventory sr2.apps.link +``` + +If you manage your own hardening and identity management, use the `link` tag to only run the CDR Link stack deployment: + +```shell +ansible-playbook -i inventory sr2.apps.link --tags link +``` diff --git a/docs/operator/identity.md b/docs/operator/identity.md new file mode 100644 index 0000000..3f01e33 --- /dev/null +++ b/docs/operator/identity.md @@ -0,0 +1,73 @@ +--- +sidebar_position: 40 +sidebar_label: Identity Management +--- + +# Identity Management Setup + +:::tip +If you are using an alternative Identity Management system or local user accounts, skip this page and go straight +to [Deploying with Ansible](./deploy.md). +::: + +## Host Setup + +It can be helpful to keep track of the following information in a text editor's buffer until deployment is complete. +None of these details are sensitive after the completion of the deployment. + +```text +Hostname: +IPv4 Address: +IPv6 Address: +OTP: +``` + +### Add Host to DNS + +1. Create an A record for the host +1. Create an AAAA record for the host +1. Create a null MX record for the host (e.g. `example.cdr.link IN MX 0 .`) + +### Add Host to Identity Management + +1. Begin by logging in to the Identity Management server with your privileged identity +1. Open the **Identity** tab, and select the **Hosts** subtab +1. Click **Add** at the top of the hosts list +1. Enter the name of the new host, e.g. `example.cdr.link` +1. The IP address will be automatically resolved from DNS, you can leave this blank but may need to allow a moment for + the authoritative DNS servers to update +1. Activate the **Generate OTP** checkbox +1. Click **Add** to add the new host +1. Save the generated OTP for later + +![Screenshot of the Add Host Wizard in Identity Management](/img/host-add.png) + +## User Setup + +### Create the Service User + +This is the user on the host that will run the Podman containers. + +1. Open the **Identity** tab, and select the **Users** subtab +1. Click **Add** at the top of the users list +1. Enter a **Username**, we prefix all our Link service users with `link_` for easy identification +1. Enter a **First Name** and **Last Name**, these values do not matter but the LDAP schema requires them +1. Do not enter a **New Password** as this user will never need to authenticate with a password +1. Click **Add** + +![Screenshot of the Add User Wizard in Identity Management](/img/user-add.png) + +### Generate subordinate IDs for the user + +1. Open the **Identity** tab, and expand the **Subordinate IDs** subtab +1. Choose the **Subordinate IDs** option from the drop-down menu +1. Click the **Add** button in the upper-right corner of the interface +1. In the **Add subid** window, select the user you have just created as the **Owner** +1. Click **Add** + +The range is automatically generated and managed by Identity Management. + +:::tip +If you are not using our baseline Ansible role, ensure that the `with-subid` feature of the `sssd` authselect profile is +enabled to allow hosts to look up subids in LDAP. +::: \ No newline at end of file diff --git a/docs/operator/requirements.md b/docs/operator/requirements.md index ebcfc95..2a98595 100644 --- a/docs/operator/requirements.md +++ b/docs/operator/requirements.md @@ -19,9 +19,9 @@ A compromise of this host effectively compromises the entire stack. * Appropriately hardened and vendor supported Linux operating system with the latest security updates applied * SSH key backed by hardware security module and requiring unlock (e.g. [YubiKey](https://www.yubico.com/)) to be used for login to the instance host -* Python 3.11+ (the `venv` module is included in Python since v3.3 so this is not a separate requirement) -* Git -* Ansible-compatible secrets management (e.g. +* [Python](https://www.python.org/) 3.11+ (the `venv` module is included in Python since 3.3 so this is not a separate requirement) +* [Git](https://git-scm.com/) +* [Ansible](https://docs.ansible.com/)-compatible secrets management (e.g. [sops](https://getsops.io/) or [Bitwarden Secrets Manager](https://bitwarden.com/products/secrets-manager/)) diff --git a/static/img/host-add.png b/static/img/host-add.png new file mode 100644 index 0000000..9b6199f Binary files /dev/null and b/static/img/host-add.png differ diff --git a/static/img/user-add.png b/static/img/user-add.png new file mode 100644 index 0000000..a97377e Binary files /dev/null and b/static/img/user-add.png differ