diff --git a/create-thehive-users.yml b/create-thehive-users.yml new file mode 100644 index 0000000000000000000000000000000000000000..f9d9e6aebb7f639491c50cf45ca7f01b8b287211 --- /dev/null +++ b/create-thehive-users.yml @@ -0,0 +1,6 @@ +--- + +- name: Create Users in TheHive + hosts: thehive + roles: + - thehive diff --git a/group_vars/all/users.yml b/group_vars/all/users.yml index bc785e4800de9f8642c7236db63cbe5069f2826a..6710fa8a9f643f3fce02f2dce37af1253799d7ea 100644 --- a/group_vars/all/users.yml +++ b/group_vars/all/users.yml @@ -18,4 +18,23 @@ soctools_users: ODFE_ADMIN_USERS: - user1 +THEHIVE_ORGANIZATION: "uninett.no" +THEHIVE_KIBANA_USER: + username: "kibana" + name: "Kibana" + surname: "User" + roles: '["read", "write"]' + + +THEHIVE_USERS: + - user1: + username: "user1" + name: "User1" + surname: "SOC" + roles: '["read", "write", "admin"]' + - user2: + username: "user2" + name: "User2" + surname: "SOC" + roles: '["read", "write", "admin"]' diff --git a/roles/cortex/tasks/start.yml b/roles/cortex/tasks/start.yml index ddb37bc3f01c9a37165ecc98232d091d5ceb34d0..9b7eb794916702247eea35118caf352bb8895258 100644 --- a/roles/cortex/tasks/start.yml +++ b/roles/cortex/tasks/start.yml @@ -23,6 +23,10 @@ - "{{playbook_dir}}/secrets/CA/cacerts.jks" - "{{playbook_dir}}/secrets/CA/ca.crt" +- name: Get openid authkey + set_fact: + cortexsecret: "{{lookup('file', '{{playbook_dir}}/secrets/tokens/cortexsecret',convert_data=False) | from_json}}" + - name: Configure embedded Elasticsearch 6 remote_user: root template: diff --git a/roles/cortex/templates/application.conf.j2 b/roles/cortex/templates/application.conf.j2 index e45e446edc48c43d6c4e2a6ae7f9aa3f9b00f879..00cd4e88af2237c15afb99696c19bc9d3a40da22 100644 --- a/roles/cortex/templates/application.conf.j2 +++ b/roles/cortex/templates/application.conf.j2 @@ -66,7 +66,7 @@ auth { # the "ad" section below. # - ldap : use LDAP to authenticate users. The associated configuration shall be done in the # "ldap" section below. - provider = [local] + provider = [local,oauth2] ad { # The Windows domain name in DNS format. This parameter is required if you do not use @@ -108,6 +108,84 @@ auth { # If 'true', use SSL to connect to the LDAP directory server. #useSSL = true } + oauth2 { + # URL of the authorization server + clientId = "soctools-cortex" + clientSecret = {{cortexsecret.value}} + redirectUri = "https://{{soctoolsproxy}}:9001/api/ssoLogin" + responseType = "code" + grantType = "authorization_code" + + # URL from where to get the access token + authorizationUrl = "https://{{soctoolsproxy}}:12443/auth/realms/{{openid_realm}}/protocol/openid-connect/auth" + authorizationHeader = "Bearer" + tokenUrl = "https://{{soctoolsproxy}}:12443/auth/realms/{{openid_realm}}/protocol/openid-connect/token" + + + # The endpoint from which to obtain user details using the OAuth token, after successful login + userUrl = "https://{{soctoolsproxy}}:12443/auth/realms/{{openid_realm}}/protocol/openid-connect/userinfo" + scope = "profile" + userIdField = "email" + #userUrl = "https://auth-site.com/api/User" + #scope = ["openid profile"] + } + + ws.ssl.trustManager { + stores = [ + { + type = "JKS" // JKS or PEM + path = "cacerts.jks" + password = "{{lookup('password', '{{playbook_dir}}/secrets/passwords/truststore')}}" + } + ] + } + + + # Single-Sign On + sso { + # Autocreate user in database? + autocreate = true + + # Autoupdate its profile and roles? + autoupdate = true + + # Autologin user using SSO? + autologin = true + + # Name of mapping class from user resource to backend user ('simple' or 'group') + #mapper = group + #mapper = simple + #attributes { + # login = "user" + # name = "name" + # groups = "groups" + # organization = "org" + #} +# defaultRoles = ["read", "write", "admin"] +# defaultOrganization = "uninett.no" + #defaultRoles = ["read"] + #defaultOrganization = "csirt" + #groups { + # # URL to retreive groups (leave empty if you are using OIDC) + # #url = "https://auth-site.com/api/Groups" + # # Group mappings, you can have multiple roles for each group: they are merged + # mappings { + # admin-profile-name = ["admin"] + # editor-profile-name = ["write"] + # reader-profile-name = ["read"] + # } + #} + + mapper = simple + attributes { + login = "user" + name = "name" + roles = "roles" + organization = "org" + } + defaultRoles = ["read", "analyze"] + defaultOrganization = "uninett.no" + } } ## ANALYZERS diff --git a/roles/keycloak/tasks/start.yml b/roles/keycloak/tasks/start.yml index 468cb2559c151b0b146a9f17cfa3980bc70b24a0..8f9bc309114504457d3ee55f03f077fe0e0b08ae 100644 --- a/roles/keycloak/tasks/start.yml +++ b/roles/keycloak/tasks/start.yml @@ -91,6 +91,13 @@ local: "{{playbook_dir}}/secrets/tokens/kibanasecret" - remote: "{{ ansible_facts.env['JBOSS_HOME'] }}/mispsecret" local: "{{playbook_dir}}/secrets/tokens/mispsecret" + - remote: "{{ ansible_facts.env['JBOSS_HOME'] }}/thehivesecret" + local: "{{playbook_dir}}/secrets/tokens/thehivesecret" + - remote: "{{ ansible_facts.env['JBOSS_HOME'] }}/cortexsecret" + local: "{{playbook_dir}}/secrets/tokens/cortexsecret" - name: Set Autostart for supervisord's services - shell: "sed -i 's/autostart=false/autostart=true/g' /etc/supervisord.conf" + replace: + path: /etc/supervisord.conf + regexp: '^autostart=false$' + replace: 'autostart=true' diff --git a/roles/keycloak/templates/initkeycloakrealm.sh.j2 b/roles/keycloak/templates/initkeycloakrealm.sh.j2 index 3d790f2eb02af9dbb6644d50795d77788f8c0ba4..1444717fc84aed57192ea89f8d047096d66c5ee6 100644 --- a/roles/keycloak/templates/initkeycloakrealm.sh.j2 +++ b/roles/keycloak/templates/initkeycloakrealm.sh.j2 @@ -31,6 +31,12 @@ kcadm.sh get realms/{{openid_realm}}/clients/${KIBANACLIENT}/client-secret --fie MISPCLIENT=$(kcadm.sh create realms/{{openid_realm}}/clients -i -b '{"enabled":true, "clientId":"soctools-misp","protocol":"openid-connect","clientAuthenticatorType": "client-secret","rootUrl": "https://{{soctoolsproxy}}:6443","adminUrl": "","redirectUris": ["https://{{soctoolsproxy}}:6443/users/login/keycloak"],"webOrigins": [], "publicClient": false }') kcadm.sh get realms/{{openid_realm}}/clients/${MISPCLIENT}/client-secret --fields value > /opt/jboss/keycloak/mispsecret +THEHIVECLIENT=$(kcadm.sh create realms/{{openid_realm}}/clients -i -b '{"enabled":true, "clientId":"soctools-thehive","protocol":"openid-connect","clientAuthenticatorType": "client-secret","adminUrl": "","redirectUris": ["https://{{soctoolsproxy}}:9000/api/ssoLogin"],"webOrigins": [], "publicClient": false }') +kcadm.sh get realms/{{openid_realm}}/clients/${THEHIVECLIENT}/client-secret --fields value > /opt/jboss/keycloak/thehivesecret + +CORTEXCLIENT=$(kcadm.sh create realms/{{openid_realm}}/clients -i -b '{"enabled":true, "clientId":"soctools-cortex","protocol":"openid-connect","clientAuthenticatorType": "client-secret","adminUrl": "","redirectUris": ["https://{{soctoolsproxy}}:9001/api/ssoLogin"],"webOrigins": [], "publicClient": false }') +kcadm.sh get realms/{{openid_realm}}/clients/${CORTEXCLIENT}/client-secret --fields value > /opt/jboss/keycloak/cortexsecret + kcadm.sh config truststore --delete exec 1>&6 6>&- diff --git a/roles/odfekibana/files/env.js.j2 b/roles/odfekibana/files/env.js.j2 index a075a2781bbbed7d80132a22a7544c7235041018..e1adb4ba1a6a4cc15b79e505921c7f2a4fab5968 100644 --- a/roles/odfekibana/files/env.js.j2 +++ b/roles/odfekibana/files/env.js.j2 @@ -1,4 +1,4 @@ // Default plugin configuration -export const THEHIVE_URL = '{{THEHIVE_URL}}'; -export const THEHIVE_API_KEY = '{{THEHIVE_API_KEY}}'; -export const THEHIVE_OWNER = '{{THEHIVE_OWNER}}'; // default owner account of the created cases +export const THEHIVE_URL = 'https://{{soctoolsproxy}}:9000'; +export const THEHIVE_API_KEY = '{{lookup('password', '{{playbook_dir}}/secrets/tokens/thehive_kibana_secret_key')}}'; +export const THEHIVE_OWNER = '{{THEHIVE_KIBANA_USER.username}}'; // default owner account of the created cases diff --git a/roles/odfekibana/tasks/start.yml b/roles/odfekibana/tasks/start.yml index e52bce77af746d938910b87fdd7b98aa2bb2a527..a067386d233ebcbd229b9297436097595dc2346f 100644 --- a/roles/odfekibana/tasks/start.yml +++ b/roles/odfekibana/tasks/start.yml @@ -126,6 +126,7 @@ -k --user admin:{{lookup("password", "{{playbook_dir}}/secrets/passwords/odfees_adminpass")}} \ -H "kbn-xsrf: reporting" -H "Content-Type: multipart/form-data" \ -F "file=@/tmp/kibana_graphs.ndjson"' + ignore_errors: True - name: Copy role modification json to container remote_user: kibana diff --git a/roles/thehive/tasks/adminuser.yml b/roles/thehive/tasks/adminuser.yml new file mode 100644 index 0000000000000000000000000000000000000000..6bc110ae6c890d0119d6efce7119fbd4b03c6b57 --- /dev/null +++ b/roles/thehive/tasks/adminuser.yml @@ -0,0 +1,40 @@ +--- + +- name: copy json file for admin user + remote_user: root + template: + src: admin.json + dest: /tmp/admin.json + +- name: get admin user id + remote_user: root + shell: "curl -X POST http://127.0.0.1:9000/api/login -b /tmp/cookie.txt -c /tmp/cookie.txt -H 'Content-Type: application/json' -d @/tmp/admin.json | cut -d\\\" -f4" + register: adminuser + args: + warn: false + +- set_fact: + adminuserid={{ adminuser.stdout }} + +- name: create admin user API KEY + shell: "curl -X POST http://127.0.0.1:9000/api/v1/user/{{ adminuserid }}/key/renew -b /tmp/cookie.txt -c /tmp/cookie.txt 2> /dev/null | tee /tmp/thehive_secret_key" + register: adminuserkey + args: + warn: false + +- set_fact: + adminuserapikey={{ adminuserkey.stdout }} + +- name: copy API key to local file + local_action: copy content="{{adminuserapikey}}" dest=secrets/tokens/thehive_secret_key + +- name: copy json file for admin pass + remote_user: root + template: + src: adminpass.json + dest: /tmp/adminpass.json + +- name: change password for admin user + shell: "curl -X POST http://127.0.0.1:9000/api/v1/user/{{ adminuserid }}/password/set -b /tmp/cookie.txt -c /tmp/cookie.txt -H 'Content-Type: application/json' -d @/tmp/adminpass.json" + args: + warn: false diff --git a/roles/thehive/tasks/createusers.yml b/roles/thehive/tasks/createusers.yml new file mode 100644 index 0000000000000000000000000000000000000000..7125a0bcbaf91849ce9656c6c99642d7ead13049 --- /dev/null +++ b/roles/thehive/tasks/createusers.yml @@ -0,0 +1,17 @@ +--- + +- name: generate json files for creating users + remote_user: root + template: + src: users.json + dest: /tmp/{{ item.username }}.json + with_items: + - "{{ THEHIVE_USERS }}" + +- name: create users + remote_user: root + shell: "curl -H 'Authorization: Bearer {{lookup('password', '{{playbook_dir}}/secrets/tokens/thehive_secret_key')}}' -H 'Content-Type: application/json' http://127.0.0.1:9000/api/user -d @/tmp/{{ item.username}}.json" + args: + warn: false + with_items: + - "{{ THEHIVE_USERS }}" diff --git a/roles/thehive/tasks/kibanauser.yml b/roles/thehive/tasks/kibanauser.yml new file mode 100644 index 0000000000000000000000000000000000000000..d4b44b09497a44df36d584f7ece27b5dc2084304 --- /dev/null +++ b/roles/thehive/tasks/kibanauser.yml @@ -0,0 +1,31 @@ +--- + +- name: generate json file for kibana user + remote_user: root + template: + src: kibanauser.json + dest: /tmp/kibanauser.json + +- name: create kibana user + remote_user: root + shell: "curl -H 'Authorization: Bearer {{lookup('password', '{{playbook_dir}}/secrets/tokens/thehive_secret_key')}}' -H 'Content-Type: application/json' http://127.0.0.1:9000/api/user -d @/tmp/kibanauser.json | cut -d\\\" -f4" + register: kibanauser + args: + warn: false + +- set_fact: + kibanauserid={{ kibanauser.stdout }} + +- name: create API key for kibana user + remote_user: root + shell: "curl -XPOST -H 'Authorization: Bearer {{lookup('password', '{{playbook_dir}}/secrets/tokens/thehive_secret_key')}}' -H 'Content-Type: application/json' http://127.0.0.1:9000/api/v1/user/{{kibanauser.stdout}}/key/renew 2> /dev/null | tee /tmp/kibanaapikey" + register: kibanaapikey + args: + warn: false + +- set_fact: + kibanauserapikey={{ kibanaapikey.stdout }} + +- name: copy API key to local file + local_action: copy content="{{kibanauserapikey}}" dest=secrets/tokens/thehive_kibana_secret_key + diff --git a/roles/thehive/tasks/main.yml b/roles/thehive/tasks/main.yml index a0f7edf3191254869b03c63056db742bacb7b71e..def4e3dee132cb841acaf437380a250cd9e0b786 100644 --- a/roles/thehive/tasks/main.yml +++ b/roles/thehive/tasks/main.yml @@ -3,6 +3,20 @@ - include: start.yml tags: - start +- include: adminuser.yml + tags: + - start +- include: organization.yml + tags: + - start +- include: kibanauser.yml + tags: + - start +- include: createusers.yml + tags: + - start + - create-thehive-users + - createusers - include: stop.yml tags: - stop diff --git a/roles/thehive/tasks/organization.yml b/roles/thehive/tasks/organization.yml new file mode 100644 index 0000000000000000000000000000000000000000..edfa059c1e23f8add5670705976845c6805b2d59 --- /dev/null +++ b/roles/thehive/tasks/organization.yml @@ -0,0 +1,15 @@ +--- + +- name: create organisation + uri: + url: "http://127.0.0.1:9000/api/organisation" + method: POST + headers: + Authorization: "Bearer {{lookup('password', '{{playbook_dir}}/secrets/tokens/thehive_secret_key')}}" + body_format: form-urlencoded + body: + name: "{{ THEHIVE_ORGANIZATION }}" + description: "{{ THEHIVE_ORGANIZATION }}" + status_code: 201 + ignore_errors: True + diff --git a/roles/thehive/tasks/start.yml b/roles/thehive/tasks/start.yml index 33a136bffda2f69156da07a3a97c4bcb9addecfb..9521b5752fe9c257a05e571980fa38ae2b0c599d 100644 --- a/roles/thehive/tasks/start.yml +++ b/roles/thehive/tasks/start.yml @@ -1,5 +1,40 @@ --- +- name: Copy cacert to ca-trust dir + remote_user: root + copy: + src: "{{playbook_dir}}/secrets/CA/ca.crt" + dest: /etc/pki/ca-trust/source/anchors/ca.crt + +- name: Install cacert to root truststore + remote_user: root + command: "update-ca-trust" + +- name: Copy certificate in thehive conf dir + copy: + src: "{{playbook_dir}}/secrets/CA/issued/{{ inventory_hostname }}.crt" + dest: "/etc/thehive/{{ inventory_hostname }}.crt" + mode: 0600 + +- name: Copy certificate key in thehive conf dir + copy: + src: "{{playbook_dir}}/secrets/CA/private/{{ inventory_hostname }}.key" + dest: "/etc/thehive/{{ inventory_hostname }}.key" + mode: 0600 + +- name: Copy CA certificates in thehive conf dir + copy: + src: "{{playbook_dir}}/secrets/CA/{{ item }}" + dest: "/etc/thehive/{{ item }}" + mode: 0600 + with_items: + - "cacerts.jks" + - "ca.crt" + +- name: Get openid authkey + set_fact: + thehivesecret: "{{lookup('file', '{{playbook_dir}}/secrets/tokens/thehivesecret',convert_data=False) | from_json}}" + - name: Configure TheHive remote_user: thehive template: diff --git a/roles/thehive/templates/admin.json b/roles/thehive/templates/admin.json new file mode 100644 index 0000000000000000000000000000000000000000..2db07d9fc4fb289868c4e71d8272cabb6846608e --- /dev/null +++ b/roles/thehive/templates/admin.json @@ -0,0 +1 @@ +{"user":"admin@thehive.local","password":"secret"} diff --git a/roles/thehive/templates/adminpass.json b/roles/thehive/templates/adminpass.json new file mode 100644 index 0000000000000000000000000000000000000000..96292dbc219846f77c437dbd7f92fee4fd4e949a --- /dev/null +++ b/roles/thehive/templates/adminpass.json @@ -0,0 +1 @@ +{"password":"{{lookup('password', '{{playbook_dir}}/secrets/passwords/thehive_adminpass')}}"} diff --git a/roles/thehive/templates/application.conf.j2 b/roles/thehive/templates/application.conf.j2 index d25e059818a773a6a4a48fb34196cc641f79e718..b66cf81f38d82aa7c4102dc84daf45f22d118db4 100644 --- a/roles/thehive/templates/application.conf.j2 +++ b/roles/thehive/templates/application.conf.j2 @@ -5,7 +5,7 @@ ## Include Play secret key # More information on secret key at https://www.playframework.com/documentation/2.8.x/ApplicationSecret #include "/etc/thehive/secret.conf" -play.http.secret.key="{{lookup('password', '{{playbook_dir}}/secrets/passwords/thehive_secret_key')}}" +play.http.secret.key="{{lookup('password', '{{playbook_dir}}/secrets/tokens/thehive_secret_key')}}" ## Database configuration db.janusgraph { @@ -13,7 +13,7 @@ db.janusgraph { ## Cassandra configuration # More information at https://docs.janusgraph.org/basics/configuration-reference/#storagecql backend: cql - hostname: ["{{groups['cassandra'][0]}}.{{soctools_netname}}"] + hostname: ["{{groups['cassandra'][0]}}.{{soctools_netname}}:9042"] # Cassandra authentication (if configured) // username: "thehive" // password: "password" @@ -47,17 +47,61 @@ storage { ## Authentication configuration # More information at https://github.com/TheHive-Project/TheHiveDocs/TheHive4/Administration/Authentication.md -//auth { -// providers: [ +auth { + providers: [ // {name: session} # required ! // {name: basic, realm: thehive} // {name: local} // {name: key} -// ] + {name: session} # required ! + {name: basic, realm: thehive} + {name: local} + {name: key} + { + name: oauth2 + clientId: "soctools-thehive" + clientSecret: {{thehivesecret.value}} + redirectUri: "https://{{soctoolsproxy}}:9000/api/ssoLogin" + responseType: "code" + grantType: "authorization_code" + authorizationUrl: "https://{{soctoolsproxy}}:12443/auth/realms/{{openid_realm}}/protocol/openid-connect/auth" + authorizationHeader: "Bearer" + tokenUrl: "https://{{soctoolsproxy}}:12443/auth/realms/{{openid_realm}}/protocol/openid-connect/token" + userUrl: "https://{{soctoolsproxy}}:12443/auth/realms/{{openid_realm}}/protocol/openid-connect/userinfo" +// scope: ["openid", "email"] + scope: ["openid"] + userIdField: "email" +// userIdField: "name" + } + ] + sso { + autocreate: true + autoupdate: true + autologin: true + mapper: "simple" +// attributes { +// login: "login" +// name: "name" +// roles: "role" +// } + defaultRoles: ["read", "write", "admin"] + defaultOrganization: "uninett.no" +// defaultOrganization: "demo" + } + ws.ssl.trustManager { + stores = [ + { + type: "JKS" // JKS or PEM + path: "cacerts.jks" + password: "{{lookup('password', '{{playbook_dir}}/secrets/passwords/truststore')}}" + } + ] + } # The format of logins must be valid email address format. If the provided login doesn't contain `@` the following # domain is automatically appended -// defaultUserDomain: "thehive.local" -//} + defaultUserDomain: "uninett.no" +# defaultUserDomain: "thehive.local" +} ## CORTEX configuration # More information at https://github.com/TheHive-Project/TheHiveDocs/TheHive4/Administration/Connectors.md diff --git a/roles/thehive/templates/kibanauser.json b/roles/thehive/templates/kibanauser.json new file mode 100644 index 0000000000000000000000000000000000000000..5feebb3585c600669dcd2ab6846208be3ba5ba1a --- /dev/null +++ b/roles/thehive/templates/kibanauser.json @@ -0,0 +1,6 @@ +{ + "login": "{{ THEHIVE_KIBANA_USER.username }}", + "name": "{{ THEHIVE_KIBANA_USER.name }} {{ THEHIVE_KIBANA_USER.surname }}", + "roles": {{ THEHIVE_KIBANA_USER.roles }}, + "organisation": "{{ THEHIVE_ORGANIZATION }}" +} diff --git a/roles/thehive/templates/users.json b/roles/thehive/templates/users.json new file mode 100644 index 0000000000000000000000000000000000000000..cba95d6cec00421b05df12f392c8e818df40d079 --- /dev/null +++ b/roles/thehive/templates/users.json @@ -0,0 +1,6 @@ +{ + "login": "{{ item.username }}", + "name": "{{ item.name }} {{ item.surname }}", + "roles": {{ item.roles }}, + "organisation": "{{ THEHIVE_ORGANIZATION }}" +} diff --git a/soctools.yml b/soctools.yml index fb4a2196557009b772ebf937cc80fe2658d65001..4e7f89ba1912be4eff657c45c7a47ed450946a6c 100644 --- a/soctools.yml +++ b/soctools.yml @@ -15,3 +15,7 @@ - name: restart soctools cluster servics import_playbook: restart-soctools.yml when: "'restart' in ansible_run_tags or 'restart-thehive' in ansible_run_tags or 'restart-keycloak' in ansible_run_tags or 'restart-cortex' in ansible_run_tags or 'restart-haproxy' in ansible_run_tags or 'restart-cassandra' in ansible_run_tags or 'restart-filebeat' in ansible_run_tags or 'restart-misp' in ansible_run_tags or 'restart-mysql' in ansible_run_tags or 'restart-nifi' in ansible_run_tags or 'restart-odfees' in ansible_run_tags or 'restart-odfekibana' in ansible_run_tags" + +- name: create thehive users + import_playbook: create-thehive-users.yml + when: "'create-thehive-users' in ansible_run_tags or 'createusers' in ansible_run_tags" diff --git a/startsoctools.yml b/startsoctools.yml index c9c4c6bb95760d4da7a0a46706507bd4d5867174..fec35b6b9396d64ef417ef1acd396a602d0d6622 100644 --- a/startsoctools.yml +++ b/startsoctools.yml @@ -35,6 +35,16 @@ roles: - nifi +- name: Reconfigure and start TheHive + hosts: thehive + roles: + - thehive + +- name: Reconfigure and start Cortex + hosts: cortex + roles: + - cortex + - name: Reconfigure and start OpenDistro for Elasticsearch hosts: odfeescontainers roles: @@ -50,13 +60,3 @@ roles: - filebeat -- name: Reconfigure and start TheHive - hosts: thehive - roles: - - thehive - -- name: Reconfigure and start Cortex - hosts: cortex - roles: - - cortex -