Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vhost role #20

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .config/molecule/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND noninteractive

{% if item.image.startswith('debian') %}
RUN apt-get update \
&& apt-get install -y python3 sudo bash ca-certificates iproute2 python3-apt aptitude systemd systemd-sysv \
&& apt-get install -y python3 sudo bash ca-certificates iproute2 python3-apt aptitude systemd systemd-sysv gpg \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
{% else %}
Expand Down
16 changes: 16 additions & 0 deletions molecule/vhost/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
- name: Converge
hosts: all
vars:
vhost_vhosts:
- vhostname: demo.example.com
port: 443
https: true
redirect_http_to_https: true
http_proxy_backend: http://127.0.0.1:8888
exported_headers:
- {header: x-wing, value: machin}
access_rules:
- {location: /accept, rule: accept}
roles:
- role: worteks.lemonldap.vhost
30 changes: 30 additions & 0 deletions molecule/vhost/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# Use shared config under .config/molecule at the root of this project
platforms:
- name: rockylinux9
image: rockylinux:9
command: /lib/systemd/systemd
privileged: true
pre_build_image: false
cgroupns_mode: host
dockerfile: ../../.config/molecule/Dockerfile.j2
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup
- name: debian11
image: debian:bullseye-slim
command: /lib/systemd/systemd
privileged: true
pre_build_image: false
cgroupns_mode: host
dockerfile: ../../.config/molecule/Dockerfile.j2
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup
- name: debian12
image: debian:bookworm-slim
command: /lib/systemd/systemd
privileged: true
pre_build_image: false
cgroupns_mode: host
dockerfile: ../../.config/molecule/Dockerfile.j2
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup
18 changes: 18 additions & 0 deletions molecule/vhost/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
- name: Prepare
hosts: all
vars:
lemonldap_domain: example.ci
pre_tasks:
- name: Update apt cache.
apt: update_cache=yes cache_valid_time=600
when: ansible_os_family == 'Debian'
changed_when: false
- name: Install ssl-cert for default snakeoil cert
apt:
name: ssl-cert
state: present
when: ansible_os_family == 'Debian'
changed_when: false
roles:
- role: worteks.lemonldap.install
22 changes: 22 additions & 0 deletions molecule/vhost/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
# This is an example playbook to execute Ansible tests.

- name: Verify
hosts: all
gather_facts: false
tasks:
- name: Verify web server is running
uri:
url: http://localhost/
status_code: 200
return_content: true
headers:
Host: auth.example.ci
register: result_get_auth_portal
- name: Debug
debug:
msg: '{{ result_get_auth_portal }}'
- name: Check if LemonLDAP is present into response
assert:
that:
- "'LemonLDAP' in result_get_auth_portal.content"
32 changes: 32 additions & 0 deletions roles/vhost/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# VHost

A basic role to handle vhost creation and configuration on LemonLDAP.
Currently we only handle vhosts creation on nginx, the idea behind that
role is also to create a generic way to configure vhosts on nginx side
and LemonLDAP manager (that part is not yet implemented).

## Role Variables

``` yaml
vhost_vhosts
```

List of dictionaries representing vhost we want to configure.

## Example Playbook

- hosts: servers
vars:
vhost_vhosts:
- vhostname: demo.example.com
configure_default_location: true
https: true
port: 443
redirect_http_to_https: true
http_proxy_backend: http://mybackend.example.com
roles:
- { worteks.lemonldap.vhost }

## License

MIT
4 changes: 4 additions & 0 deletions roles/vhost/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
vhost_global_certificate_location: "{{ '/etc/ssl/certs/ssl-cert-snakeoil.pem' if ansible_os_family == 'Debian' else ('/etc/ssl/certs/%s.pem' % ansible_hostname) }}"
vhost_global_certificate_key_location: "{{ '/etc/ssl/private/ssl-cert-snakeoil.key' if ansible_os_family == 'Debian' else ('/etc/ssl/%s.key' % ansible_hostname) }}"
vhost_lua_module_available: "{{ ansible_os_family == 'Debian' }}"
6 changes: 6 additions & 0 deletions roles/vhost/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: Reload webserver
ansible.builtin.service:
name: nginx
state: reloaded
when: ansible_os_family == 'Debian'
27 changes: 27 additions & 0 deletions roles/vhost/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
galaxy_info:
author: Julian Vanden Broeck
description: Configure vhost on LLNG server
company: Dalibo
license: MIT
min_ansible_version: 2.13
platforms:
- name: CentOS
versions:
- all
- name: RedHat
versions:
- all
- name: Debian
versions:
- all
- name: Ubuntu
versions:
- all
galaxy_tags:
- authentication
- SSO
- SAML
- LemonLDAP-NG
- Web
dependencies: []
21 changes: 21 additions & 0 deletions roles/vhost/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
- name: Configure vhost on nginx
ansible.builtin.template:
src: nginx_vhost.j2
dest: '{{ __nginx_vhosts_dir }}{{ item.vhostname }}.conf'
owner: '{{ __nginx_webserver_owner }}'
group: '{{ __nginx_webserver_group }}'
mode: '0640'
loop: '{{ vhost_vhosts }}'
notify: Reload webserver

- name: Create a symbolic link
when: ansible_os_family == 'Debian'
ansible.builtin.file:
src: '{{ __nginx_vhosts_dir }}{{ item.vhostname }}.conf'
dest: '{{ __nginx_vhosts_dir_enabled }}{{ item.vhostname }}.conf'
owner: '{{ __nginx_webserver_owner }}'
group: '{{ __nginx_webserver_group }}'
state: link
loop: '{{ vhost_vhosts }}'
notify: Reload webserver
70 changes: 70 additions & 0 deletions roles/vhost/templates/nginx_vhost.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{% if item.https and (item.redirect_http_to_https | default(false)) %}
server {
listen 80;
server_name {{ item.vhostname }};

# Redirect all traffic to SSL
rewrite ^ https://$host:{{ item.port }}$request_uri? permanent;
}
{% endif %}
server {
{% if item.https %}
listen {{ item.port | default(__nginx_default_https_port) }} ssl http2;
ssl on;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;

# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate {{ item.certificate_location | default(vhost_global_certificate_location) }};
ssl_certificate_key {{ item.certificate_key_location | default(vhost_global_certificate_key_location) }};

{% else %}
listen {{ item.port | default(__nginx_default_http_port) }};
{% endif %}

server_name {{ item.vhostname }};
root /var/www/html;
# Internal authentication request
location = /lmauth {
internal;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/llng-fastcgi-server/llng-fastcgi.sock;
# Drop post data
fastcgi_pass_request_body off;
fastcgi_param CONTENT_LENGTH "";
# Keep original hostname
fastcgi_param HOST $http_host;
# Keep original request (LLNG server will receive /lmauth)
fastcgi_param X_ORIGINAL_URI $original_uri;
}

{% if item.configure_default_location | default(true) %}
# Client requests
location / {
auth_request /lmauth;
set $original_uri $uri$is_args$args;
auth_request_set $lmremote_user $upstream_http_lm_remote_user;
auth_request_set $lmlocation $upstream_http_location;
error_page 401 $lmlocation;
{% if item.http_proxy_backend is defined %}
proxy_pass {{ item.http_proxy_backend }};
include /etc/nginx/proxy_params;
{% endif %}
##################################
# PASSING HEADERS TO APPLICATION #
##################################
include /etc/lemonldap-ng/nginx-lua-headers.conf;
}
{% endif %}
}
7 changes: 7 additions & 0 deletions roles/vhost/vars/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
__nginx_vhosts_dir: "{{ '/etc/nginx/sites-available/' if ansible_os_family == 'Debian' else '/etc/nginx/conf.d/' }}"
__nginx_vhosts_dir_enabled: "{{ '/etc/nginx/sites-enabled/' if ansible_os_family == 'Debian' else '/etc/nginx/conf.d/' }}"
__nginx_webserver_owner: "{{ 'www-data' if ansible_os_family == 'Debian' else 'nginx' }}"
__nginx_webserver_group: "{{ 'www-data' if ansible_os_family == 'Debian' else 'nginx' }}"
__nginx_default_http_port: 80
__nginx_default_https_port: 443
Loading