diff --git a/.github/workflows/molecule-install-xnat.yml b/.github/workflows/molecule-install-xnat.yml index 3d041591..5fce8201 100644 --- a/.github/workflows/molecule-install-xnat.yml +++ b/.github/workflows/molecule-install-xnat.yml @@ -6,6 +6,7 @@ on: - "roles/xnat_container_service/**" - "playbooks/install_xnat.yml" - "playbooks/install_container_service.yml" + - "playbooks/molecule/**/xnat/**" - ".github/workflows/molecule-install-xnat.yml" release: types: [published] diff --git a/.github/workflows/molecule-nginx.yml b/.github/workflows/molecule-nginx.yml new file mode 100644 index 00000000..46c82f79 --- /dev/null +++ b/.github/workflows/molecule-nginx.yml @@ -0,0 +1,13 @@ +name: Test nginx +on: + pull_request: + paths: + - "roles/nginx/**" + - ".github/workflows/molecule.yml" + - ".github/workflows/molecule-nginx.yml" + +jobs: + molecule-nginx: + uses: ./.github/workflows/molecule.yml + with: + tests-path: ansible_collections/mirsg/infrastructure/roles/nginx diff --git a/molecule_configs/centos7_base_config.yml b/molecule_configs/centos7_base_config.yml index 7b457d27..cb0564a5 100644 --- a/molecule_configs/centos7_base_config.yml +++ b/molecule_configs/centos7_base_config.yml @@ -48,7 +48,7 @@ provisioner: playbooks: prepare: ../resources/prepare.yml converge: ../resources/converge.yml - verify: ../resources/converge.yml + verify: ../resources/verify.yml env: ANSIBLE_VERBOSITY: "1" diff --git a/molecule_configs/rocky9_base_config.yml b/molecule_configs/rocky9_base_config.yml index b283de69..5407a76a 100644 --- a/molecule_configs/rocky9_base_config.yml +++ b/molecule_configs/rocky9_base_config.yml @@ -49,7 +49,7 @@ provisioner: playbooks: prepare: ../resources/prepare.yml converge: ../resources/converge.yml - verify: ../resources/converge.yml + verify: ../resources/verify.yml env: ANSIBLE_VERBOSITY: "1" diff --git a/playbooks/group_vars/web.yml b/playbooks/group_vars/web.yml index 61d14b9b..bb828235 100644 --- a/playbooks/group_vars/web.yml +++ b/playbooks/group_vars/web.yml @@ -76,3 +76,13 @@ firewalld_public_zone_open_services: firewalld_work_zone_open_services: - http - https + +# mirsg.infrastructure.nginx +nginx_use_ssl: "{{ ssl.use_ssl }}" +nginx_server_name: "{{ xnat_web_server.host }}" +nginx_upstream_port: 8104 +nginx_upstream_listen_port: 8104 +nginx_proxy_port: 8080 # tomcat +nginx_root: /usr/share/tomcat/webapps/ROOT +nginx_app_access_log: "{{ nginx_log_folder }}/xnat.access.log" +nginx_app_error_log: "{{ nginx_log_folder }}/xnat.error.log" diff --git a/playbooks/molecule/centos7_xnat/molecule.yml b/playbooks/molecule/centos7_xnat/molecule.yml index 73ecee6c..d2200f9b 100644 --- a/playbooks/molecule/centos7_xnat/molecule.yml +++ b/playbooks/molecule/centos7_xnat/molecule.yml @@ -64,9 +64,10 @@ platforms: exposed_ports: - 80 - 443 + - 8080 - 8104 published_ports: - - 127.0.0.1:8104:8104 + - 127.0.0.1:8000:80 etc_hosts: xnat.db.local: 192.168.56.2 xnat.cserv.local: 192.168.56.4 @@ -111,11 +112,7 @@ provisioner: playbooks: prepare: ../resources/xnat/prepare.yml converge: ../resources/xnat/converge.yml - env: - ANSIBLE_VERBOSITY: 1 - -verifier: - name: ansible + verify: ../resources/xnat/verify.yml env: ANSIBLE_VERBOSITY: 1 diff --git a/playbooks/molecule/resources/xnat/inventory/group_vars/all/all.yml b/playbooks/molecule/resources/xnat/inventory/group_vars/all/all.yml index 3e0b2b93..f43da6a7 100644 --- a/playbooks/molecule/resources/xnat/inventory/group_vars/all/all.yml +++ b/playbooks/molecule/resources/xnat/inventory/group_vars/all/all.yml @@ -1,14 +1,4 @@ --- -# Bit size for OpenSSL Diffie-Hellman Parameters. Higher bit sizes are more -# secure, but require exponentially larger times for the one-off parameter -# generation. Use 4096 for production. These may take 10mins+ to generate but -# are only generated once per server. -# For local testing (non-production), use 2096 to speed up deployment. -diffie_helman_size_bits: 2048 - -# Support for ipv6 -ipv6_enabled: false - # XNAT configuration shared between all servers xnat_common_config: admin_email: "xnatadmin@{{ hostvars['xnat_web']['hostname'] }}" diff --git a/playbooks/molecule/resources/xnat/inventory/group_vars/all/server.yml b/playbooks/molecule/resources/xnat/inventory/group_vars/all/server.yml index 4dfab2d4..355ad383 100644 --- a/playbooks/molecule/resources/xnat/inventory/group_vars/all/server.yml +++ b/playbooks/molecule/resources/xnat/inventory/group_vars/all/server.yml @@ -26,10 +26,6 @@ ssl: use_ssl: false validate_certs: false -# nginx config -dicom_port: 8104 -xnat_dicom_port: 8105 - # XNAT configuration xnat_config: site_name: "MIRSG XNAT" diff --git a/playbooks/molecule/resources/xnat/inventory/group_vars/web.yml b/playbooks/molecule/resources/xnat/inventory/group_vars/web.yml index acd14263..d36bc6e2 100644 --- a/playbooks/molecule/resources/xnat/inventory/group_vars/web.yml +++ b/playbooks/molecule/resources/xnat/inventory/group_vars/web.yml @@ -6,19 +6,20 @@ firewalld_public_zone_sources: - "0.0.0.0/0" firewalld_internal_zone_ports: - - "{{ dicom_port }}" - - "{{ tomcat_port }}" + - "{{ nginx_upstream_listen_port }}" firewalld_work_zone_ports: - - "{{ dicom_port }}" - - "{{ tomcat_port }}" + - "{{ nginx_upstream_listen_port }}" firewalld_public_zone_ports: - - "{{ dicom_port }}" - - "{{ tomcat_port }}" + - "{{ nginx_upstream_listen_port }}" # mirsg.xnat.xnat # Some times the default admin account hasn't finished creating even after tomcat has started # Add a delay here to give the admin account a chance to be created # Note, this issue only seems to happen in CI xnat_wait_for_tomcat: 15 + +# nginx config +nginx_diffie_helman_size_bits: 2048 +nginx_add_default_server: false # set Tomcat as default server to allow access to XNAT web UI through localhost:8000 diff --git a/playbooks/molecule/resources/xnat/verify.yml b/playbooks/molecule/resources/xnat/verify.yml new file mode 100644 index 00000000..a9864fc2 --- /dev/null +++ b/playbooks/molecule/resources/xnat/verify.yml @@ -0,0 +1,18 @@ +--- +- name: Verify XNAT instance is running + hosts: localhost + tasks: + - name: Get server status + ansible.builtin.uri: + url: http://localhost:8000 + method: GET + validate_certs: false + return_content: true + register: response + + - name: Check server status and response + ansible.builtin.assert: + that: + - response.status == 200 + - response.server == "nginx" + - "response.content is search('MIRSG XNAT')" diff --git a/playbooks/molecule/rocky9_xnat/molecule.yml b/playbooks/molecule/rocky9_xnat/molecule.yml index afbb4b0c..fb760790 100644 --- a/playbooks/molecule/rocky9_xnat/molecule.yml +++ b/playbooks/molecule/rocky9_xnat/molecule.yml @@ -66,9 +66,10 @@ platforms: exposed_ports: - 80 - 443 + - 8080 - 8104 published_ports: - - 127.0.0.1:8104:8104 + - 127.0.0.1:8000:80 etc_hosts: xnat.db.local: 192.168.56.2 xnat.cserv.local: 192.168.56.4 @@ -95,7 +96,7 @@ platforms: - name: xnat ipv4_address: 192.168.56.4 exposed_ports: - - "2376" + - 2376 extra_hosts: xnat.db.local: 192.168.56.2 xnat.web.local: 192.168.56.3 @@ -114,6 +115,7 @@ provisioner: playbooks: prepare: ../resources/xnat/prepare.yml converge: ../resources/xnat/converge.yml + verify: ../resources/xnat/verify.yml env: ANSIBLE_VERBOSITY: "1" diff --git a/roles/firewalld/molecule/resources/inventory/group_vars/all.yml b/roles/firewalld/molecule/resources/inventory/group_vars/all.yml index dd7bf1eb..b2420dce 100644 --- a/roles/firewalld/molecule/resources/inventory/group_vars/all.yml +++ b/roles/firewalld/molecule/resources/inventory/group_vars/all.yml @@ -12,6 +12,6 @@ firewalld_work_zone_open_services: - http - https firewalld_public_zone_ports: - - "8080" + - "80" firewalld_internal_zone_ports: - "5432" diff --git a/roles/nginx/README.md b/roles/nginx/README.md new file mode 100644 index 00000000..50ef7c05 --- /dev/null +++ b/roles/nginx/README.md @@ -0,0 +1,57 @@ +# mirsg.infrastructure.nginx + +This role is for configuring [nginx](https://www.nginx.com/) as a +[reverse proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) +on CentOS 7 or RockyLinux 9. + +## Role Variables + +| Name | Description | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `nginx_owner` | The OS user that will have ownership of the nginx service file and directory. Defaults to `root` | +| `nginx_group` | The OS group that will have ownership of the nginx service file and directory. Defaults to `root` | +| `nginx_log_folder` | The path to the nginx logs. Defaults to `/var/log/nginx` | +| `nginx_access_log` | File in which to write access logs for the default server. Defaults to `/var/log/access.log` | +| `nginx_error_log` | File in which to write error logs for the default server. Defaults to `/var/log/error.log` | +| `nginx_app_access_log` | File in which to write access logs for the application server. Defaults to `/var/log/app.access.log` | +| `nginx_app_error_log` | File in which to write error logs for the application server. Defaults to `/var/log/app.error.log` | +| `nginx_http_port` | The port to listen on for HTTP connections. Defaults to `80` | +| `nginx_https_port` | The port to listen on for HTTPS connections. Defaults to `443` | +| `nginx_proxy_port` | The port to forward requests to. Required variable; no default | +| `nginx_root` | The path to search for static files. Optional variable; no default | +| `nginx_conf_template` | The template to use for generating the NGINX config. See currently available [templates](templates/). Defaults to `nginx_reverse_proxy.j2`, which is used to configure NGINX as a reverse proxy | +| `nginx_conf_file` | The path to write the NGINX config to. Defaults to `/etc/nginx/nginx.conf` | +| `nginx_add_default_server` | Whether to add an additional server block for a default server that returns an empty response. Defaults to `true` | +| `nginx_ipv6_enabled` | Whether to enable support for IPv6. Defaults to `false` | + +If you would like to use SSL with NGINX, you will need to have the +certificate and key on your Ansible Controller, and may also need to set +the following variables: + +| Name | Description | +| ------------------------------- | ----------------------------------------------------------------------------------------- | +| `nginx_use_ssl` | Whether to use SSL. Defaults to `true` | +| `nginx_certs_dir` | Where to store the certificates. Defaults to `/etc/nginx/ssl` | +| `nginx_server_cert_cache` | Path to SSL certificate on the Ansible Controller. Required if using SSL; no default | +| `nginx_server_key_cache` | Path to SSL certificate on the Ansible Controller. Required if using SSL; no default | +| `nginx_ssl_cert_file` | Path to copy the SSL certificate to. Defaults to `/etc/nginx/ssl/server.cert` | +| `nginx_ssl_key_file` | Path to copy the SSL key to. Defaults to `/etc/nginx/ssl/server.key` | +| `nginx_diffie_helman_size_bits` | Bit size for OpenSSL Diffie-Hellman Parameters. Defaults to `4096` | +| `nginx_dh_params_file` | Path to write the Diffie-Hellman Parameters to. Defaults to `"/etc/nginx/ssl/dhparam.pem` | + +## Dependencies + +You will need to install the following collections before using `mirsg.infrastructure.nginx`: + +- `ansible.posix` +- `community.crypto` +- `community.general` + +## Example Playbook + +```yaml +- name: Configure nginx + hosts: all + roles: + - mirsg.infrastructure.nginx +``` diff --git a/roles/nginx/defaults/main.yml b/roles/nginx/defaults/main.yml index 0e2ff8a4..b54e653b 100644 --- a/roles/nginx/defaults/main.yml +++ b/roles/nginx/defaults/main.yml @@ -1,15 +1,26 @@ --- -nginx: # noqa: var-naming[no-role-prefix] - owner: root - group: root - log_folder: "/var/log/nginx" - http_port: 80 - https_port: 443 - certs_dir: "/etc/nginx/ssl" - dh_params_file: "/etc/nginx/ssl/dhparam.pem" - conf_file: "/etc/nginx/nginx.conf" - ssl_cert_file: "/etc/nginx/ssl/server.cert" - ssl_key_file: "/etc/nginx/ssl/server.key" +nginx_owner: root +nginx_group: root + +nginx_log_folder: /var/log/nginx +nginx_access_log: "{{ nginx_log_folder }}/access.log" +nginx_error_log: "{{ nginx_log_folder }}/error.log" +nginx_app_access_log: "{{ nginx_log_folder }}/app.access.log" +nginx_app_error_log: "{{ nginx_log_folder }}/app.error.log" + +nginx_http_port: 80 +nginx_https_port: 443 + +nginx_conf_template: nginx_reverse_proxy.j2 # check the template file for the variables it requires +nginx_conf_file: /etc/nginx/nginx.conf +nginx_add_default_server: true + +nginx_ipv6_enabled: false + +nginx_use_ssl: true +nginx_certs_dir: /etc/nginx/ssl +nginx_ssl_cert_file: /etc/nginx/ssl/server.cert +nginx_ssl_key_file: /etc/nginx/ssl/server.key # Bit size for OpenSSL Diffie-Hellman Parameters. Higher bit sizes are more # secure, but require exponentially larger times for the one-off parameter @@ -17,3 +28,4 @@ nginx: # noqa: var-naming[no-role-prefix] # are only generated once per server. # For local testing (non-production), use 2048 to speed up deployment. nginx_diffie_helman_size_bits: 4096 +nginx_dh_params_file: /etc/nginx/ssl/dhparam.pem diff --git a/roles/nginx/molecule/centos7/molecule.yml b/roles/nginx/molecule/centos7/molecule.yml new file mode 100644 index 00000000..0279dcbd --- /dev/null +++ b/roles/nginx/molecule/centos7/molecule.yml @@ -0,0 +1,35 @@ +--- +# test this scenario from the roles/provision directory with the command +# molecule --base-config ../../molecule_configs/centos7_base_config.yml test --scenario centos7 +platforms: + - name: instance + hostname: molecule.instance.local + image: ${MOLECULE_DOCKER_IMAGE:-geerlingguy/docker-centos7-ansible:latest} + required: true + command: "" + cgroupns_mode: host + privileged: true + pre_build_image: ${MOLECULE_PRE_BUILD_IMAGE:-true} + volumes: + - ./molecule-data:/storage/molecule + keep_volumes: false + groups: + - all + - molecule + - centos7 + docker_networks: + - name: molecule + ipam_config: + - subnet: 192.168.56.0/24 + gateway: 192.168.56.1 + networks: + - name: molecule + ipv4_address: 192.168.56.2 + exposed_ports: + - 80 + - 443 + - 8000 + published_ports: + - 127.0.0.1:8080:80 + etc_hosts: + molecule.instance.local: 192.168.56.2 diff --git a/roles/nginx/molecule/resources/converge.yml b/roles/nginx/molecule/resources/converge.yml new file mode 100644 index 00000000..a8449d65 --- /dev/null +++ b/roles/nginx/molecule/resources/converge.yml @@ -0,0 +1,7 @@ +--- +- name: Configure nginx as a reverse proxy + hosts: all + become: true + gather_facts: true + roles: + - role: mirsg.infrastructure.nginx diff --git a/roles/nginx/molecule/resources/files/app.py b/roles/nginx/molecule/resources/files/app.py new file mode 100644 index 00000000..5186476f --- /dev/null +++ b/roles/nginx/molecule/resources/files/app.py @@ -0,0 +1,7 @@ +from flask import Flask + +app = Flask(__name__) + +@app.route("/") +def index(): + return "

Hello World!

" diff --git a/roles/nginx/molecule/resources/inventory/group_vars/all.yml b/roles/nginx/molecule/resources/inventory/group_vars/all.yml new file mode 100644 index 00000000..ffcd1d0b --- /dev/null +++ b/roles/nginx/molecule/resources/inventory/group_vars/all.yml @@ -0,0 +1,6 @@ +--- +nginx_server_name: molecule.instance.local +nginx_proxy_port: 8000 +nginx_diffie_helman_size_bits: 2048 +nginx_root: "/home/" +nginx_use_ssl: false diff --git a/roles/nginx/molecule/resources/inventory/group_vars/centos7.yml b/roles/nginx/molecule/resources/inventory/group_vars/centos7.yml new file mode 100644 index 00000000..77512db8 --- /dev/null +++ b/roles/nginx/molecule/resources/inventory/group_vars/centos7.yml @@ -0,0 +1,17 @@ +--- +# mirsg.infrastructure.install_python +install_python: + version: "2" + pip_version: "20.3.4" + pip_executable: pip + system_packages: + - python + - python-pip + - python-setuptools + - libselinux-python + - policycoreutils-python + pip_packages: + - gunicorn + - Flask + +gunicorn_executable: /usr/bin/gunicorn diff --git a/roles/nginx/molecule/resources/inventory/group_vars/rocky9.yml b/roles/nginx/molecule/resources/inventory/group_vars/rocky9.yml new file mode 100644 index 00000000..8d618da4 --- /dev/null +++ b/roles/nginx/molecule/resources/inventory/group_vars/rocky9.yml @@ -0,0 +1,17 @@ +--- +# mirsg.infrastructure.install_python +install_python: + version: "3" + pip_version: "21.3.1" + pip_executable: /usr/local/bin/pip3 + system_packages: + - python3 + - python3-pip + - python3-setuptools + - python3-libselinux + - policycoreutils-python-utils + pip_packages: + - gunicorn + - flask + +gunicorn_executable: /usr/local/bin/gunicorn diff --git a/roles/nginx/molecule/resources/prepare.yml b/roles/nginx/molecule/resources/prepare.yml new file mode 100644 index 00000000..34eece31 --- /dev/null +++ b/roles/nginx/molecule/resources/prepare.yml @@ -0,0 +1,31 @@ +--- +- name: Install and configure Flask and Gunicorn + hosts: all + become: true + gather_facts: true + tasks: + - name: Install python and Flask/Gunicorn dependencies + ansible.builtin.include_role: + name: mirsg.infrastructure.install_python + + - name: Copy Flask app to host + ansible.builtin.copy: + src: app.py + dest: /home/app.py + owner: root + group: root + mode: "0644" + + - name: Create Gunicorn service config + ansible.builtin.template: + src: gunicorn_service.j2 + dest: /etc/systemd/system/gunicorn.service + owner: root + group: root + mode: "0644" + force: true + + - name: Start Gunicorn service + ansible.builtin.systemd: + name: gunicorn + state: restarted diff --git a/roles/nginx/molecule/resources/templates/gunicorn_service.j2 b/roles/nginx/molecule/resources/templates/gunicorn_service.j2 new file mode 100644 index 00000000..d33b5adf --- /dev/null +++ b/roles/nginx/molecule/resources/templates/gunicorn_service.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Gunicorn instance to serve flask app +After=network.target + +[Service] +User=root +Group=root +WorkingDirectory=/home +ExecStart={{ gunicorn_executable }} --workers 2 --bind localhost:8000 app:app diff --git a/roles/nginx/molecule/resources/verify.yml b/roles/nginx/molecule/resources/verify.yml new file mode 100644 index 00000000..267189cd --- /dev/null +++ b/roles/nginx/molecule/resources/verify.yml @@ -0,0 +1,20 @@ +--- +- name: Verify nginx configured as a reverse proxy + hosts: localhost + tasks: + - name: Get server status + ansible.builtin.uri: + url: http://localhost:8080 + method: GET + headers: + Host: molecule.instance.local + validate_certs: false + return_content: true + register: response + + - name: Check server status and response + ansible.builtin.assert: + that: + - response.status == 200 + - response.server == "nginx" + - response.content is search('Hello World!') diff --git a/roles/nginx/molecule/rocky9/molecule.yml b/roles/nginx/molecule/rocky9/molecule.yml new file mode 100644 index 00000000..01adc398 --- /dev/null +++ b/roles/nginx/molecule/rocky9/molecule.yml @@ -0,0 +1,34 @@ +--- +# test this scenario from the roles/provision directory with the command +# molecule --base-config ../../molecule_configs/rocky9_base_config.yml test --scenario rocky9 +platforms: + - name: instance + hostname: molecule.instance.local + image: ${MOLECULE_DOCKER_IMAGE:-geerlingguy/docker-rockylinux9-ansible:latest} + required: true + command: "" + cgroupns_mode: host + privileged: true + pre_build_image: ${MOLECULE_PRE_BUILD_IMAGE:-true} + volumes: + - ./molecule-data:/storage/molecule + - /sys/fs/cgroup:/sys/fs/cgroup:rw + keep_volumes: false + groups: + - all + - molecule + - rocky9 + docker_networks: + - name: molecule + ipam_config: + - subnet: 192.168.56.0/24 + gateway: 192.168.56.1 + networks: + - name: molecule + ipv4_address: 192.168.56.2 + exposed_ports: + - 80 + - 443 + - 8000 + published_ports: + - 127.0.0.1:8080:80 diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml index 608f3263..4e357d35 100644 --- a/roles/nginx/tasks/main.yml +++ b/roles/nginx/tasks/main.yml @@ -2,12 +2,13 @@ - name: Configure SELinux if enabled and enforced when: ansible_selinux.status == "enabled" and ansible_selinux.mode == "enforcing" block: - - name: Configure SELinux to allow nginx to listen on port {{ dicom_port }} + - name: Configure SELinux to allow nginx to listen on port {{ nginx_upstream_listen_port }} community.general.seport: - ports: "{{ dicom_port }}" + ports: "{{ nginx_upstream_listen_port }}" proto: tcp setype: http_port_t state: present + when: nginx_upstream_listen_port is defined - name: Configure SELinux to allow httpd to act as relay and keep it persistent across reboots ansible.posix.seboolean: @@ -28,9 +29,9 @@ - name: Ensure nginx certs directory exists ansible.builtin.file: - path: "{{ nginx.certs_dir }}" - owner: "{{ nginx.owner }}" - group: "{{ nginx.group }}" + path: "{{ nginx_certs_dir }}" + owner: "{{ nginx_owner }}" + group: "{{ nginx_group }}" state: directory mode: "0700" @@ -39,27 +40,29 @@ remote_src: true src: "{{ item.src }}" dest: "{{ item.dest }}" - owner: "{{ nginx.owner }}" - group: "{{ nginx.group }}" + owner: "{{ nginx_owner }}" + group: "{{ nginx_group }}" mode: "0600" with_items: - - { src: "{{ ssl.server_cert }}", dest: "{{ nginx.ssl_cert_file }}" } - - { src: "{{ ssl.server_key }}", dest: "{{ nginx.ssl_key_file }}" } + - src: "{{ nginx_server_cert_cache }}" + dest: "{{ nginx_ssl_cert_file }}" + - src: "{{ nginx_server_key_cache }}" + dest: "{{ nginx_ssl_key_file }}" notify: Reload nginx - when: ssl.use_ssl + when: nginx_use_ssl - name: Generate Diffie-Hellman (DH) parameters. Number of {{ diffie_helman_size_bits }}. community.crypto.openssl_dhparam: - path: "{{ nginx.dh_params_file }}" - size: "{{ diffie_helman_size_bits }}" + path: "{{ nginx_dh_params_file }}" + size: "{{ nginx_diffie_helman_size_bits }}" notify: Reload nginx - name: Copy nginx config file ansible.builtin.template: - src: "nginx.j2" - dest: "{{ nginx.conf_file }}" - owner: "{{ nginx.owner }}" - group: "{{ nginx.group }}" + src: "{{ nginx_conf_template }}" + dest: "{{ nginx_conf_file }}" + owner: "{{ nginx_owner }}" + group: "{{ nginx_group }}" mode: "0644" force: true notify: Reload nginx diff --git a/roles/nginx/templates/nginx.j2 b/roles/nginx/templates/nginx_reverse_proxy.j2 similarity index 66% rename from roles/nginx/templates/nginx.j2 rename to roles/nginx/templates/nginx_reverse_proxy.j2 index d0887f45..09a37c17 100644 --- a/roles/nginx/templates/nginx.j2 +++ b/roles/nginx/templates/nginx_reverse_proxy.j2 @@ -1,23 +1,27 @@ +# Configure a reverse proxy +# Optionally create an additional default_server load_module '/usr/lib64/nginx/modules/ngx_stream_module.so'; user nginx; worker_processes auto; -error_log {{ nginx.log_folder }}/error.log warn; +error_log {{ nginx_error_log }} warn; pid /run/nginx.pid; events { worker_connections 1024; } +{% if nginx_upstream_port is defined and nginx_upstream_listen_port is defined %} stream { - upstream dicom { - server localhost:{{ xnat_dicom_port }}; + upstream backend { + server localhost:{{ nginx_upstream_port }}; } server { - listen {{ dicom_port }}; - proxy_pass dicom; + listen {{ nginx_upstream_listen_port }}; + proxy_pass backend; } } +{% endif %} http { sendfile off; @@ -27,7 +31,7 @@ http { keepalive_timeout 65; types_hash_max_size 2048; default_type application/octet-stream; - access_log {{ nginx.log_folder }}/access.log; + access_log {{ nginx_access_log }}; # Good security practice is not to expose nginx version server_tokens off; @@ -36,19 +40,19 @@ http { gzip on; gzip_disable "msie6"; -{% if ssl.use_ssl %} +{% if nginx_use_ssl %} # SSL parameters must be specified outside of the server block. # Otherwise may only use the nginx may end up using parameters specified in # the default_server block even if a different serer is matched - ssl_certificate {{ nginx.ssl_cert_file }}; - ssl_certificate_key {{ nginx.ssl_key_file }}; + ssl_certificate {{ nginx_ssl_cert_file }}; + ssl_certificate_key {{ nginx_ssl_key_file }}; # TLS 1.0 and TLS 1.1 should be disabled # TLS 1.3 may not be supported by Centos7 ssl_protocols TLSv1.2; - ssl_dhparam {{ nginx.dh_params_file }}; + ssl_dhparam {{ nginx_dh_params_file }}; ssl_ecdh_curve secp384r1; # Increase the cache lifetime to improve performance; this requires a larger cache size @@ -71,57 +75,59 @@ http { # Note that nginx only uses server_name for disambiguation purposes; if # there is no matching server_name then nginx will use the default_server # regardless of its value of server_name +{% if nginx_add_default_server %} server { listen 80 default_server; -{% if ssl.use_ssl %} + {% if nginx_use_ssl %} listen 443 ssl default_server; -{% endif %} + {% endif %} -{% if ipv6_enabled %} + {% if nginx_ipv6_enabled %} listen [::]:80 default_server; - {% if ssl.use_ssl %} + {% if nginx_use_ssl %} listen [::]:443 ssl default_server; + {% endif %} {% endif %} -{% endif %} server_name _; return 444; } +{% endif %} -{% if ssl.use_ssl %} +{% if nginx_use_ssl %} # Redirect to https server { - listen {{ nginx.http_port }}; + listen {{ nginx_http_port }}; - server_name {{ xnat_web_server.host }}; - return 301 https://{{ xnat_web_server.host }}:{{ nginx.https_port }}$request_uri; + server_name {{ nginx_server_name }}; + return 301 https://{{ nginx_server_name }}:{{ nginx_https_port }}$request_uri; } {% endif %} server { -{% if ssl.use_ssl %} - listen {{ nginx.https_port }} ssl http2; - {% if ipv6_enabled %} - listen [::]:{{ nginx.https_port }} ssl http2; +{% if nginx_use_ssl %} + listen {{ nginx_https_port }} ssl http2{% if not nginx_add_default_server %} default_server{% endif %}; + {% if nginx_ipv6_enabled %} + listen [::]:{{ nginx_https_port }} ssl http2{% if not nginx_add_default_server %} default_server{% endif %}; {% endif %} {% else %} - listen {{ nginx.http_port }}; - {% if ipv6_enabled %} - listen [::]:{{ nginx.http_port }}; + listen {{ nginx_http_port }}{% if not nginx_add_default_server %} default_server{% endif %}; + {% if nginx_ipv6_enabled %} + listen [::]:{{ nginx_http_port }}{% if not nginx_add_default_server %} default_server{% endif %}; {% endif %} {% endif %} - # Note: server_name is only used for disambiguation - server_name {{ xnat_web_server.host }}; - - root {{ tomcat_root }}; + server_name {{ nginx_server_name }}; + {% if nginx_root is defined %} + root {{ nginx_root }}; + {% endif %} location / { - proxy_pass http://localhost:{{ tomcat_port }}; + proxy_pass http://localhost:{{ nginx_proxy_port }}; proxy_redirect http:// $scheme://; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; @@ -137,7 +143,7 @@ http { client_body_buffer_size 128k; proxy_max_temp_file_size 0; } - access_log {{ nginx.log_folder }}/xnat.access.log; - error_log {{ nginx.log_folder }}/xnat.error.log; + access_log {{ nginx_app_access_log }}; + error_log {{ nginx_app_error_log }}; } }