diff --git a/ANSIBLE/group_vars/dev_roundcube/main.yml b/ANSIBLE/group_vars/dev_roundcube/main.yml
index ad005a9..6e90482 100644
--- a/ANSIBLE/group_vars/dev_roundcube/main.yml
+++ b/ANSIBLE/group_vars/dev_roundcube/main.yml
@@ -1,2 +1,69 @@
---
httpd_php: true
+httpd_tls_site_root: /srv/roundcube/roundcubemail-{{ roundcube_version }}/public_html
+httpd_optional_enabled_modules:
+ - deflate
+ - expires
+ - headers
+httpd_tls_vhost_raw: |
+
+ Options +SymLinksIfOwnerMatch
+ RewriteEngine On
+ RewriteRule ^favicon\.ico$ skins/elastic/images/favicon.ico
+
+ # security rules:
+ # - deny access to files not containing a dot or starting with a dot
+ # in all locations except installer directory
+ RewriteRule ^(?!installer|\.well-known\/|[a-zA-Z0-9]{16})(\.?[^\.]+)$ - [F]
+ # - deny access to some locations
+ RewriteRule ^/?(\.git|\.tx|SQL|bin|config|logs|temp|tests|vendor|program\/(include|lib|localization|steps)) - [F]
+ # - deny access to some documentation files
+ RewriteRule /?(README.*|CHANGELOG.*|SECURITY.*|meta\.json|composer\..*|jsdeps.json)$ - [F]
+
+
+
+ SetOutputFilter DEFLATE
+
+
+ # prefer to brotli over gzip if brotli is available
+
+ SetOutputFilter BROTLI_COMPRESS
+ # some assets have been compressed, so no need to do it again
+ SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|web[pm]|woff2?)$ no-brotli
+
+
+
+ ExpiresActive On
+ ExpiresDefault "access plus 1 month"
+
+
+ FileETag MTime Size
+
+
+ Options -Indexes
+
+
+
+ # Disable page indexing
+ Header set X-Robots-Tag "noindex, nofollow"
+ # replace 'merge' with 'append' for Apache < 2.2.9
+ #Header merge Cache-Control public env=!NO_CACHE
+ # Optional security headers
+ # Only provides increased security if the browser supports those features
+ # Be careful! Testing is required! They should be adjusted to your installation / user environment
+ # HSTS - HTTP Strict Transport Security
+ #Header always set Strict-Transport-Security "max-age=31536000; preload" env=HTTPS
+ # HPKP - HTTP Public Key Pinning
+ # Only template - fill with your values
+ #Header always set Public-Key-Pins "max-age=3600; report-uri=\"\"; pin-sha256=\"\"; pin-sha256=\"\"" env=HTTPS
+ # X-Xss-Protection
+ # This header is used to configure the built in reflective XSS protection found in Internet Explorer, Chrome and Safari (Webkit).
+ #Header set X-XSS-Protection "1; mode=block"
+ # X-Frame-Options
+ # The X-Frame-Options header (RFC), or XFO header, protects your visitors against clickjacking attacks
+ # Already set by php code! Do not activate both options
+ #Header set X-Frame-Options SAMEORIGIN
+ # X-Content-Type-Options
+ # It prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server.
+ #Header set X-Content-Type-Options "nosniff"
+
\ No newline at end of file
diff --git a/ANSIBLE/roles/httpd/defaults/main.yml b/ANSIBLE/roles/httpd/defaults/main.yml
index 5bedd1e..575905a 100644
--- a/ANSIBLE/roles/httpd/defaults/main.yml
+++ b/ANSIBLE/roles/httpd/defaults/main.yml
@@ -1,8 +1,25 @@
+httpd_pkgs:
+ - apache2
+httpd_pkgs_plugins: []
+
httpd_site_name: 'default'
httpd_site_root: '/var/www/html'
+httpd_default_enabled_modules:
+ - ssl
+httpd_optional_enabled_modules: []
+
+httpd_tls_certbot: true
+httpd_tls_auto_redirect: true
+httpd_tls_certbot_additonal_args: ''
+httpd_tls_site_root:
+
+httpd_tls_vhost_default: true
+
+httpd_tls_vhost_raw: ''
httpd_php: false
httpd_php_version: 8.3
+httpd_php_socket: '/run/php/php{{ httpd_php_version }}-fpm.sock'
httpd_php_pkgs:
- php
- php-fpm
@@ -13,4 +30,7 @@ httpd_php_pkgs:
- php-mbstring
- php-xml
- php-zip
-
\ No newline at end of file
+httpd_php_enabled_modules:
+ - proxy_fcgi
+ - setenvif
+ - php{{ httpd_php_version }}
diff --git a/ANSIBLE/roles/httpd/tasks/httpd_certbot_tls.yml b/ANSIBLE/roles/httpd/tasks/httpd_certbot_tls.yml
new file mode 100644
index 0000000..dc31599
--- /dev/null
+++ b/ANSIBLE/roles/httpd/tasks/httpd_certbot_tls.yml
@@ -0,0 +1,20 @@
+---
+- name: Install Certbot and Apache plugin
+ ansible.builtin.apt:
+ name:
+ - certbot
+ - python3-certbot-apache
+ state: present
+- name: Ensure Apache is running and enabled
+ ansible.builtin.service:
+ name: apache2
+ state: started
+ enabled: true
+- name: Obtain Let's Encrypt certificate using certbot
+ ansible.builtin.command: >
+ certbot --apache -n --agree-tos --redirect
+ -d {{ httpd_site_name }}
+ --email {{ admin_email }} {{ httpd_tls_certbot_additonal_args }}
+ args:
+ creates: "/etc/letsencrypt/live/{{ httpd_site_name }}/fullchain.pem"
+
diff --git a/ANSIBLE/roles/httpd/tasks/httpd_default_config.yml b/ANSIBLE/roles/httpd/tasks/httpd_default_config.yml
index 55a6b65..548d087 100644
--- a/ANSIBLE/roles/httpd/tasks/httpd_default_config.yml
+++ b/ANSIBLE/roles/httpd/tasks/httpd_default_config.yml
@@ -11,12 +11,21 @@
ansible.builtin.template:
src: httpd/vhost.conf.j2
dest: "/etc/apache2/sites-available/{{ httpd_site_name }}.conf"
+ owner: www-data
+ group: www-data
+ mode: '0644'
notify: Reload Apache
-- name: Enable site
+- name: "Enable http site {{ httpd_site_name }}"
ansible.builtin.command: "a2ensite {{ httpd_site_name }}"
+ args:
+ creates: "/etc/apache2/sites-enabled/{{ httpd_site_name }}.conf"
notify: Reload Apache
-- name: Enable SSL module
- ansible.builtin.command: a2enmod ssl
+- name: Enable modules
+ ansible.builtin.command: " a2enmod {{ item }}"
+ args:
+ creates: "/etc/apache2/mods-enabled/{{ item }}*"
+ loop: "{{ httpd_default_enabled_modules + httpd_optional_enabled_modules }}"
notify: Reload Apache
+
diff --git a/ANSIBLE/roles/httpd/tasks/httpd_install.yml b/ANSIBLE/roles/httpd/tasks/httpd_install.yml
index 9c2cddb..057f776 100644
--- a/ANSIBLE/roles/httpd/tasks/httpd_install.yml
+++ b/ANSIBLE/roles/httpd/tasks/httpd_install.yml
@@ -1,17 +1,10 @@
---
-- name: Install Apache2
+- name: Install Apache2 and plugins
ansible.builtin.apt:
- name: apache2
+ name: "{{ httpd_pkgs + httpd_pkgs_plugins }}"
state: present
update_cache: true
-- name: Install Certbot and Apache plugin
- ansible.builtin.apt:
- name:
- - certbot
- - python3-certbot-apache
- state: present
-
- name: Ensure site root exists
ansible.builtin.file:
path: "{{ httpd_site_root }}"
@@ -20,3 +13,9 @@
group: www-data
mode: '0755'
+- name: Ensure Apache is running and enabled
+ ansible.builtin.service:
+ name: apache2
+ state: started
+ enabled: true
+
diff --git a/ANSIBLE/roles/httpd/tasks/httpd_vhost_tls.yml b/ANSIBLE/roles/httpd/tasks/httpd_vhost_tls.yml
new file mode 100644
index 0000000..2bcba07
--- /dev/null
+++ b/ANSIBLE/roles/httpd/tasks/httpd_vhost_tls.yml
@@ -0,0 +1,19 @@
+---
+- name: "Disable Certbot autocreated {{ httpd_site_name }}-le-ssl"
+ ansible.builtin.command: "a2dissite {{ httpd_site_name }}-le-ssl"
+ args:
+ removes: "/etc/apache2/sites-enabled/{{ httpd_site_name }}-le-ssl.conf"
+ notify: Reload Apache
+- name: Create Apache TLS virtual host config
+ ansible.builtin.template:
+ src: httpd/tls_vhost.conf.j2
+ dest: "/etc/apache2/sites-available/{{ httpd_site_name }}_tls.conf"
+ owner: www-data
+ group: www-data
+ mode: '0644'
+ notify: Reload Apache
+- name: "Enable http site {{ httpd_site_name }}_tls"
+ ansible.builtin.command: "a2ensite {{ httpd_site_name }}_tls"
+ args:
+ creates: "/etc/apache2/sites-enabled/{{ httpd_site_name }}_tls.conf"
+ notify: Reload Apache
diff --git a/ANSIBLE/roles/httpd/tasks/main.yml b/ANSIBLE/roles/httpd/tasks/main.yml
index ee21aa9..e1e84ab 100644
--- a/ANSIBLE/roles/httpd/tasks/main.yml
+++ b/ANSIBLE/roles/httpd/tasks/main.yml
@@ -4,21 +4,11 @@
ansible.builtin.include_tasks: httpd_install.yml
- name: Apache2 Default Config
ansible.builtin.include_tasks: httpd_default_config.yml
-
-- name: Ensure Apache is running and enabled
- ansible.builtin.service:
- name: apache2
- state: started
- enabled: true
-
-- name: Obtain Let's Encrypt certificate using certbot
- ansible.builtin.command: >
- certbot --apache -n --agree-tos --redirect
- -d {{ httpd_site_name }}
- --email {{ admin_email }}
- args:
- creates: "/etc/letsencrypt/live/{{ httpd_site_name }}/fullchain.pem"
-
+- name: Certbot TLS
+ when: httpd_tls_certbot
+ ansible.builtin.include_tasks: httpd_certbot_tls.yml
- name: PHP Application
when: httpd_php
ansible.builtin.include_tasks: php.yml
+- name: TLS Enabled Site
+ ansible.builtin.include_tasks: httpd_vhost_tls.yml
diff --git a/ANSIBLE/roles/httpd/tasks/php.yml b/ANSIBLE/roles/httpd/tasks/php.yml
index a430cad..2673c23 100644
--- a/ANSIBLE/roles/httpd/tasks/php.yml
+++ b/ANSIBLE/roles/httpd/tasks/php.yml
@@ -6,12 +6,12 @@
update_cache: true
- name: Enable Apache modules for PHP-FPM
ansible.builtin.command: a2enmod {{ item }}
- loop:
- - proxy_fcgi
- - setenvif
- - php{{ httpd_php_version }} # or php8.1 depending on your distro
+ args:
+ creates: "/etc/apache2/mods-enabled/{{ item }}*"
+ loop: "{{ httpd_php_enabled_modules }}"
notify: Reload Apache
ignore_errors: true # in case some modules aren't available
+ register: httpd_php_modules_errors
- name: Ensure PHP-FPM service is running
ansible.builtin.service:
@@ -29,4 +29,3 @@
mode: '0644'
notify: Restart PHP-FPM
-
diff --git a/ANSIBLE/roles/httpd/templates/httpd/tls_vhost.conf.j2 b/ANSIBLE/roles/httpd/templates/httpd/tls_vhost.conf.j2
new file mode 100644
index 0000000..cd573fe
--- /dev/null
+++ b/ANSIBLE/roles/httpd/templates/httpd/tls_vhost.conf.j2
@@ -0,0 +1,33 @@
+
+
+ # General vhost config
+ ServerName {{ httpd_site_name }}
+ DocumentRoot {{ httpd_tls_site_root }}
+ #TLS Config
+ SSLCertificateFile /etc/letsencrypt/live/{{ httpd_site_name }}/fullchain.pem
+ SSLCertificateKeyFile /etc/letsencrypt/live/{{ httpd_site_name }}/privkey.pem
+ Include /etc/letsencrypt/options-ssl-apache.conf
+ # Standardised Access & error Logging locations
+ ErrorLog ${APACHE_LOG_DIR}/{{ httpd_site_name }}_error.log
+ CustomLog ${APACHE_LOG_DIR}/{{ httpd_site_name }}_access.log combined
+{% if httpd_tls_vhost_default %}
+
+ Options Indexes FollowSymLinks
+ AllowOverride All
+ Require all granted
+ {% if httpd_php %}
+
+ SetHandler "proxy:unix:{{ httpd_php_socket }}|fcgi://localhost/"
+
+ {% endif %}
+
+{% endif %}
+
+{% if httpd_tls_vhost_raw != '' %}
+
+ {{ httpd_tls_vhost_raw }}
+
+{% endif %}
+
+
+
diff --git a/ANSIBLE/roles/httpd/templates/php/www.conf.j2 b/ANSIBLE/roles/httpd/templates/php/www.conf.j2
index a338f10..b7b688f 100644
--- a/ANSIBLE/roles/httpd/templates/php/www.conf.j2
+++ b/ANSIBLE/roles/httpd/templates/php/www.conf.j2
@@ -3,7 +3,7 @@
user = www-data
group = www-data
-listen = /run/php/php{{ httpd_php_version }}-fpm.sock
+listen = {{ httpd_php_socket }}
listen.owner = www-data
listen.group = www-data