Add support for High Availability

This patch adds the ability to configure the Luna Network HSM
client to use more than one HSM for high availability (HA) mode.

Change-Id: If0eb393ca970206cc95c7453641f33781eb698b2
This commit is contained in:
Douglas Mendizábal 2020-07-13 15:41:50 -05:00
parent ce3e955a1d
commit b4eaaeb9cc
5 changed files with 148 additions and 87 deletions

View File

@ -1,11 +1,14 @@
lunasa-hsm lunasa-hsm
========== ==========
A role to manage Safenet Lunasa Hardware Security Module (HSM) client software. A role to manage Thales Luna Network Hardware Security Module (HSM) clients.
Role Variables Role Variables
-------------- --------------
This ansible role automates the configuration of a new client for the
Thales Luna Network HSM.
.. list-table:: .. list-table::
:widths: auto :widths: auto
:header-rows: 1 :header-rows: 1
@ -25,18 +28,22 @@ Role Variables
* - lunasa_client_installer_path * - lunasa_client_installer_path
- None - None
- Path to the instal.sh script inside the tarball. - Path to the instal.sh script inside the tarball.
* - lunasa_hsm_server_hostname * - lunasa_client_pin
- None - None
- Hostnme for the Lunasa HSM. - The HSM Partition Password (PKCS#11 PIN) to be used by the client.
* - lunasa_hsm_server_admin_password
- None
- Password for the admin user for the Lunasa HSM.
* - lunasa_hsm_partition
- None
- HSM Partition to assign the client.
* - lunasa_client_ip * - lunasa_client_ip
- None - None
- IP to use when registering the client. - (Optional) When set, this role will use the given IP to register
the client instead of the client's fqdn.
* - lunasa_client_rotate_cert
- False
- When set to True, the role will generate a new client certificate
to replace the previous one.
* - lunasa_hsms
- None
- List of dictionaries, each of which describes a single HSM
`see vars.sample.yaml` for details. When more than one HSM is
listed here, the client will be configured in HA mode.
Requirements Requirements
------------ ------------

View File

@ -1,12 +1,4 @@
--- ---
# TODO: maybe use random tmpdir here
lunasa_client_working_dir: /tmp/lunasa_client_install lunasa_client_working_dir: /tmp/lunasa_client_install
lunasa_client_rotate_cert: false
# non-defaults lunasa_ha_label: myHAgroup
#lunasa_client_tarball_location: http://download-node-02.eng.bos.redhat.com/qa/rhts/lookaside/IdM/rhcs/lunasa_software/610-012382-014_SW_Client_HSM_6.2_RevA.tar.zip
#lunasa_client_tarball_name: 610-012382-014_SW_Client_HSM_6.2_RevA.tar.zip
#lunasa_client_installer_path: 610-012382-014_SW_Client_HSM_6.2_RevA/linux/64/install.sh
#lunasa_hsm_server_hostname: os-luna-hsm-1.perf.lab.eng.rdu2.redhat.com
#lunasa_hsm_server_admin_password: ABC123!!!
#lunasa_hsm_partition: secdfgPartition1
#lunasa_client_ip: 10.0.79.37

View File

@ -1,9 +1,9 @@
--- ---
- name: Create working directory - name: Create working directory
file: file:
path: "{{ lunasa_client_working_dir }}" path: "{{ lunasa_client_working_dir }}"
state: directory state: directory
mode: 0755 mode: 0755
- name: Download Lunasa client tarball - name: Download Lunasa client tarball
get_url: get_url:
@ -26,22 +26,59 @@
creates: /usr/lib/libCryptoki2_64.so creates: /usr/lib/libCryptoki2_64.so
become: true become: true
- name: register the client to the HSMs - name: set client facts for fqdn
include_tasks: register_hsm.yaml set_fact:
loop: "{{ lunasa_hsms }}" client_name: "{{ ansible_fqdn }}"
client_reg_opt: "-hostname"
client_host: "{{ ansible_fqdn }}"
client_cert_cn: "{{ inventory_hostname }}"
when: lunasa_client_ip is undefined
- name: set client facts for IP override
set_fact:
client_name: "{{ ansible_fqdn }}"
client_reg_opt: "-ip"
client_host: "{{ lunasa_client_ip }}"
client_cert_cn: "{{ lunasa_client_ip }}"
when: lunasa_client_ip is defined
- name: Check for existing client cert
stat:
path: "/usr/safenet/lunaclient/cert/client/{{ client_host }}.pem"
register: client_cert
- name: Generate a new client cert for NTL
command: /usr/safenet/lunaclient/bin/vtl createCert -n "{{ client_cert_cn }}"
become: true
register: created_cert
when: not client_cert.stat.exists or lunasa_client_rotate_cert
- name: Note when a new cert is created
set_fact:
client_new_cert: "{{ created_cert.changed }}"
- name: register the client on each HSM
include_tasks: register_client.yaml
vars: vars:
hsm_name: "{{ item.name }}"
hsm_hostname: "{{ item.hostname }}" hsm_hostname: "{{ item.hostname }}"
hsm_admin_password: "{{ item.admin_password }}" hsm_admin_password: "{{ item.admin_password }}"
client_ip: "{{ item.client_ip }}"
hsm_partition: "{{ item.partition }}" hsm_partition: "{{ item.partition }}"
loop: "{{ lunasa_hsms }}"
- name: verify the NTL connection - name: verify the NTL connection
command: /usr/safenet/lunaclient/bin/vtl verify command: /usr/safenet/lunaclient/bin/vtl verify
become: true become: true
register: vtl_verify
- name: Fail if NTL connection doesn't verify
fail:
msg: >
ERROR: 'vtl verify' failed. This is commonly due to network NAT between
the client and the HSM. Try disabling client IP checking in the HSM
when: "'Error: Unable to find any Luna SA slots/partitions' in vtl_verify.stdout"
- name: create hsm ha partition - name: create hsm ha partition
when: lunasa_ha_label is defined when: lunasa_hsms | length > 1
become: true become: true
block: block:
- name: create ha partition - name: create ha partition
@ -49,7 +86,7 @@
echo 'copy' | /usr/safenet/lunaclient/bin/lunacm -c hagroup createGroup \ echo 'copy' | /usr/safenet/lunaclient/bin/lunacm -c hagroup createGroup \
-label {{ lunasa_ha_label }} \ -label {{ lunasa_ha_label }} \
-serialNumber {{ lunasa_hsms[0].partition_serial }} \ -serialNumber {{ lunasa_hsms[0].partition_serial }} \
-password {{ lunasa_partition_password }} -password {{ lunasa_client_pin }}
register: result register: result
failed_when: failed_when:
- "'Command Result : No Error' not in result.stdout" - "'Command Result : No Error' not in result.stdout"
@ -60,7 +97,7 @@
echo 'copy' | /usr/safenet/lunaclient/bin/lunacm -c hagroup addMember \ echo 'copy' | /usr/safenet/lunaclient/bin/lunacm -c hagroup addMember \
-group {{ lunasa_ha_label }} \ -group {{ lunasa_ha_label }} \
-serialNumber {{ item.partition_serial }} \ -serialNumber {{ item.partition_serial }} \
-password {{ lunasa_partition_password }} -password {{ lunasa_client_pin }}
loop: "{{ lunasa_hsms }}" loop: "{{ lunasa_hsms }}"
loop_control: loop_control:
extended: yes extended: yes
@ -86,3 +123,7 @@
- name: Set HA Slot fact for use by the playbook calling this role - name: Set HA Slot fact for use by the playbook calling this role
set_fact: set_fact:
lunasa_ha_slot: "{{ slot_result.stdout }}" lunasa_ha_slot: "{{ slot_result.stdout }}"
- name: Log the HA Slot ID used
debug:
var: lunasa_ha_slot

View File

@ -0,0 +1,77 @@
---
- name: Log when client is being registered to HSM
debug:
msg: "Registering client: {{ client_name }} [{{ client_host }}] with HSM: {{ hsm_hostname }}"
- name: Get the hsm server cert from the hsm_server
shell: >
sshpass -p '{{ hsm_admin_password }}'
scp -o StrictHostKeyChecking=false -c aes256-cbc
admin@{{ hsm_hostname }}:server.pem
/usr/safenet/lunaclient/bin/{{ hsm_hostname }}.pem
args:
creates: /usr/safenet/lunaclient/bin/{{ hsm_hostname }}.pem
become: true
- name: Register the HSM server cert with the client
shell: >
/usr/safenet/lunaclient/bin/vtl addServer -n {{ hsm_hostname }}
-c /usr/safenet/lunaclient/bin/{{ hsm_hostname }}.pem
register: add_server
become: true
failed_when:
- add_server.rc != 0
- '"This server is already registered" not in add_server.stdout'
- name: Check for existing clients
shell: >
sshpass -p '{{ hsm_admin_password }}'
ssh -o StrictHostKeyChecking=false -c aes256-cbc admin@{{ hsm_hostname }}
-C client list
register: client_list
- name: Fail if client is already registered, but we don't have that cert
fail:
msg: "Client: {{ client_name }} is already registered, but the client cert is missing!"
when:
- client_name in client_list.stdout
- client_new_cert
- not lunasa_client_rotate_cert
- name: Delete existing client when rotating certs
shell: >
sshpass -p '{{ hsm_admin_password }}' ssh -c aes256-cbc admin@{{ hsm_hostname }}
-C "client delete -f -c {{ client_name }}"
when:
- client_name in client_list.stdout
- lunasa_client_rotate_cert
- name: Register the client certificate on the hsm_server
block:
- name: Copy the NTL client cert to the HSM
shell: >
sshpass -p '{{ hsm_admin_password }}' scp -c aes256-cbc
/usr/safenet/lunaclient/cert/client/{{ client_host }}.pem
admin@{{ hsm_hostname }}:{{ client_host }}.pem
- name: Register the client
shell: >
sshpass -p '{{ hsm_admin_password }}' ssh -c aes256-cbc admin@{{ hsm_hostname }}
-C "client register -c {{ client_name }} {{ client_reg_opt }} {{ client_host }}"
register: client_register
failed_when:
- client_register.rc != 0
- "'client with the same IP address has already been registered' not in client_register.stdout"
become: true
when: client_name not in client_list.stdout or lunasa_client_rotate_cert
- name: Assign client to an HSM partition
shell: |
sshpass -p '{{ hsm_admin_password }}' ssh -c aes256-cbc admin@{{ hsm_hostname }} \
-C "client assignPartition -c {{ client_name }} -p {{ hsm_partition }}"
register: assign_partition
failed_when:
- assign_partition.rc != 0
- "'client already has access' not in assign_partition.stdout"
become: true

View File

@ -1,56 +0,0 @@
---
- debug:
msg: "Registering the following HSM: {{ hsm_name }}"
- name: Get the hsm server cert from the hsm_server
shell: |
sshpass -p '{{ hsm_admin_password }}' \
scp -o StrictHostKeyChecking=false admin@{{ hsm_hostname }}:server.pem /usr/safenet/lunaclient/bin/{{ hsm_hostname }}.pem
become: true
- name: Register the HSM server cert with the client
shell: |
/usr/safenet/lunaclient/bin/vtl addServer -n {{ hsm_hostname }} \
-c /usr/safenet/lunaclient/bin/{{ hsm_hostname }}.pem
register: add_server
become: true
failed_when:
- add_server.rc != 0
- '"This server is already registered" not in add_server.stdout'
- name: Set the cert file name
set_fact:
client_name: "{{ inventory_hostname }}"
- name: Create a client cert for NTL
command: /usr/safenet/lunaclient/bin/vtl createCert -n "{{ client_ip }}"
args:
creates: "/usr/safenet/lunaclient/cert/client/{{ client_ip }}.pem"
become: true
- name: Copy the NTL client cert to the HSM
shell: |
sshpass -p '{{ hsm_admin_password }}' scp /usr/safenet/lunaclient/cert/client/{{ client_ip }}.pem \
admin@{{ hsm_hostname }}:{{ client_ip }}.pem
become: true
# A client with the same hostname has already been registered
- name: Register the client certificate on the hsm_server
shell: |
sshpass -p '{{ hsm_admin_password }}' ssh admin@{{ hsm_hostname }} \
-C "client register -c {{ client_name }} -ip {{ client_ip }}"
register: client_register
failed_when:
- client_register.rc != 0
- "'client with the same IP address has already been registered' not in client_register.stdout"
become: true
- name: Assign client to an HSM partition
shell: |
sshpass -p '{{ hsm_admin_password }}' ssh admin@{{ hsm_hostname }} \
-C "client assignPartition -c {{ client_name }} -p {{ hsm_partition }}"
register: assign_partition
failed_when:
- assign_partition.rc != 0
- "'client already has access' not in assign_partition.stdout"
become: true