Fix security settings and mpm
diff --git a/README.rst b/README.rst
index 179de58..0780397 100644
--- a/README.rst
+++ b/README.rst
@@ -136,10 +136,19 @@
server:
# ServerTokens
tokens: Prod
- # ServerSignature
- signature: False
- # TraceEnable
- trace: False
+ # ServerSignature, can be also set per-site
+ signature: false
+ # TraceEnable, can be also set per-site
+ trace: false
+ # Deny access to .git, .svn, .hg directories
+ secure_scm: true
+ # Required for settings bellow
+ modules:
+ - headers
+ # Set X-Content-Type-Options
+ content_type_options: nosniff
+ # Set X-Frame-Options
+ frame_options: sameorigin
Example pillar
==============
diff --git a/apache/files/_name.conf b/apache/files/_name.conf
index 82f10a2..a3b208f 100644
--- a/apache/files/_name.conf
+++ b/apache/files/_name.conf
@@ -13,5 +13,4 @@
{%- endif %}
ServerSignature {% if site.get('signature', server.get('signature', False)) %}On{% else %}Off{% endif %}
- ServerTokens {{ site.get('tokens', server.get('tokens', 'Prod')) }}
TraceEnable {% if site.get('trace', server.get('trace', False)) %}On{% else %}Off{% endif %}
diff --git a/apache/files/mpm/mpm_event.conf b/apache/files/mpm/mpm_event.conf
new file mode 100644
index 0000000..e6d72af
--- /dev/null
+++ b/apache/files/mpm/mpm_event.conf
@@ -0,0 +1,21 @@
+{%- from "apache/map.jinja" import server with context -%}
+{%- set mpm = server.mpm.event -%}
+# event MPM
+# StartServers: initial number of server processes to start
+# MinSpareThreads: minimum number of worker threads which are kept spare
+# MaxSpareThreads: maximum number of worker threads which are kept spare
+# ThreadsPerChild: constant number of worker threads in each server process
+# MaxRequestWorkers: maximum number of worker threads
+# MaxConnectionsPerChild: maximum number of requests a server process serves
+
+<IfModule mpm_event_module>
+ StartServers {{ mpm.servers.start }}
+ MinSpareThreads {{ mpm.servers.spare.min }}
+ MaxSpareThreads {{ mpm.servers.spare.max }}
+ ThreadLimit {{ mpm.limit }}
+ ThreadsPerChild {{ mpm.servers.threads_per_child }}
+ MaxRequestWorkers {{ mpm.max_clients }}
+ MaxConnectionsPerChild {{ mpm.servers.max_requests }}
+</IfModule>
+
+# vim: syntax=apache ts=4 sw=4 sts=4 sr et
diff --git a/apache/files/mpm/mpm_prefork.conf b/apache/files/mpm/mpm_prefork.conf
index 21eeea1..238cbb1 100644
--- a/apache/files/mpm/mpm_prefork.conf
+++ b/apache/files/mpm/mpm_prefork.conf
@@ -1,4 +1,5 @@
-{%- from "apache/map.jinja" import server with context %}
+{%- from "apache/map.jinja" import server with context -%}
+{%- set mpm = server.mpm.prefork -%}
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
@@ -7,12 +8,12 @@
# MaxConnectionsPerChild: maximum number of requests a server process serves
<IfModule mpm_prefork_module>
- StartServers {{ server.mpm.prefork.servers.start }}
- MinSpareServers {{ server.mpm.prefork.servers.spare.min }}
- MaxSpareServers {{ server.mpm.prefork.servers.spare.max }}
- MaxRequestWorkers {{ server.mpm.prefork.max_clients }}
- MaxConnectionsPerChild {{ server.mpm.prefork.servers.max_requests }}
- ServerLimit {{ server.mpm.prefork.limit }}
+ StartServers {{ mpm.servers.start }}
+ MinSpareServers {{ mpm.servers.spare.min }}
+ MaxSpareServers {{ mpm.servers.spare.max }}
+ MaxRequestWorkers {{ mpm.max_clients }}
+ MaxConnectionsPerChild {{ mpm.servers.max_requests }}
+ ServerLimit {{ mpm.limit }}
</IfModule>
-# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
+# vim: syntax=apache ts=4 sw=4 sts=4 sr et
diff --git a/apache/files/mpm/mpm_worker.conf b/apache/files/mpm/mpm_worker.conf
new file mode 100644
index 0000000..6b75d36
--- /dev/null
+++ b/apache/files/mpm/mpm_worker.conf
@@ -0,0 +1,23 @@
+{%- from "apache/map.jinja" import server with context -%}
+{%- set mpm = server.mpm.event -%}
+# worker MPM
+# MinSpareThreads: minimum number of worker threads which are kept spare
+# MaxSpareThreads: maximum number of worker threads which are kept spare
+# ThreadLimit: ThreadsPerChild can be changed to this maximum value during a
+# graceful restart. ThreadLimit can only be changed by stopping
+# and starting Apache.
+# ThreadsPerChild: constant number of worker threads in each server process
+# MaxRequestWorkers: maximum number of threads
+# MaxConnectionsPerChild: maximum number of requests a server process serves
+
+<IfModule mpm_event_module>
+ StartServers {{ mpm.servers.start }}
+ MinSpareThreads {{ mpm.servers.spare.min }}
+ MaxSpareThreads {{ mpm.servers.spare.max }}
+ ThreadLimit {{ mpm.limit }}
+ ThreadsPerChild {{ mpm.servers.threads_per_child }}
+ MaxRequestWorkers {{ mpm.max_clients }}
+ MaxConnectionsPerChild {{ mpm.servers.max_requests }}
+</IfModule>
+
+# vim: syntax=apache ts=4 sw=4 sts=4 sr et
diff --git a/apache/files/security.conf b/apache/files/security.conf
new file mode 100644
index 0000000..2437dd1
--- /dev/null
+++ b/apache/files/security.conf
@@ -0,0 +1,28 @@
+{%- from "apache/map.jinja" import server with context -%}
+ServerSignature {% if server.get('signature', False) %}On{% else %}Off{% endif %}
+TraceEnable {% if server.get('trace', False) %}On{% else %}Off{% endif %}
+ServerTokens {{ server.get('tokens', 'Prod') }}
+
+{%- if server.get('secure_scm', True) %}
+<DirectoryMatch "/\.svn">
+ Require all denied
+</DirectoryMatch>
+
+<DirectoryMatch "/\.git">
+ Require all denied
+</DirectoryMatch>
+
+<DirectoryMatch "/\.hg">
+ Require all denied
+</DirectoryMatch>
+{%- endif %}
+
+{%- if 'headers' in server.get('modules', []) %}
+{%- if server.get('content_type_options', "nosniff") %}
+Header set X-Content-Type-Options: "{{ server.get('content_type_options', 'nosniff') }}"
+{%- endif %}
+
+{%- if server.get('frame_options', "sameorigin") %}
+Header set X-Frame-Options: "{{ server.get('frame_options', 'sameorigin') }}"
+{%- endif %}
+{%- endif %}
diff --git a/apache/map.jinja b/apache/map.jinja
index a1dddb3..dde5d4f 100644
--- a/apache/map.jinja
+++ b/apache/map.jinja
@@ -10,7 +10,7 @@
'mod_auth_kerb': 'libapache2-mod-auth-kerb',
'htpasswd_dir': '/etc/apache2',
'vhost_dir': '/etc/apache2/sites-available',
- 'conf_dir': '/etc/apache2/conf.d',
+ 'conf_dir': '/etc/apache2/conf-available',
'conf_ext': '.conf',
'log_dir': '/var/log/apache2',
'wwwdir': '/srv',
diff --git a/apache/server/service.sls b/apache/server/service.sls
deleted file mode 100644
index e6dc6a8..0000000
--- a/apache/server/service.sls
+++ /dev/null
@@ -1,151 +0,0 @@
-{%- from "apache/map.jinja" import server with context %}
-{%- if server.enabled %}
-
-apache_packages:
- pkg.installed:
- - names: {{ server.pkgs }}
-
-apache_ports_config:
- file.managed:
- - name: /etc/apache2/ports.conf
- - source: salt://apache/files/ports.conf
- - template: jinja
- - require:
- - pkg: apache_packages
- - watch_in:
- - service: apache_service
-
-{%- for module in server.modules %}
-
-{%- if module == 'passenger' %}
-
-apache_passenger_package:
- pkg.installed:
- - name: libapache2-mod-passenger
- - require:
- - pkg: apache_packages
-
-{%- endif %}
-
-{%- if module == 'php' %}
-
-apache_php_package:
- pkg.installed:
- - name: {{ server.mod_php }}
- - require:
- - pkg: apache_packages
-
-{%- set module = 'php5' %}
-
-{%- endif %}
-
-{%- if module == 'perl' %}
-
-apache_perl_package:
- pkg.installed:
- - name: {{ server.mod_perl }}
- - require:
- - pkg: apache_packages
-
-{%- endif %}
-
-{%- if module == 'wsgi' %}
-
-apache_wsgi_package:
- pkg.installed:
- - name: {{ server.mod_wsgi }}
- - require:
- - pkg: apache_packages
-
-{%- endif %}
-
-{%- if module == 'xsendfile' %}
-
-apache_xsendfile_package:
- pkg.installed:
- - name: {{ server.mod_xsendfile }}
- - require:
- - pkg: apache_packages
-
-{%- endif %}
-
-{%- if module == 'auth_kerb' %}
-
-apache_auth_kerb_package:
- pkg.installed:
- - name: {{ server.mod_auth_kerb }}
- - require:
- - pkg: apache_packages
-
-{%- endif %}
-
-apache_{{ module }}_enable:
- cmd.run:
- - name: "a2enmod {{ module }}"
- - creates: /etc/apache2/mods-enabled/{{ module }}.load
- - require:
- - pkg: apache_packages
- - watch_in:
- - service: apache_service
-
-{%- endfor %}
-
-/etc/apache2/sites-enabled/000-default.conf:
- file.absent
-
-apache_service:
- service.running:
- - name: {{ server.service }}
- - reload: true
- - enable: true
- - require:
- - pkg: apache_packages
-
-{%- else %}
-
-apache_service_dead:
- service.dead:
- - name: {{ server.service }}
-
-apache_remove_packages:
- pkg.purged:
- - pkgs: {{ server.pkgs }}
- - require:
- - service: apache_service_dead
-
-{%- for mpm_type, mpm in server.mpm.iteritems() %}
-
-{%- if mpm.enabled %}
-
-apache_mpm_{{ mpm_type }}_enable:
- cmd.run:
- - name: "a2enmod mpm_{{ mpm_type }}"
- - creates: /etc/apache2/mods-enabled/mpm_{{ mpm_type }}.load
- - require:
- - file: apache_mpm_{{ mpm_type }}_config
- - watch_in:
- - service: apache_service
-
-apache_mpm_{{ mpm_type }}_config:
- file.managed:
- - name /etc/apache2/mods-available/mpm_{{ mpm_type }}.conf
- - source: salt://apache/files/mpm/mpm_{{ mpm_type }}.conf
- - template: jinja
- - require:
- - pkg: apache_packages
- - watch_in:
- - service: apache_service
-
-{%- else %}
-
-apache_mpm_{{ mpm_type }}_disable:
- file.absent:
- - name: /etc/apache2/mods-enabled/mpm_{{ mpm_type }}.load
- - watch_in:
- - service: apache_service
-
-{%- endif %}
-
-{%- endfor %}
-
-{%- endif %}
diff --git a/apache/server/service/init.sls b/apache/server/service/init.sls
new file mode 100644
index 0000000..c7f43c1
--- /dev/null
+++ b/apache/server/service/init.sls
@@ -0,0 +1,68 @@
+{%- from "apache/map.jinja" import server with context %}
+
+include:
+- apache.server.service.modules
+- apache.server.service.mpm
+
+{%- if server.enabled %}
+
+apache_packages:
+ pkg.installed:
+ - names: {{ server.pkgs }}
+
+apache_ports_config:
+ file.managed:
+ - name: /etc/apache2/ports.conf
+ - source: salt://apache/files/ports.conf
+ - template: jinja
+ - require:
+ - pkg: apache_packages
+ - watch_in:
+ - service: apache_service
+
+apache_security_config:
+ file.managed:
+ - name: {{ server.conf_dir }}/security.conf
+ - source: salt://apache/files/security.conf
+ - template: jinja
+ - require:
+ - pkg: apache_packages
+ - watch_in:
+ - service: apache_service
+
+{%- if grains.os_family == "Debian" %}
+/etc/apache2/conf-enabled/security.conf:
+ file.symlink:
+ - target: {{ server.conf_dir }}/security.conf
+ - require:
+ - file: {{ server.conf_dir }}/security.conf
+ - watch_in:
+ - service: apache_service
+{%- endif %}
+
+/etc/apache2/sites-enabled/000-default.conf:
+ file.absent:
+ - watch_in:
+ - service: apache_service
+
+apache_service:
+ service.running:
+ - name: {{ server.service }}
+ - reload: true
+ - enable: true
+ - require:
+ - pkg: apache_packages
+
+{%- else %}
+
+apache_service_dead:
+ service.dead:
+ - name: {{ server.service }}
+
+apache_remove_packages:
+ pkg.purged:
+ - pkgs: {{ server.pkgs }}
+ - require:
+ - service: apache_service_dead
+
+{%- endif %}
diff --git a/apache/server/service/modules.sls b/apache/server/service/modules.sls
new file mode 100644
index 0000000..cee92fe
--- /dev/null
+++ b/apache/server/service/modules.sls
@@ -0,0 +1,79 @@
+{%- from "apache/map.jinja" import server with context %}
+{%- if server.enabled %}
+
+{%- for module in server.modules %}
+
+{%- if module == 'passenger' %}
+
+apache_passenger_package:
+ pkg.installed:
+ - name: libapache2-mod-passenger
+ - require:
+ - pkg: apache_packages
+
+{%- endif %}
+
+{%- if module == 'php' %}
+
+apache_php_package:
+ pkg.installed:
+ - name: {{ server.mod_php }}
+ - require:
+ - pkg: apache_packages
+
+{%- set module = 'php5' %}
+
+{%- endif %}
+
+{%- if module == 'perl' %}
+
+apache_perl_package:
+ pkg.installed:
+ - name: {{ server.mod_perl }}
+ - require:
+ - pkg: apache_packages
+
+{%- endif %}
+
+{%- if module == 'wsgi' %}
+
+apache_wsgi_package:
+ pkg.installed:
+ - name: {{ server.mod_wsgi }}
+ - require:
+ - pkg: apache_packages
+
+{%- endif %}
+
+{%- if module == 'xsendfile' %}
+
+apache_xsendfile_package:
+ pkg.installed:
+ - name: {{ server.mod_xsendfile }}
+ - require:
+ - pkg: apache_packages
+
+{%- endif %}
+
+{%- if module == 'auth_kerb' %}
+
+apache_auth_kerb_package:
+ pkg.installed:
+ - name: {{ server.mod_auth_kerb }}
+ - require:
+ - pkg: apache_packages
+
+{%- endif %}
+
+apache_{{ module }}_enable:
+ cmd.run:
+ - name: "a2enmod {{ module }}"
+ - creates: /etc/apache2/mods-enabled/{{ module }}.load
+ - require:
+ - pkg: apache_packages
+ - watch_in:
+ - service: apache_service
+
+{%- endfor %}
+
+{%- endif %}
diff --git a/apache/server/service/mpm.sls b/apache/server/service/mpm.sls
new file mode 100644
index 0000000..ff7907e
--- /dev/null
+++ b/apache/server/service/mpm.sls
@@ -0,0 +1,52 @@
+{%- from "apache/map.jinja" import server with context %}
+{%- if server.enabled %}
+
+{%- if grains.os_family == 'Debian' %}
+
+{%- for mpm_type, mpm in server.mpm.iteritems() %}
+
+{%- if mpm.enabled %}
+
+apache_mpm_{{ mpm_type }}_enable:
+ cmd.run:
+ - name: "a2enmod mpm_{{ mpm_type }}"
+ - creates: /etc/apache2/mods-enabled/mpm_{{ mpm_type }}.load
+ - require:
+ - file: apache_mpm_{{ mpm_type }}_config
+ {%- for mpm_name, dummy in server.mpm.iteritems() if mpm_name != mpm_type %}
+ - file: apache_mpm_{{ mpm_name }}_disable
+ {%- endfor %}
+ - watch_in:
+ - service: apache_service
+
+apache_mpm_{{ mpm_type }}_config:
+ file.managed:
+ - name: /etc/apache2/mods-available/mpm_{{ mpm_type }}.conf
+ - source: salt://apache/files/mpm/mpm_{{ mpm_type }}.conf
+ - template: jinja
+ - require:
+ - pkg: apache_packages
+ - watch_in:
+ - service: apache_service
+
+{%- else %}
+
+apache_mpm_{{ mpm_type }}_disable:
+ file.absent:
+ - name: /etc/apache2/mods-enabled/mpm_{{ mpm_type }}.load
+ - watch_in:
+ - service: apache_service
+
+apache_mpm_{{ mpm_type }}_conf_disable:
+ file.absent:
+ - name: /etc/apache2/mods-enabled/mpm_{{ mpm_type }}.conf
+ - watch_in:
+ - service: apache_service
+
+{%- endif %}
+
+{%- endfor %}
+
+{%- endif %}
+
+{%- endif %}
diff --git a/metadata/service/server/single.yml b/metadata/service/server/single.yml
index 304285e..88220d9 100644
--- a/metadata/service/server/single.yml
+++ b/metadata/service/server/single.yml
@@ -31,5 +31,27 @@
limit: ${apache:server:mpm:prefork:max_clients}
event:
enabled: false
+ servers:
+ start: 5
+ spare:
+ min: 25
+ max: 75
+ # Avoid memory leakage by restarting workers every x requests
+ max_requests: 0
+ # Should be 80% of server memory / average memory usage of one worker
+ max_clients: 150
+ limit: 64
+ threads_per_child: 25
worker:
enabled: false
+ servers:
+ start: 5
+ spare:
+ min: 25
+ max: 75
+ # Avoid memory leakage by restarting workers every x requests
+ max_requests: 0
+ # Should be 80% of server memory / average memory usage of one worker
+ max_clients: 150
+ limit: 64
+ threads_per_child: 25
diff --git a/tests/pillar/apache_server.sls b/tests/pillar/apache_server.sls
index e6dab85..2a4ac0b 100644
--- a/tests/pillar/apache_server.sls
+++ b/tests/pillar/apache_server.sls
@@ -53,4 +53,21 @@
- lists.example.com
- mail01.example.com
- mail01
-
+ mpm:
+ prefork:
+ enabled: true
+ servers:
+ start: 5
+ spare:
+ min: ${apache:server:mpm:prefork:servers:start}
+ max: 10
+ # Avoid memory leakage by restarting workers every x requests
+ max_requests: 0
+ # Should be 80% of server memory / average memory usage of one worker
+ max_clients: 150
+ # Should be same or more than max clients
+ limit: ${apache:server:mpm:prefork:max_clients}
+ event:
+ enabled: false
+ worker:
+ enabled: true