From 15f59fbfce6a17b175e92c3cf48818433feb05bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20K=C3=A1cha?= <ph@cesnet.cz>
Date: Thu, 15 Aug 2019 16:06:06 +0200
Subject: [PATCH] Add proof-of-concept ansible script for Warden server and
 Warden filer

---
 .../warden-filer-receiver/defaults/main.yml   |  9 ++
 .../warden-filer-receiver/tasks/main.yml      | 31 +++++++
 .../etc/defaults/warden_filer_receiver        |  1 +
 .../templates/etc/warden_filer.cfg            | 23 ++++++
 .../ansible/warden-server/defaults/main.yml   | 21 +++++
 contrib/ansible/warden-server/tasks/main.yml  | 82 +++++++++++++++++++
 .../etc/apache2/sites-available/warden.conf   | 40 +++++++++
 .../templates/opt/warden-ra/warden_ra.cfg     | 18 ++++
 .../opt/warden-server/warden_server.cfg       | 20 +++++
 9 files changed, 245 insertions(+)
 create mode 100644 contrib/ansible/warden-filer-receiver/defaults/main.yml
 create mode 100644 contrib/ansible/warden-filer-receiver/tasks/main.yml
 create mode 100644 contrib/ansible/warden-filer-receiver/templates/etc/defaults/warden_filer_receiver
 create mode 100644 contrib/ansible/warden-filer-receiver/templates/etc/warden_filer.cfg
 create mode 100644 contrib/ansible/warden-server/defaults/main.yml
 create mode 100644 contrib/ansible/warden-server/tasks/main.yml
 create mode 100644 contrib/ansible/warden-server/templates/etc/apache2/sites-available/warden.conf
 create mode 100644 contrib/ansible/warden-server/templates/opt/warden-ra/warden_ra.cfg
 create mode 100644 contrib/ansible/warden-server/templates/opt/warden-server/warden_server.cfg

diff --git a/contrib/ansible/warden-filer-receiver/defaults/main.yml b/contrib/ansible/warden-filer-receiver/defaults/main.yml
new file mode 100644
index 0000000..e2bbd78
--- /dev/null
+++ b/contrib/ansible/warden-filer-receiver/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+server_admin: "{{ root@inventory_hostname }}"
+warden_filer_bin_path: /opt/warden-filer
+warden_client_cert_path: /etc/ssl/certs/warden.cert.pem
+warden_client_key_path: /etc/ssl/private/warden.key.pem
+warden_client_id_store: /var/lib/warden_filer/warden_filer.id
+warden_filer_pid_file: /run/warden_filer/receiver.pid
+warden_filer_uid: 1
+warden_filer_gid: 1
\ No newline at end of file
diff --git a/contrib/ansible/warden-filer-receiver/tasks/main.yml b/contrib/ansible/warden-filer-receiver/tasks/main.yml
new file mode 100644
index 0000000..1d9c959
--- /dev/null
+++ b/contrib/ansible/warden-filer-receiver/tasks/main.yml
@@ -0,0 +1,31 @@
+---
+- name: Checkout Warden repository
+  git:
+    repo: https://homeproj.cesnet.cz/git/warden.git/
+    version: warden-client-3.0-beta2
+    dest: /tmp/warden_client_repository
+
+- name: Install Filer binaries
+  copy:
+    src: "/tmp/warden_client_repository/{{ src }}"
+    dest: "{{ warden_filer_bin_path }}/{{ dest }}"
+  with_items:
+    - src: warden_client/warden_client.py
+      dest: warden_client.py
+    - src: warden_filer/warden_filer.py
+      dest: warden_filer.py
+    - src: warden_filer/check_file_count
+      dest: check_file_count
+
+- name: Install Warden Filer config
+  template:
+    src: "{{ item }}"
+    dest: "/{{ item }}"
+  with_items:
+    - etc/warden_filer.cfg
+    - etc/defaults/warden_filer_receiver
+
+- name: Install Warden Filer init script
+  copy:
+    src: /tmp/warden_client_repository/warden_filer/warden_filer_receiver
+    dest: /etc/init.d/warden_filer_receiver
diff --git a/contrib/ansible/warden-filer-receiver/templates/etc/defaults/warden_filer_receiver b/contrib/ansible/warden-filer-receiver/templates/etc/defaults/warden_filer_receiver
new file mode 100644
index 0000000..a0dcd74
--- /dev/null
+++ b/contrib/ansible/warden-filer-receiver/templates/etc/defaults/warden_filer_receiver
@@ -0,0 +1 @@
+PYTHONPATH={{ warden_filer_bin_path }}
diff --git a/contrib/ansible/warden-filer-receiver/templates/etc/warden_filer.cfg b/contrib/ansible/warden-filer-receiver/templates/etc/warden_filer.cfg
new file mode 100644
index 0000000..f6a5fd6
--- /dev/null
+++ b/contrib/ansible/warden-filer-receiver/templates/etc/warden_filer.cfg
@@ -0,0 +1,23 @@
+{
+    // Warden config can be also referenced as:
+    // "warden": "/path/to/warden_client.cfg"
+    "warden": {
+        "url": "{{ warden_server_url | mandatory }}",
+        "keyfile": "{{ warden_client_key_path }}",
+        "certfile": "{{ warden_client_cert_path }}",
+        "timeout": 30,
+        "send_events_limit": 1000,
+        "get_events_limit": 1000,
+        "syslog": {"level": "debug", "facility": "local7"},
+        "idstore": "{{ warden_client_id_store }}",
+        "name": "{{ warden_client_name | mandatory }}"
+    },
+    "receiver": {
+        "dir": "{{ warden_filer_output_dir | mandatory }}",
+        "pid_file": "{{ warden_filer_pid_file }}",
+        "uid": {{ warden_filer_uid }},
+        "gid": {{ warden_filer_gid }},
+        "file_limit": 10000,
+        "limit_wait_time": 20
+    }
+}
diff --git a/contrib/ansible/warden-server/defaults/main.yml b/contrib/ansible/warden-server/defaults/main.yml
new file mode 100644
index 0000000..87f7882
--- /dev/null
+++ b/contrib/ansible/warden-server/defaults/main.yml
@@ -0,0 +1,21 @@
+---
+server_admin: "{{ root@inventory_hostname }}"
+
+warden_server_hostname: "{{ inventory_hostname }}"
+warden_server_virtual_host: "{{ ansible_default_ipv4 }}:443 {{ ansible_default_ipv6 }}:443"
+
+warden_server_dir_path: /opt/warden-server
+warden_ra_dir_path: /opt/warden-ra
+
+warden_db_name: warden3
+warden_db_user: warden
+
+warden_ra_ejbca_url: https://ejbca.cesnet-ca.cz:8443/ejbca/ejbcaws/ejbcaws?wsdl
+warden_ra_cert: /etc/ssl/certs/warden_ra.cert.pem
+warden_ra_key: /etc/ssl/private/warden_ra.key.pem
+warden_ra_ca_name: "Warden CA"
+warden_ra_ejbca_certificate_profile: "Warden"
+warden_ra_ejbca_end_entity_profile: "Warden EE"
+warden_ra_subject_dn_template: "DC=test,DC=snakeoil,DC=warden,CN=%s"
+warden_ra_ejbca_username_suffix: "@warden"
+
diff --git a/contrib/ansible/warden-server/tasks/main.yml b/contrib/ansible/warden-server/tasks/main.yml
new file mode 100644
index 0000000..1b059d5
--- /dev/null
+++ b/contrib/ansible/warden-server/tasks/main.yml
@@ -0,0 +1,82 @@
+---
+- name: Checkout Warden repository
+  git:
+    repo: https://homeproj.cesnet.cz/git/warden.git/
+    version: warden-server-3.0-beta2
+    dest: /tmp/warden_server_repository
+
+- name: Populate Warden server directory
+  copy:
+    src: "/tmp/warden_server_repository/warden_server"
+    dest: "{{ warden_server_dir_path }}"
+
+- name: Populate Warden RA directory
+  copy:
+    src: "/tmp/warden_server_repository/warden_ra"
+    dest: "{{ warden_ra_dir_path }}"
+  
+- name: Install Warden server config
+  template:
+    src: opt/warden-server/warden_server.cfg
+    dest: "{{ warden_server_dir_path }}/warden_server.cfg"
+
+- name: Install Warden RA config
+  template:
+    src: opt/warden-ra/warden_ra.cfg
+    dest: "{{ warden_ra_dir_path }}/warden_ra.cfg"
+
+- name: Ensure PyMySQL module
+  apt:
+    pkg: python-mysqldb
+    state: present
+
+- name: Check whether Warden database already exists
+  command: |
+    mysql
+      --batch --skip-column-names
+      --user="{{ warden_db_user }}" --password="{{ warden_db_password | mandatory }}"
+      "{{ warden_db_name }}"
+      --execute "SELECT 1;"
+  register: warden_db_exists
+  changed_when: False
+
+- name: Create Warden database
+  mysql_db:
+    name: "{{ warden_db_name }}"
+    state: present
+
+- name: Create Warden database user
+  mysql_user:
+    name: "{{ warden_db_user }}"
+    password: "{{ warden_db_password | mandatory }}"
+    priv: "{{ warden_db_name }}.*:ALL"
+    state: present
+
+- name: Prepare initial Warden tables and fixtures
+  mysql_db:
+    name: "{{ warden_db_name }}"
+    login_user: "{{ warden_db_user }}"
+    login_password: "{{ warden_db_password | mandatory }}"
+    state: import
+    target: "{{ warden_server_dir_path }}/warden_3.0.sql"
+  # Import is not idempotent, so run it only when db does not exist
+  when: "warden_db_exists is defined and warden_db_exists.rc != 0 and warden_db_exists.stderr.find('ERROR 1049')"
+
+- name: Install https config
+  template:
+    src: "etc/apache2/sites-available/warden.conf"
+    dest: "/etc/apache2/sites-available/warden.conf"
+    validate: "{{ ansible_apache_include_check.dest }} sites-enabled/ %s"
+  notify: Reload Apache
+
+- name: Activate http/s config
+  command: a2ensite warden
+  args:
+    creates: /etc/apache2/sites-enabled/warden.conf
+  notify: Reload Apache
+
+- name: Deactivate default site
+  command: a2dissite default-ssl
+  args:
+    removes: /etc/apache2/sites-enabled/default-ssl.conf
+  notify: Reload Apache
diff --git a/contrib/ansible/warden-server/templates/etc/apache2/sites-available/warden.conf b/contrib/ansible/warden-server/templates/etc/apache2/sites-available/warden.conf
new file mode 100644
index 0000000..246c809
--- /dev/null
+++ b/contrib/ansible/warden-server/templates/etc/apache2/sites-available/warden.conf
@@ -0,0 +1,40 @@
+<VirtualHost {{ warden_server_virtual_host }} >
+    ServerAdmin {{ server_admin }}
+    DocumentRoot /var/www
+
+    <Directory />
+            Options FollowSymLinks
+            AllowOverride None
+    </Directory>
+
+    ServerName {{ warden_server_hostname }}
+
+    ErrorLog /var/log/apache2/ssl_error_warden3.log
+    CustomLog /var/log/apache2/ssl_access_warden3.log common
+
+    SSLEngine on
+
+    SSLVerifyClient optional
+    SSLVerifyDepth 4
+    SSLOptions +StdEnvVars +ExportCertData
+
+    SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
+    SSLProtocol all -SSLv2 -SSLv3
+    SSLHonorCipherOrder On
+
+    SSLCertificateFile      /etc/ssl/certs/cert.pem
+    SSLCertificateKeyFile   /etc/ssl/certs/key.pem
+    SSLCACertificateFile    /etc/ssl/certs/root_cert_chain.pem
+
+    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
+
+    WSGIScriptAlias /warden3 {{ warden_server_dir_path }}/warden_server.wsgi
+    <Directory /opt/warden-server/warden_server.wsgi>
+        Require all granted
+    </Directory>
+
+    WSGIScriptAlias /warden-ra {{ warden_ra_dir_path }}/warden_ra.wsgi
+    <Directory /opt/warden-ra/warden_ra.wsgi>
+        Require all granted
+    </Directory>
+</VirtualHost>
diff --git a/contrib/ansible/warden-server/templates/opt/warden-ra/warden_ra.cfg b/contrib/ansible/warden-server/templates/opt/warden-ra/warden_ra.cfg
new file mode 100644
index 0000000..a596833
--- /dev/null
+++ b/contrib/ansible/warden-server/templates/opt/warden-ra/warden_ra.cfg
@@ -0,0 +1,18 @@
+{
+    "Log": {
+        "type": "SysLogger",
+        "facility": "local6",
+        "level": "debug"
+    },
+    "Registry": {
+        "type": "EjbcaRegistry",
+        "url": "{{ warden_ra_ejbca_url }}
+        "cert": "{{ warden_ra_cert }}",
+        "key": "{{ warden_ra_key }}",
+        "ca_name": "{{ warden_ra_ca_name }}",
+        "certificate_profile_name": "{{ warden_ra_ejbca_certificate_profile }}",
+        "end_entity_profile_name": "{{ warden_ra_ejbca_end_entity_profile }}",
+        "subject_dn_template": "{{ warden_ra_subject_dn_template }}",
+        "username_suffix": "{{ warden_ra_ejbca_username_suffix }}"
+    }
+}
diff --git a/contrib/ansible/warden-server/templates/opt/warden-server/warden_server.cfg b/contrib/ansible/warden-server/templates/opt/warden-server/warden_server.cfg
new file mode 100644
index 0000000..697aa05
--- /dev/null
+++ b/contrib/ansible/warden-server/templates/opt/warden-server/warden_server.cfg
@@ -0,0 +1,20 @@
+{
+    "Log": {
+        "type": "SysLogger",
+	"facility": "local7",
+        "level": "debug"
+    },
+    "Auth": {
+        "type": "X509MixMatchAuthenticator"
+    },
+    "Handler": {
+        "send_events_limit": 1000,
+        "get_events_limit": 1000,
+        "description": "Warden 3 Server"
+    },
+    "DB": {
+        "user": "warden",
+        "password": "{{ warden_db_password }}",
+        "dbname": "{{ warden_db_user }}"
+    }
+}
-- 
GitLab