From: sankar palanivel Date: Tue, 6 Oct 2020 12:35:12 +0000 (+0100) Subject: Automate nordix openvpn user config files X-Git-Url: https://gerrit.nordix.org/gitweb?a=commitdiff_plain;h=35f55f98da2088f79be1f5ae6aad5510d22117f3;p=infra%2Ftools.git Automate nordix openvpn user config files In this change, - Generate *.ovpn file in project specific Openvpn/jump server - Revoke user's Openvpn access from project specific Openvpn/jump server Change-Id: Ifb692a8a467cf511de4cb95a291c9d9ca6010224 --- diff --git a/infra/openvpn_automation/README.md b/infra/openvpn_automation/README.md new file mode 100644 index 0000000..ba44e08 --- /dev/null +++ b/infra/openvpn_automation/README.md @@ -0,0 +1,119 @@ +# Creating OpenVPN files for users + +## Prerequisites + +In order to follow the steps documented here, few things must be prepared +in advance. + +* Access to required below Nordix OpenVPN/Jump servers with sudo access to infra user, + +----------------+---------------+--------------------------------------+ + | Nordix OpenVPN | IP ADDRESS | SSH ACCESS | + +================+===============+======================================+ + | ONAP-CityCloud | 77.81.6.42 | ssh @77.81.6.42 -p 52413 | + +----------------+---------------+--------------------------------------+ + | ONAP-Xerces | 129.192.70.24 | ssh @129.192.70.24 -p 52413 | + +----------------+---------------+--------------------------------------+ + | Acumos | 91.106.193.58 | ssh @91.106.193.58 -p 52413 | + +----------------+---------------+--------------------------------------+ + +* Ensure SSH key based authentication enabled between Openvpn server and CA + +* Login to required Nordix OpenVPN/Jump server from your machine + +* Install virtualenv, python3-minimal, python3-dev, and python3-pip +```bash +sudo apt update +sudo apt install -y virtualenv python3-minimal python3-dev python3-pip +``` +* Create and set virtualenv +```bash +virtualenv -p python3 .venv +source .venv/bin/activate +``` +* Install Ansible 2.9.6 +``` +pip install ansible==2.9.6 +``` + +## Generate User ovpn file + +* Login to OpenVPN/Jump server with your credentials + +* Clone infra/tools repository from Nordix Gerrit + +```bash +git clone "ssh://@gerrit.nordix.org:29418/infra/tools" && scp -p -P 29418 @gerrit.nordix.org:hooks/commit-msg "tools/.git/hooks/" +``` +You are now ready to create ovpn files for users in project specific OpenVPN server, + +* Switch to infra user in OpenVPN/Jump server + +* Change directory to you home directory from where repo cloned +```bash +cd /tools/infra/openvpn_automation +source /.venv/bin/activate +ansible-playbook -i inventory/inventory.ini openvpn_user_setup.yaml -e "client_name=" +``` + +NOTE: +* Client user ID should be user's username (first character of user firstname + lastname) +* {{ client_name }} should be given as per specific OpenvVPN servers listed below, + +----------------+---------------+---------------------------+ + | Nordix OpenVPN | CIDR | Client_name | + +================+===============+===========================+ + | ONAP-CityCloud | 10.1.0.0/24 | client_userid.onap | + | | 10.2.0.0/24 | | + +----------------+---------------+---------------------------+ + | ONAP-Xerces | 10.10.10.0/24 | client_userid.xerces.onap | + | | 172.16.0.0/16 | | + +----------------+---------------+---------------------------+ + | Acumos | 10.1.0.0/24 | client_userid.acumos | + +----------------+---------------+---------------------------+ + +* Once user specific ovpn file is generated, this file should be shared with user's email with below instructions, + + * Please install the openvpn on your laptop. Assuming you using Ubuntu: + $ sudo apt install openvpn + * Then you need to open the VPN connection using the .ovpn file which contain all the required certificates: + $ sudo openvpn --config {{ client_name }}.ovpn + * Now, you should have access to all the VMs directly from your laptop + $ nmap -n -sP /24 + * In case you use Windows 10 OS, please use the community version of OpenVPN client: + https://swupdate.openvpn.org/community/releases/openvpn-install-2.4.8-I602-Win10.exe + + +## Revoke User ovpn file + +* Login to required Nordix OpenVPN/Jump server from your machine + +* Clone infra/tools repository from Nordix Gerrit + +```bash +git clone "ssh://@gerrit.nordix.org:29418/infra/tools && scp -p -P 29418 @gerrit.nordix.org:hooks/commit-msg "tools/.git/hooks/" +``` +You are now ready to revoke Openvpn access for users in project specific OpenVPN server, + +* Switch to infra user in OpenVPN/Jump server + +* Change directory to you home directory from where repo cloned +```bash +cd /tools/infra/openvpn_automation +source /.venv/bin/activate +ansible-playbook -i inventory/inventory.ini openvpn_user_revoke.yaml -e "client_name=" +``` +NOTE: +* Client user ID should be user's username (first character of user firstname + lastname) +* {{ client_name }} should be given as per specific OpenvVPN servers listed below, + +----------------+---------------+---------------------------+ + | Nordix OpenVPN | CIDR | Client_name | + +================+===============+===========================+ + | ONAP-CityCloud | 10.1.0.0/24 | client_userid.onap | + | | 10.2.0.0/24 | | + +----------------+---------------+---------------------------+ + | ONAP-Xerces | 10.10.10.0/24 | client_userid.xerces.onap | + | | 172.16.0.0/16 | | + +----------------+---------------+---------------------------+ + | Acumos | 10.1.0.0/24 | client_userid.acumos | + +----------------+---------------+---------------------------+ + +You are done! diff --git a/infra/openvpn_automation/generate-user-ovpn/files/make_config.sh b/infra/openvpn_automation/generate-user-ovpn/files/make_config.sh new file mode 100644 index 0000000..24ba4b5 --- /dev/null +++ b/infra/openvpn_automation/generate-user-ovpn/files/make_config.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# First argument: Client identifier +if [ -z "$1" ] + then + echo "Please provide the client identifier." + echo " example: $0 jsmith.xerces.onap" + exit 1 +fi + +KEY_DIR=~/OpenVPN/client-configs/keys +OUTPUT_DIR=~/OpenVPN/client-configs/files +BASE_CONFIG=~/OpenVPN/client-configs/base.conf + +cat ${BASE_CONFIG} \ + <(echo -e '') \ + ${KEY_DIR}/ca.crt \ + <(echo -e '\n') \ + ${KEY_DIR}/${1}.crt \ + <(echo -e '\n') \ + ${KEY_DIR}/${1}.key \ + <(echo -e '\n') \ + ${KEY_DIR}/ta.key \ + <(echo -e '') \ + > ${OUTPUT_DIR}/${1}.ovpn + diff --git a/infra/openvpn_automation/generate-user-ovpn/tasks/main.yaml b/infra/openvpn_automation/generate-user-ovpn/tasks/main.yaml new file mode 100644 index 0000000..fcf8bdf --- /dev/null +++ b/infra/openvpn_automation/generate-user-ovpn/tasks/main.yaml @@ -0,0 +1,81 @@ +--- +- name: Check {{ client_name }} key existence + stat: + path: "{{ nordix_openvpn_easyrsa_path }}/pki/private/{{ client_name }}.key" + register: client_privatekey + delegate_to: localhost + +- name: Create client cert and csr + command: ./easyrsa --batch --req-cn={{ client_name }} gen-req {{ client_name }} nopass + args: + chdir: "{{ nordix_openvpn_easyrsa_path }}" + when: client_privatekey.stat.exists == false + delegate_to: localhost + +- name: Copy client key to client_config directory + copy: + src: "{{ nordix_openvpn_easyrsa_path }}/pki/private/{{ client_name }}.key" + dest: "{{ nordix_openvpn_clientconfig }}/keys/" + changed_when: true + delegate_to: localhost + +- name: Copy client csr to nordix CA + copy: + src: "{{ nordix_openvpn_easyrsa_path }}/pki/reqs/{{ client_name }}.req" + dest: /tmp + changed_when: true + +- name: Check {{ client_name }} csr existence in CA + stat: + path: "{{ nordix_ca_easyrsa_path }}/pki/reqs/{{ client_name }}.req" + register: client_csr + +- name: Import client csr + command: ./easyrsa --batch import-req /tmp/{{ client_name }}.req {{ client_name }} + args: + chdir: "{{ nordix_ca_easyrsa_path }}" + when: client_csr.stat.exists == false + changed_when: true + +- name: Check {{ client_name }} crt existence in CA + stat: + path: "{{ nordix_ca_easyrsa_path }}/pki/issued/{{ client_name }}.crt" + register: client_crt + +- name: Sign client csr + command: ./easyrsa --batch sign-req client {{ client_name }} + args: + chdir: "{{ nordix_ca_easyrsa_path }}" + when: client_crt.stat.exists == false + changed_when: true + +- name: Fetch client cert to client-configs/keys/ dir + fetch: + src: "{{ nordix_ca_easyrsa_path }}/pki/issued/{{ client_name }}.crt" + dest: "{{ nordix_openvpn_clientconfig }}/keys/" + flat: true + changed_when: true + +- name: Generate Client .ovpn file + script: make_config.sh "{{ client_name }}" + args: + chdir: "{{ nordix_openvpn_clientconfig }}/" + executable: /bin/bash + delegate_to: localhost + +- name: Log user specific ovpn files location on the console + debug: + msg: + - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + - "The ovpn file {{ client_name }}.ovpn is located in {{ nordix_openvpn_clientconfig }}/files/{{ client_name }}.ovpn" + - "Please share the newly generated {{ client_name }}.ovpn file with user over email with below instructions," + - "1. Please install the openvpn on your laptop. Assuming you using Ubuntu:" + - "#sudo apt install openvpn" + - "2. Then you need to open the VPN connection using the .ovpn file which contain all the required certificates:" + - "#sudo openvpn --config {{ client_name }}.ovpn &" + - "3. Now, user should have access to all the VMs directly from your laptop" + - "4. In case you use Windows 10 OS, please use the community version of OpenVPN client:" + - "https://swupdate.openvpn.org/community/releases/openvpn-install-2.4.8-I602-Win10.exe" + - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + - '' + delegate_to: localhost diff --git a/infra/openvpn_automation/inventory/group_vars/all/vars.yaml b/infra/openvpn_automation/inventory/group_vars/all/vars.yaml new file mode 100644 index 0000000..0f31ca2 --- /dev/null +++ b/infra/openvpn_automation/inventory/group_vars/all/vars.yaml @@ -0,0 +1,6 @@ +# common: vars +--- +nordix_remote_user_name: "infra" +nordix_ca_easyrsa_path: "/home/infra/EasyRSA-v3.0.6" +nordix_openvpn_easyrsa_path: "/home/infra/OpenVPN/EasyRSA-v3.0.6" +nordix_openvpn_clientconfig: "/home/infra/OpenVPN/client-configs" diff --git a/infra/openvpn_automation/inventory/inventory.ini b/infra/openvpn_automation/inventory/inventory.ini new file mode 100644 index 0000000..624a86b --- /dev/null +++ b/infra/openvpn_automation/inventory/inventory.ini @@ -0,0 +1,8 @@ +[all:vars] +ansible_ssh_extra_args=' -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + +[localhost] +127.0.0.1 ansible_connection=local ansible_user=infra + +# Nordix CA server used to sign CSR's generated for user ovpn files +nordix_ca ansible_connection=ssh ansible_host=77.81.6.250 ansible_user=infra ansible_port=52413 ansible_python_interpreter=/usr/bin/python diff --git a/infra/openvpn_automation/openvpn_user_revoke.yaml b/infra/openvpn_automation/openvpn_user_revoke.yaml new file mode 100644 index 0000000..60d3a6f --- /dev/null +++ b/infra/openvpn_automation/openvpn_user_revoke.yaml @@ -0,0 +1,21 @@ +--- +- name: Revoke user Openvpn config files + hosts: nordix_ca + become: false + gather_facts: false + + pre_tasks: + - name: Check user ovpn file existence + stat: + path: "{{ nordix_openvpn_clientconfig }}/files/{{ client_name }}.ovpn" + register: user_ovpn_file + delegate_to: localhost + + - name: Fail the deployment + fail: + msg: + - "{{ client_name }}.ovpn file not exist under '{{ nordix_openvpn_clientconfig }}/files/{{ client_name }}.ovpn' or Client name is not defined" + when: client_name is not defined and client_name | length > 0 or user_ovpn_file.stat.exists == false + + roles: + - {role: revoke-user-ovpn, when: client_name is defined and client_name | length > 0} diff --git a/infra/openvpn_automation/openvpn_user_setup.yaml b/infra/openvpn_automation/openvpn_user_setup.yaml new file mode 100644 index 0000000..3c7fe49 --- /dev/null +++ b/infra/openvpn_automation/openvpn_user_setup.yaml @@ -0,0 +1,21 @@ +--- +- name: Generate user vpn config files + hosts: nordix_ca + become: false + gather_facts: false + + pre_tasks: + - name: Check user ovpn file existence + stat: + path: "{{ nordix_openvpn_clientconfig }}/files/{{ client_name }}.ovpn" + register: user_ovpn_file + delegate_to: localhost + + - name: Fail the deployment + fail: + msg: + - "{{ client_name }}.ovpn file already exist under '{{ nordix_openvpn_clientconfig }}/files/{{ client_name }}.ovpn' or Client name is not defined" + when: client_name is not defined and client_name | length > 0 or user_ovpn_file.stat.exists + + roles: + - {role: generate-user-ovpn, when: client_name is defined and client_name | length > 0} diff --git a/infra/openvpn_automation/revoke-user-ovpn/tasks/main.yaml b/infra/openvpn_automation/revoke-user-ovpn/tasks/main.yaml new file mode 100644 index 0000000..bcb8bf2 --- /dev/null +++ b/infra/openvpn_automation/revoke-user-ovpn/tasks/main.yaml @@ -0,0 +1,71 @@ +--- +- name: Check {{ client_name }} cert existence in CA + stat: + path: "{{ nordix_ca_easyrsa_path }}/pki/issued//{{ client_name }}.crt" + register: client_cert + +- name: Revoke {{ client_name }} cert in CA + command: ./easyrsa --batch revoke {{ client_name }} + args: + chdir: "{{ nordix_ca_easyrsa_path }}" + when: client_cert.stat.exists == true + register: revoke_result + +- name: Run gen-crl in CA + command: ./easyrsa gen-crl + args: + chdir: "{{ nordix_ca_easyrsa_path }}" + when: revoke_result.rc == 0 + +- name: Check updated crl file existence in CA + stat: + path: "{{ nordix_ca_easyrsa_path }}/pki/crl.pem" + register: crl_existence + +- name: Fetch updated crl from CA to Openvpn /tmp dir + fetch: + src: "{{ nordix_ca_easyrsa_path }}/pki/crl.pem" + dest: "/tmp/" + flat: true + when: crl_existence.stat.exists == true + changed_when: true + +- name: Move updated crl to /etc/openvpn/ dir + command: mv /tmp/crl.pem /etc/openvpn/ + delegate_to: localhost + register: updated_crl + changed_when: true + become: true + +- name: Restart Openvpn Service + systemd: + name: openvpn@server + state: restarted + daemon_reload: true + enabled: true + delegate_to: localhost + when: updated_crl.rc == 0 + become: true + +- name: Remove {{ client_name }} files from OpenVPN server + file: + path: "{{ item }}" + state: absent + with_items: + - "{{ nordix_openvpn_easyrsa_path }}/pki/private/{{ client_name }}.key" + - "{{ nordix_openvpn_easyrsa_path }}/pki/reqs/{{ client_name }}.req" + - "{{ nordix_openvpn_clientconfig }}/keys/{{ client_name }}.crt" + - "{{ nordix_openvpn_clientconfig }}/keys/{{ client_name }}.key" + - "{{ nordix_openvpn_clientconfig }}/files/{{ client_name }}.ovpn" + delegate_to: localhost + register: user_files_removal + +- name: Log user specific ovpn files location on the console + debug: + msg: + - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + - "The OpenVPN access has been revoked for the user {{ client_name }}" + - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + - '' + when: '"All items completed" in user_files_removal.msg' + delegate_to: localhost