diff --git a/group_vars/stations/eci_users.yml b/group_vars/stations/eci_users.yml index 652d5a8e4dc304316dfadbd686d328295686c2e8..4c2d55f986bc9af6032d43c74d3c05908a52d336 100644 --- a/group_vars/stations/eci_users.yml +++ b/group_vars/stations/eci_users.yml @@ -1,7 +1,19 @@ eci_users: - - testuser - - testuser2 + - ecitk + - eciae + - ecihmt + - testuser + - testuser2 + +eci_overseers: + - ecitk + - eciae + - ecihmt + eci_users_uid: - testuser: 61 - testuser2: 62 + testuser: 71 + testuser2: 72 + ecitk: 73 + eciae: 74 + ecihmt: 75 diff --git a/pbook.yml b/pbook.yml index 890d489fe77d978ed07c36a91b95f2013829ccea..c57f2539754b2fbc163f510d8fc5910b9ac59e4f 100644 --- a/pbook.yml +++ b/pbook.yml @@ -4,3 +4,4 @@ roles: - base - ftpserver + - shinyproxy diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml index 9eb5f9cea37d7c16ecd05a86523c7893b56ec53c..1c91cd85a0d0716d7d8cb517c5ea3cd86ee4a3dd 100644 --- a/roles/base/tasks/main.yml +++ b/roles/base/tasks/main.yml @@ -69,19 +69,24 @@ mode: '0755' - name: Create private key. + tags: create-certs + notify: created-certs community.crypto.openssl_privatekey: path: /etc/eci-platform/priv/certificate.key - name: Create certificate signing request (CSR) for self-signed certificate. community.crypto.openssl_csr_pipe: privatekey_path: /etc/eci-platform/priv/certificate.key - common_name: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}.uni.lux" + common_name: "{{ ansible_hostname }}.uni.lux" organization_name: Environmental Cheminformatics subject_alt_name: - - "DNS:{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}.uni.lux" + - "DNS:{{ ansible_hostname }}.uni.lux" + - "DNS:{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" register: csr - name: Create self-signed certificate from CSR + tags: create-certs + notify: created-certs community.crypto.x509_certificate: path: /etc/eci-platform/pub/certificate.key csr_content: "{{ csr.csr }}" diff --git a/roles/ftpserver/tasks/main.yml b/roles/ftpserver/tasks/main.yml index 932e8f24ac83cbda2ca8b257a9e8b2b526a0e190..89b08282bbfec44b172040befc31c6c4165b3ab6 100644 --- a/roles/ftpserver/tasks/main.yml +++ b/roles/ftpserver/tasks/main.yml @@ -1,6 +1,8 @@ - name: Install packages. apt: - name: [ "proftpd-basic" ] + name: [ "proftpd-core", + "proftpd-mod-crypto", + "proftpd-mod-wrap" ] - name: Ensure group auth exists. file: @@ -22,6 +24,13 @@ line: Umask 002 002 path: /etc/proftpd/proftpd.conf notify: restart-ftp + +- name: Configure ProFTPd umask. + ansible.builtin.lineinfile: + regexp: '^#?.LoadModule' + line: ModulePath mod_tls.c + path: /etc/proftpd/modules.conf + notify: restart-ftp - name: Configure ProFTPd for multiple virtual users. tags: proftpd-conf-text diff --git a/roles/shinyproxy/files/eci-users/proxer/addusers.py b/roles/shinyproxy/files/eci-users/proxer/addusers.py new file mode 100644 index 0000000000000000000000000000000000000000..f36e0543c73103990f1605ebc29e2cc1d0d336d6 --- /dev/null +++ b/roles/shinyproxy/files/eci-users/proxer/addusers.py @@ -0,0 +1,39 @@ +import yaml +import os + + +fn_passwd="eci_passwords.yml" +fn_application="application.in.yml" +fn_users="eci_users.yml" + +fn_out="application.yml" +names = yaml.safe_load(fn_passwd) +with open(fn_passwd, 'r') as file: + passwd = yaml.safe_load(file)['eci_passwords'] + +with open(fn_users,'r') as file: + x = yaml.safe_load(file) + users = x['eci_users'] + overseers = x['eci_overseers'] + all_users = list(set(users+overseers)) + +with open(fn_application,'r') as file: + appln = yaml.safe_load(file) + + +def use_group(user): + res=None + if user in users: + res = "eci" + elif user in overseers: + res = "overseers" + return(res) + +appln['proxy']['users']=[ { 'name':x,'groups':use_group(x),'password':passwd[x] } for x in all_users ] + +with open(fn_out, 'w') as file: + yaml.dump(appln, file, default_flow_style=False,sort_keys=False) + + +os.remove(fn_passwd) +os.remove(fn_users) diff --git a/roles/shinyproxy/files/eci-users/proxer/application.in.yml b/roles/shinyproxy/files/eci-users/proxer/application.in.yml new file mode 100644 index 0000000000000000000000000000000000000000..bff07ba5352aba641293b67b34da3b5a74d6dac2 --- /dev/null +++ b/roles/shinyproxy/files/eci-users/proxer/application.in.yml @@ -0,0 +1,33 @@ +proxy: + title: ECI Platform + logo-url: https://wwwen.uni.lu/var/storage/images/universite/presentation/galerie_de_photos/learning_center_library/1446055-1-fre-FR/learning_center_library.jpg + # logo-url: https://www.openanalytics.eu/shinyproxy/logo.png + landing-page: / + heartbeat-rate: 10000 + heartbeat-timeout: 60000 + port: 8080 + container-wait-time: 600000 + container-log-path: /eci-users/proxer/container-logs + bind-address: 127.0.0.1 + authentication: simple + admin-groups: overseers + # Example: 'simple' authentication configuration + # proxy[users] will be added later. + # Docker configuration + docker: + url: http://localhost:2375 + port-range-start: 15000 + specs: + - id: 01_shinyscreen + container-image: r-r-shinyscreen-coreutils-minimal-bash + container-cpu-limit: 4 + display-name: Shinyscreen + port: 7777 + container-volumes: [ "/eci-users:/scratch" ] + container-cmd: [ "R", "-e", "library(future);future::plan('multisession');usdir=Sys.getenv('SHINYPROXY_USERNAME');indir=file.path('/scratch',usdir);shinyscreen::serve(indir=indir,topuserdir='/scratch',user=usdir)"] + access-groups: [overseers,eci] + + +logging: + file: + name: shinyproxy.log diff --git a/roles/shinyproxy/files/eci-users/proxer/eci_passwords.yml b/roles/shinyproxy/files/eci-users/proxer/eci_passwords.yml new file mode 100644 index 0000000000000000000000000000000000000000..ad0a5ce72ae5b441769050464604aa817493727a --- /dev/null +++ b/roles/shinyproxy/files/eci-users/proxer/eci_passwords.yml @@ -0,0 +1 @@ +eci_passwords: "{{ eci_passwords }}" diff --git a/roles/shinyproxy/files/eci-users/proxer/overseers.yml b/roles/shinyproxy/files/eci-users/proxer/overseers.yml new file mode 100644 index 0000000000000000000000000000000000000000..9a0e3fc27aae8a7640b31fbc497b10783e9a3bc2 --- /dev/null +++ b/roles/shinyproxy/files/eci-users/proxer/overseers.yml @@ -0,0 +1,4 @@ +overseers: + - ecitk + - ecihmt + - eciae diff --git a/roles/shinyproxy/files/etc/nginx/conf.d/shinyproxy.conf b/roles/shinyproxy/files/etc/nginx/conf.d/shinyproxy.conf new file mode 100644 index 0000000000000000000000000000000000000000..3822700f43e2cc74ecc624f892eb3019acb17199 --- /dev/null +++ b/roles/shinyproxy/files/etc/nginx/conf.d/shinyproxy.conf @@ -0,0 +1,34 @@ +server { + listen 80; + server_name ___ECI_VM_HOSTNAME___; + rewrite ^(.*) https://$server_name$1 permanent; +} + +server { + listen 443; + server_name ___ECI_VM_HOSTNAME___; + access_log /var/log/nginx/shinyproxy.access.log; + error_log /var/log/nginx/shinyproxy.error.log error; + + ssl on; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + + ssl_certificate /eci-users/proxer/certificate.pub.key; + ssl_certificate_key /eci-users/proxer/certificate.key; + + location / { + proxy_pass http://127.0.0.1:8080/; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_read_timeout 600s; + + proxy_redirect off; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + +} diff --git a/roles/shinyproxy/files/etc/systemd/system/docker.service.d/override.conf b/roles/shinyproxy/files/etc/systemd/system/docker.service.d/override.conf new file mode 100644 index 0000000000000000000000000000000000000000..15f171e9ac31f30de40ca49a7b1592a08e888f3a --- /dev/null +++ b/roles/shinyproxy/files/etc/systemd/system/docker.service.d/override.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=/usr/sbin/dockerd -H unix:// -D -H tcp://127.0.0.1:2375 \ No newline at end of file diff --git a/roles/shinyproxy/files/etc/systemd/system/shinyproxy.service b/roles/shinyproxy/files/etc/systemd/system/shinyproxy.service new file mode 100644 index 0000000000000000000000000000000000000000..feb0a3a0bf8ac598fd2563be4cb8a29cba2c7677 --- /dev/null +++ b/roles/shinyproxy/files/etc/systemd/system/shinyproxy.service @@ -0,0 +1,15 @@ +[Unit] +Description=Manual service for Shinyproxy. +After=docker.service nginx.service +BindsTo=docker.service nginx.service +ReloadPropagatedFrom=docker.service nginx.service + +[Service] +Type=simple +ExecStart=/usr/bin/java -jar shinyproxy.jar +Restart=on-failure +User=proxer +WorkingDirectory=/eci_users/proxer + +[Install] +WantedBy=multi-user.target diff --git a/roles/shinyproxy/handlers/main.yml b/roles/shinyproxy/handlers/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..d2a275cccca94d780cadeeca4446c94b0b64f6a5 --- /dev/null +++ b/roles/shinyproxy/handlers/main.yml @@ -0,0 +1,29 @@ +- name: Reload systemd. + listen: + - docker-reconf + ansible.builtin.systemd: + daemon_reload: yes + +- name: Restart nginx. + listen: + - update-www-conf + ansible.builtin.service: + name: nginx + state: restarted + +- name: Change application.yml permissions. + listen: + - shinyproxy-application + ansible.builtin.file: + path: /eci-users/proxer/application.yml + owner: proxer + mode: '0600' + +- name: Restart shinyproxy. + listen: + - update-www-conf + - shinyproxy-service + ansible.builtin.service: + name: shinyproxy + state: restarted + enabled: yes diff --git a/roles/shinyproxy/tasks/main.yml b/roles/shinyproxy/tasks/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..5bd9c77d35f3d740e4245868aeabb0700b6db4bc --- /dev/null +++ b/roles/shinyproxy/tasks/main.yml @@ -0,0 +1,123 @@ +- name: Install docker. + apt: + name: [ 'docker.io', + 'nginx', + 'python3-yaml' ] + + +- name: Create service user 'proxer'. + user: + name: proxer + system: yes + groups: + - docker + - eci + +- name: Create /eci-users/proxer. + ansible.builtin.file: + path: /eci-users/proxer + owner: proxer + state: directory + mode: '0711' + +- name: Copy TLS keys for use here (priv). + ansible.builtin.copy: + remote_src: yes + src: /etc/eci-platform/priv/certificate.key + dest: /eci-users/proxer/certificate.key + owner: proxer + mode: 0600 + +- name: Copy TLS keys for use here(pub). + ansible.builtin.copy: + remote_src: yes + src: /etc/eci-platform/pub/certificate.key + dest: /eci-users/proxer/certificate.pub.key + owner: proxer + mode: 0644 + +- name: Copy configuration file for nginx (shinyproxy). + notify: update-www-conf + ansible.builtin.copy: + src: files/etc/nginx/conf.d/shinyproxy.conf + dest: /etc/nginx/conf.d/shinyproxy.conf + mode: '0644' + +- name: Write the hostname/IP address to the shinyproxy.conf file. + notify: update-www-conf + ansible.builtin.replace: + path: /etc/nginx/conf.d/shinyproxy.conf + regexp: '___ECI_VM_HOSTNAME___' + replace: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" + +- name: Get Shinyproxy. + get_url: + url: https://www.shinyproxy.io/downloads/shinyproxy-2.6.0.jar + dest: /eci-users/proxer/shinyproxy.jar + owner: proxer + mode: '0700' + +- name: Get Shinyscreen docker container. + get_url: + url: https://zenodo.org/record/6362024/files/docker-shinyscreen.tar.gz?download=1 + dest: /eci-users/proxer/docker-shinyscreen.tar.gz + owner: proxer + mode: '0700' + +- name: Create docker config directory. + ansible.builtin.file: + path: /etc/systemd/system/docker.service.d + state: directory + mode: '0744' + +- name: Copy configuration file for docker (shinyproxy). + notify: + - docker-reconf + ansible.builtin.copy: + src: files/etc/systemd/system/docker.service.d/override.conf + dest: /etc/systemd/system/docker.service.d/override.conf + mode: '0644' + +- name: Load docker image. + ansible.builtin.shell: + cmd: docker load -i docker-shinyscreen.tar.gz && touch loaded.shinyscreen + creates: loaded.shinyscreen + chdir: /eci-users/proxer + + +- name: Copy config file for shinyproxy. + tags: shinyproxy-conf + ansible.builtin.copy: + src: files/eci-users/proxer/application.in.yml + dest: /eci-users/proxer/application.in.yml + owner: proxer + mode: '0600' + +- name: Copy users file for shinyproxy. + tags: shinyproxy-conf + ansible.builtin.template: + src: "eci-users/proxer/{{ item }}.tmpl.yml" + dest: "/eci-users/proxer/{{ item }}.yml" + owner: proxer + mode: '0600' + loop: + - eci_passwords + - eci_users + +- name: Generate application.yml. + tags: shinyproxy-conf + notify: + - shinyproxy-application + ansible.builtin.script: + cmd: files/eci-users/proxer/addusers.py + chdir: /eci-users/proxer + executable: python3 + +- name: Copy service file for shinyproxy. + tags: shinyproxy-conf + notify: shinyproxy-service + ansible.builtin.copy: + src: files/etc/systemd/system/shinyproxy.service + dest: /etc/systemd/system/shinyproxy.service + mode: '0644' + diff --git a/roles/shinyproxy/templates/eci-users/proxer/eci_passwords.tmpl.yml b/roles/shinyproxy/templates/eci-users/proxer/eci_passwords.tmpl.yml new file mode 100644 index 0000000000000000000000000000000000000000..aee3f367e8d03715855e4c976fc2e494bc5c5a77 --- /dev/null +++ b/roles/shinyproxy/templates/eci-users/proxer/eci_passwords.tmpl.yml @@ -0,0 +1 @@ +eci_passwords: {{ eci_passwords }} diff --git a/roles/shinyproxy/templates/eci-users/proxer/eci_users.tmpl.yml b/roles/shinyproxy/templates/eci-users/proxer/eci_users.tmpl.yml new file mode 100644 index 0000000000000000000000000000000000000000..8d9a2b215b7af701963a38fac0b55dad98b049b2 --- /dev/null +++ b/roles/shinyproxy/templates/eci-users/proxer/eci_users.tmpl.yml @@ -0,0 +1,3 @@ +eci_users: {{ eci_users }} + +eci_overseers: {{ eci_overseers }}