Commit eee846a4dc6bc83e294e2fc5472231d1faa4f750

Authored by nollieheel
1 parent 70b9bd40

Bump to v0.3.0.

Add support for multiple upstream servers in nginx config.
Add support for LetsEncrypt certificate configurations.
  1 +# 0.3.0
  2 +
  3 +Add support for multiple FastCGI ports.
  4 +Add support for Letsencrypt configuration.
  5 +
1 # 0.2.1 6 # 0.2.1
2 7
3 Add some defaults for php-fpm 8 Add some defaults for php-fpm
@@ -18,12 +18,6 @@ Ubuntu 14.04 @@ -18,12 +18,6 @@ Ubuntu 14.04
18 <th>Default</th> 18 <th>Default</th>
19 </tr> 19 </tr>
20 <tr> 20 <tr>
21 - <td><tt>['cfe-nginx-php-fpm']['php_fastcgi_socket']</tt></td>  
22 - <td>String</td>  
23 - <td>The socket used by PHP-FPM. Set to boolean false to disable PHP-FPM.</td>  
24 - <td><tt>'127.0.0.1:9000'</tt></td>  
25 - </tr>  
26 - <tr>  
27 <td><tt>['cfe-nginx-php-fpm']['postfix']['email_domain']</tt></td> 21 <td><tt>['cfe-nginx-php-fpm']['postfix']['email_domain']</tt></td>
28 <td>String</td> 22 <td>String</td>
29 <td>Email domain to be used by Postfix.</td> 23 <td>Email domain to be used by Postfix.</td>
1 # 1 #
2 -# Author:: Earth U (<sysadmin@chromedia.com>) 2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
3 # Cookbook Name:: cfe-nginx-php-fpm 3 # Cookbook Name:: cfe-nginx-php-fpm
4 # Attribute:: default 4 # Attribute:: default
5 # 5 #
@@ -18,12 +18,30 @@ @@ -18,12 +18,30 @@
18 # limitations under the License. 18 # limitations under the License.
19 # 19 #
20 20
  21 +# TODO defunct attribs
21 # The socket used PHP-FPM. If false, fastcgi is not used. 22 # The socket used PHP-FPM. If false, fastcgi is not used.
22 # Examples: 23 # Examples:
23 # '127.0.0.1:9000' 24 # '127.0.0.1:9000'
24 # '/var/run/php-fpm.sock' 25 # '/var/run/php-fpm.sock'
25 # false 26 # false
26 -default['cfe-nginx-php-fpm']['php_fastcgi_socket'] = '127.0.0.1:9000' 27 +#default['cfe-nginx-php-fpm']['php_fastcgi_socket'] = '127.0.0.1:9000'
  28 +
  29 +# PHP-FPM sockets to be used. If unset, or set to string 'php-fpm-pools' (default),
  30 +# the recipe automatically gets this value from node['php-fpm']['pools'].
  31 +#default['cfe-nginx-php-fpm']['php_fastcgi_sockets'] = [
  32 +# {
  33 +# :name => 'example_socket',
  34 +# # Example values:
  35 +# # '127.0.0.1:9000'
  36 +# # '127.0.0.1:9001'
  37 +# # '/var/run/php-fpm.sock'
  38 +# :listen => '127.0.0.1:9000',
  39 +# # An optional array of comments for this socket
  40 +# :comments => []
  41 +# }
  42 +#]
  43 +
  44 +
27 45
28 # Setting 'update_cacert' to true will get the latest cacert from 46 # Setting 'update_cacert' to true will get the latest cacert from
29 # http://curl.haxx.se/ca/cacert.pem and use that as CAFile for postfix. 47 # http://curl.haxx.se/ca/cacert.pem and use that as CAFile for postfix.
@@ -51,35 +69,64 @@ default['cfe-nginx-php-fpm']['nginx']['restriction_file']['static_types'] = %w{ @@ -51,35 +69,64 @@ default['cfe-nginx-php-fpm']['nginx']['restriction_file']['static_types'] = %w{
51 69
52 default['cfe-nginx-php-fpm']['nginx']['sites'] = [ 70 default['cfe-nginx-php-fpm']['nginx']['sites'] = [
53 #{ 71 #{
  72 + # Name of server. Mandatory.
  73 + #
54 #:server_name => 'example.com', 74 #:server_name => 'example.com',
  75 +
  76 + # Server aliases in an array. Default: []
  77 + #
55 #:aliases => ['www.example.com'], 78 #:aliases => ['www.example.com'],
  79 +
  80 + # Location of document root. If not given, the root directive
  81 + # will not be included in the config. Default: nil
  82 + #
56 #:doc_root => '/var/www/example.com', 83 #:doc_root => '/var/www/example.com',
  84 +
  85 + # Index, if applicable, of the site. Default: nil
  86 + #
57 #:index => 'index.php', 87 #:index => 'index.php',
58 88
59 - # Access log options as one long string. Default: false 89 + # Access log options as one long string. Default: nil
  90 + #
60 #:access_log_options => '<some options>', 91 #:access_log_options => '<some options>',
61 92
62 # Whether to include a default virtual server named '_' or not. 93 # Whether to include a default virtual server named '_' or not.
63 # If there is more than one server given in this 'sites' array, 94 # If there is more than one server given in this 'sites' array,
64 - # 'catch_all' value will always be overriden to 'false'.  
65 - # Default: true 95 + # :catch_all value will always be overriden to false. Default: true
  96 + #
66 #:catch_all => true, 97 #:catch_all => true,
67 98
68 - # Necessary values for SSL/TLS setup. Default: :ssl => false 99 + # Necessary values for SSL/TLS setup. Default: nil
  100 + #
69 #:ssl => { 101 #:ssl => {
70 - # :cert => '[contents of chain cert here]',  
71 - # :key => '[contents of cert private key here]',  
72 - # :dh_modulus => 2048,  
73 - # :self_signed => false,  
74 - # :hsts_max_age => '15758000',  
75 - # :hsts_include_subdomains => true 102 + # # Subvalues and their defaults:
  103 + #
  104 + # # If LetsEncrypt is used, set to true.
  105 + # # le_sub_dir defaults to the server name.
  106 + # #
  107 + # :letsencrypt => false,
  108 + # :le_base_dir => '/etc/letsencrypt/live',
  109 + # :le_sub_dir => '<server_name>',
  110 + #
  111 + # # If not using LetsEncrypt, specify cert and key here.
  112 + # # If using LetsEncrypt, these attributes are not used:
  113 + # #
  114 + # :cert => '<contents of chain cert here>',
  115 + # :key => '<contents of cert private key here>',
  116 + #
  117 + # :self_signed => false,
  118 + # :cipher_suite => 'medium', # or 'modern'
  119 + # :dh_modulus => 4096,
  120 + # :hsts_max_age => '15758000',
  121 + # :hsts_subdomains => true
76 #}, 122 #},
77 123
78 - # Necessary values for Basic Auth setup. Default: :auth => false 124 + # Necessary values for Basic Auth setup. Default: nil
  125 + #
79 #:auth => { 126 #:auth => {
80 # :msg => 'Restricted Area. Please authenticate.', 127 # :msg => 'Restricted Area. Please authenticate.',
81 # :users => { 128 # :users => {
82 - # 'example_user' => 'secretpassword123' 129 + # 'example_user' => '<password>'
83 # } 130 # }
84 #}, 131 #},
85 132
@@ -87,31 +134,63 @@ default['cfe-nginx-php-fpm']['nginx']['sites'] = [ @@ -87,31 +134,63 @@ default['cfe-nginx-php-fpm']['nginx']['sites'] = [
87 # the 'server' declaration. Default: [] 134 # the 'server' declaration. Default: []
88 #:init_statements => [], 135 #:init_statements => [],
89 136
  137 + # Additional headers to insert into the server responses.
  138 + # If the site uses HTTPS, the header 'Strict-Transport-Security' will
  139 + # always be included. Default:
  140 + # {
  141 + # 'X-Frame-Options' => 'SAMEORIGIN',
  142 + # 'X-Content-Type-Options' => 'nosniff',
  143 + # 'X-XSS-Protection' => '"1; mode=block"',
  144 + # 'X-Permitted-Cross-Domain-Policies' => 'none'
  145 + # }
  146 + #
  147 + #:add_headers => {},
  148 +
90 # An array of strings that will be included as statements in the main 149 # An array of strings that will be included as statements in the main
91 - # nginx config file for this server. Default: []  
92 - #:custom_statements => [], 150 + # nginx config file for this server, before the first 'include'
  151 + # directive. Default: []
  152 + #
  153 + #:server_statements_1 => [],
  154 +
  155 + # An array of strings that will be included as statements in the main
  156 + # nginx config file for this server, after the last 'include'
  157 + # directive. Default: []
  158 + #
  159 + #:server_statements_2 => [],
93 160
94 # Enumerates the different site types this server supports. 161 # Enumerates the different site types this server supports.
95 - # Possible elements of :types are (only :type is mandatory):  
96 - # {  
97 - # :type => 'basic',  
98 - # :subpath => ''  
99 - # }  
100 - # {  
101 - # :type => 'wordpress',  
102 - # :subpath => '',  
103 - # :fastcgi_intercept_errors => false,  
104 - # :loginpage_statements => [] # An array of strings to be  
105 - # # written on the config for the  
106 - # # /wp-login.php and /wp-admin pages.  
107 - # }  
108 - # {  
109 - # :type => 'webserver',  
110 - # :subpath => '',  
111 - # :upstream_name => 'example',  
112 - # :upstream_ip => '127.0.0.1',  
113 - # :upstream_port => '8080',  
114 - # } 162 + # Each type element of this array is a hash containing different attributes.
  163 + #
  164 + # Mandatory attributes are:
  165 + # :type => One of: 'basic' (basic PHP site)
  166 + # 'wordpress' (standard Wordpress site)
  167 + # 'webserver' (proxy webserver)
  168 + # :upstream_servers => An array containing upstream server endpoints.
  169 + # Unix socket example: ['/var/run/php-fpm.sock']
  170 + # Tcp port example: ['127.0.0.1:9000']
  171 + #
  172 + # Optional attributes are:
  173 + # :subpath => A string of the form: 'news/blog'.
  174 + # Indicates what subpath of the site this type applies.
  175 + # Default: '', which means this site type applies
  176 + # to the root directory of the site.
  177 + # :upstream_name => The auto-generated config's upstream name can
  178 + # be customized through this attribute.
  179 + # Default: (an auto-generated string)
  180 + # :add_statements => Additional statements to put in the config file.
  181 + # Default: []
  182 + #
  183 + # Unique attributes for each type are indicated below:
  184 + # Basic PHP Site (:type => 'basic'):
  185 + # :fastcgi_intercept_errors => Optional. Default: false
  186 + # Standard Wordpress Site (:type => 'wordpress'):
  187 + # :fastcgi_intercept_errors => Optional. Default: false
  188 + # :loginpage_statements => An array of strings to be put on the
  189 + # config for the /wp-login.php
  190 + # and /wp-admin pages. Default: []
  191 + # Proxy Webserver (:type => 'webserver'):
  192 + # (none)
  193 + #
115 #:types => [] 194 #:types => []
116 #} 195 #}
117 ] 196 ]
@@ -132,12 +211,14 @@ default['php-fpm']['pools'] = [ @@ -132,12 +211,14 @@ default['php-fpm']['pools'] = [
132 # Most likely, just use one pool for all PHP needs. 211 # Most likely, just use one pool for all PHP needs.
133 # (But there are exceptions, of course) 212 # (But there are exceptions, of course)
134 { 213 {
  214 + # Required attributes:
135 :name => 'example_pool', 215 :name => 'example_pool',
136 :enable => true, 216 :enable => true,
  217 + :listen => '127.0.0.1:9000',
  218 + #:listen => '/var/run/php-fpm.sock',
137 219
138 - # Default value is: node['cfe-nginx-php-fpm']['php_fastcgi_socket']  
139 - #:listen => node['cfe-nginx-php-fpm']['php_fastcgi_socket'],  
140 - 220 + # Optional attributes with their defaults:
  221 + #
141 # Default is same as Nginx user and group 222 # Default is same as Nginx user and group
142 #:user => node['nginx']['user'], 223 #:user => node['nginx']['user'],
143 #:group => node['nginx']['group'], 224 #:group => node['nginx']['group'],
1 # 1 #
2 -# Author:: Earth U (<sysadmin@chromedia.com>) 2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
3 # Cookbook Name:: cfe-nginx-php-fpm 3 # Cookbook Name:: cfe-nginx-php-fpm
4 # Definition:: php_ext 4 # Definition:: php_ext
5 # 5 #
@@ -4,7 +4,7 @@ maintainer_email 'sysadmin@chromedia.com' @@ -4,7 +4,7 @@ maintainer_email 'sysadmin@chromedia.com'
4 license 'Apache License' 4 license 'Apache License'
5 description 'Simplifies setup of Nginx+PHP-FPM in Chromedia.' 5 description 'Simplifies setup of Nginx+PHP-FPM in Chromedia.'
6 long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) 6 long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
7 -version '0.2.1' 7 +version '0.3.0'
8 8
9 { 9 {
10 'php-fpm' => '0.7.5', 10 'php-fpm' => '0.7.5',
1 # 1 #
2 -# Author:: Earth U (<sysadmin@chromedia.com>) 2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
3 # Cookbook Name:: cfe-nginx-php-fpm 3 # Cookbook Name:: cfe-nginx-php-fpm
4 # Recipe:: default 4 # Recipe:: default
5 # 5 #
1 # 1 #
2 -# Author:: Earth U (<sysadmin@chromedia.com>) 2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
3 # Cookbook Name:: cfe-nginx-php-fpm 3 # Cookbook Name:: cfe-nginx-php-fpm
4 # Recipe:: mariadb_client 4 # Recipe:: mariadb_client
5 # 5 #
1 # 1 #
2 -# Author:: Earth U (<sysadmin@chromedia.com>) 2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
3 # Cookbook Name:: cfe-nginx-php-fpm 3 # Cookbook Name:: cfe-nginx-php-fpm
4 # Recipe:: nginx 4 # Recipe:: nginx
5 # 5 #
@@ -30,216 +30,4 @@ node.default['cfe-nginx-php-fpm']['nginx']['priv_dir'] = @@ -30,216 +30,4 @@ node.default['cfe-nginx-php-fpm']['nginx']['priv_dir'] =
30 # Begin server configuration 30 # Begin server configuration
31 31
32 include_recipe 'nginx' 32 include_recipe 'nginx'
33 -  
34 -attribs = node['cfe-nginx-php-fpm']['nginx']  
35 -inc_dir = attribs['inc_dir']  
36 -priv_dir = attribs['priv_dir']  
37 -  
38 -[ inc_dir, priv_dir ].each do |ndir|  
39 - directory ndir do  
40 - recursive true  
41 - end  
42 -end  
43 -  
44 -# The restrictions.conf file containing default rules for virtual servers.  
45 -path_rest = "#{inc_dir}/restrictions.conf"  
46 -template path_rest do  
47 - action :create_if_missing  
48 - mode 0644  
49 - variables(  
50 - :log_robots => attribs['restriction_file']['log_robots'],  
51 - :log_hidden => attribs['restriction_file']['log_hidden'],  
52 - :log_static => attribs['restriction_file']['log_static'],  
53 - :static_types => attribs['restriction_file']['static_types']  
54 - )  
55 -end  
56 -  
57 -# Some basic "include" files for PHP  
58 -path_bpf = "#{inc_dir}/inc_basic_php_fastcgi"  
59 -template path_bpf do  
60 - action :create_if_missing  
61 - mode 0644  
62 - variables(  
63 - :socket => node['cfe-nginx-php-fpm']['php_fastcgi_socket']  
64 - )  
65 - only_if { node['cfe-nginx-php-fpm']['php_fastcgi_socket'] }  
66 -end  
67 -  
68 -catch_all_def_false = attribs['sites'].length > 1  
69 -  
70 -attribs['sites'].each do |site|  
71 -  
72 - if site.is_a?(Array)  
73 - site_sname = site[0]  
74 - site = site[1]  
75 - else  
76 - site_sname = site[:server_name]  
77 - end  
78 -  
79 - site_index = site[:index] || 'index.php'  
80 - site_aliases = site[:aliases] || []  
81 - site_doc_root = site[:doc_root] || ''  
82 - site_ssl = site[:ssl] || false  
83 - site_auth = site[:auth] || false  
84 - site_alo = site[:access_log_options] || false  
85 - site_cs = site[:custom_statements] || []  
86 - site_ins = site[:init_statements] || []  
87 -  
88 - site_types = ( site[:types] || [] ).uniq { |e| e[:type] }  
89 -  
90 - temp_catch_all = site.has_key?(:catch_all) ? site[:catch_all] : true  
91 - site_catch_all = catch_all_def_false ? false : temp_catch_all  
92 -  
93 - path_crt = "#{priv_dir}/#{site_sname}.crt"  
94 - path_key = "#{priv_dir}/#{site_sname}.key"  
95 - path_pass = "#{priv_dir}/#{site_sname}.htpasswd"  
96 - path_dhparam = "#{priv_dir}/#{site_sname}.dhparam"  
97 -  
98 - # If TLS/SSL is enabled, create necessary files  
99 - if site_ssl  
100 - if site_ssl[:cert].nil?  
101 - Chef::Log.error('Missing SSL certificate')  
102 - raise 'Missing SSL certificate'  
103 - end  
104 -  
105 - if site_ssl[:key].nil?  
106 - Chef::Log.error('Missing SSL key file')  
107 - raise 'Missing SSL key file'  
108 - end  
109 -  
110 - file path_crt do  
111 - mode 0644  
112 - content site_ssl[:cert]  
113 - sensitive true  
114 - action :create_if_missing  
115 - end  
116 -  
117 - file path_key do  
118 - mode 0644  
119 - content site_ssl[:key]  
120 - sensitive true  
121 - action :create_if_missing  
122 - end  
123 -  
124 - dh_modulus = site_ssl[:dh_modulus] || 2048  
125 - execute "openssl dhparam -out #{path_dhparam} #{dh_modulus}" do  
126 - not_if { ::File.exist?(path_dhparam) }  
127 - end  
128 - end  
129 -  
130 - # If basic auth is enabled, create htaccess file  
131 - if site_auth  
132 - site_auth[:users].each do |auser, apass|  
133 - execute "Generate #{path_pass}" do  
134 - command "printf \"#{auser}:"\  
135 - "$( openssl passwd -apr1 '#{apass}' )"\  
136 - "\\n\" >> #{path_pass}"  
137 - action :run  
138 - sensitive true  
139 - not_if { ::File.exist?(path_pass) }  
140 - end  
141 - end  
142 - end  
143 -  
144 - site_includes = []  
145 - upstreams = []  
146 -  
147 - # Create necessary include files for each type of this site  
148 - site_types.each do |stype|  
149 - stype_subp = stype[:subpath] ? stype[:subpath].gsub(/^\/+|\/$|\s/, '') : ''  
150 - stype_subp = stype_subp.length > 0 ? "#{stype_subp}/" : stype_subp  
151 -  
152 - case stype[:type]  
153 - # BASIC PHP SITE  
154 - when 'basic'  
155 - template "#{inc_dir}/inc_type_basic_#{site_sname}" do  
156 - source 'inc_type_basic.erb'  
157 - mode 0644  
158 - action :create_if_missing  
159 - variables(  
160 - :index => site_index,  
161 - :subpath => stype_subp,  
162 - :basic_php_fastcgi => path_bpf  
163 - )  
164 - end  
165 - site_includes.push("#{inc_dir}/inc_type_basic_#{site_sname}")  
166 -  
167 - # STANDARD WORDPRESS SITE  
168 - when 'wordpress'  
169 - template "#{inc_dir}/inc_type_wordpress_#{site_sname}" do  
170 - source 'inc_type_wordpress.erb'  
171 - mode 0644  
172 - action :create_if_missing  
173 - variables(  
174 - :index => site_index,  
175 - :subpath => stype_subp,  
176 - :basic_php_fastcgi => path_bpf,  
177 - :loginpage_statements => stype[:loginpage_statements] || [],  
178 - :fastcgi_intercept_errors => stype[:fastcgi_intercept_errors] || false  
179 - )  
180 - end  
181 - site_includes.push("#{inc_dir}/inc_type_wordpress_#{site_sname}")  
182 -  
183 - # BASIC PROXIED WEBSERVER  
184 - when 'webserver'  
185 - upstream_name = stype[:upstream_name] || 'webserver'  
186 - template "#{inc_dir}/inc_type_webserver_#{site_sname}" do  
187 - source 'inc_type_webserver.erb'  
188 - mode 0644  
189 - action :create_if_missing  
190 - variables(  
191 - :subpath => stype_subp,  
192 - :upstream_name => upstream_name  
193 - )  
194 - end  
195 - site_ins.push("map $http_upgrade $connection_upgrade {\n"\  
196 - " default upgrade;\n"\  
197 - " '' close;\n"\  
198 - "}")  
199 - upstreams.push( {  
200 - :name => upstream_name,  
201 - :ip => stype[:upstream_ip] || '127.0.0.1',  
202 - :port => stype[:upstream_port] || '8080'  
203 - } )  
204 - site_includes.push("#{inc_dir}/inc_type_webserver_#{site_sname}")  
205 -  
206 - else  
207 - Chef::Log.error("Unknown site type: #{stype[:type]}")  
208 - raise 'Unknown site type'  
209 - end  
210 - end  
211 -  
212 - # Create the main config file for this site  
213 - template "#{node['nginx']['dir']}/sites-available/#{site_sname}" do  
214 - source 'nginx_site.conf.erb'  
215 - action :create_if_missing  
216 - mode 0644  
217 - notifies :restart, 'service[nginx]'  
218 - variables(  
219 - :server_name => site_sname,  
220 - :aliases => site_aliases,  
221 - :doc_root => site_doc_root,  
222 - :index => site_index,  
223 - :ssl => site_ssl,  
224 - :auth => site_auth,  
225 -  
226 - :access_log_options => site_alo,  
227 - :catch_all => site_catch_all,  
228 -  
229 - :path_crt => path_crt,  
230 - :path_key => path_key,  
231 - :path_pass => path_pass,  
232 - :path_dhparam => path_dhparam,  
233 - :path_rest => path_rest,  
234 -  
235 - :upstreams => upstreams,  
236 - :includes => site_includes,  
237 - :init_statements => site_ins,  
238 - :custom_statements => site_cs  
239 - )  
240 - end  
241 -  
242 - nginx_site site_sname do  
243 - enable true  
244 - end  
245 -end 33 +include_recipe "#{cookbook_name}::nginx_configure"
  1 +#
  2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
  3 +# Cookbook Name:: cfe-nginx-php-fpm
  4 +# Recipe:: nginx_configure
  5 +#
  6 +# Copyright 2016, Chromedia Far East, Inc.
  7 +#
  8 +# Licensed under the Apache License, Version 2.0 (the "License");
  9 +# you may not use this file except in compliance with the License.
  10 +# You may obtain a copy of the License at
  11 +#
  12 +# http://www.apache.org/licenses/LICENSE-2.0
  13 +#
  14 +# Unless required by applicable law or agreed to in writing, software
  15 +# distributed under the License is distributed on an "AS IS" BASIS,
  16 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17 +# See the License for the specific language governing permissions and
  18 +# limitations under the License.
  19 +#
  20 +
  21 +# Create necessary directories
  22 +inc_dir = node['cfe-nginx-php-fpm']['nginx']['inc_dir']
  23 +priv_dir = node['cfe-nginx-php-fpm']['nginx']['priv_dir']
  24 +
  25 +[ inc_dir, priv_dir ].each do |ndir|
  26 + directory ndir do
  27 + recursive true
  28 + end
  29 +end
  30 +
  31 +# The restrictions file containing default rules for virtual servers.
  32 +path_rest = "#{inc_dir}/inc_restrictions"
  33 +restfa = node['cfe-nginx-php-fpm']['nginx']['restriction_file']
  34 +template path_rest do
  35 + action :create_if_missing
  36 + mode 0644
  37 + variables(
  38 + :log_robots => restfa['log_robots'],
  39 + :log_hidden => restfa['log_hidden'],
  40 + :log_static => restfa['log_static'],
  41 + :static_types => restfa['static_types']
  42 + )
  43 +end
  44 +
  45 +# Generate config files for each virtual server.
  46 +catch_all_def_false = node['cfe-nginx-php-fpm']['nginx']['sites'].length > 1
  47 +
  48 +node['cfe-nginx-php-fpm']['nginx']['sites'].each do |site|
  49 +
  50 + if site.is_a?(Array)
  51 + site_sname = site[0]
  52 + site = site[1]
  53 + else
  54 + site_sname = site[:server_name]
  55 + end
  56 +
  57 + # Assign default values to attributes
  58 + site_index = site[:index] || nil
  59 + site_aliases = site[:aliases] || []
  60 + site_doc_root = site[:doc_root] || nil
  61 + site_alo = site[:access_log_options] || nil
  62 + site_ssl = site[:ssl] || nil
  63 + site_auth = site[:auth] || nil
  64 + site_ins = site[:init_statements] || []
  65 + site_ss1 = site[:server_statements_1] || []
  66 + site_ss2 = site[:server_statements_2] || []
  67 +
  68 + temp_catch_all = site.has_key?(:catch_all) ? site[:catch_all] : true
  69 + site_catch_all = catch_all_def_false ? false : temp_catch_all
  70 + site_types = ( site[:types] || [] ).uniq { |e| e[:type] }
  71 + site_aheads = site[:add_headers] || {
  72 + 'X-Frame-Options' => 'SAMEORIGIN',
  73 + 'X-Content-Type-Options' => 'nosniff',
  74 + 'X-XSS-Protection' => '"1; mode=block"',
  75 + 'X-Permitted-Cross-Domain-Policies' => 'none'
  76 + }
  77 +
  78 + # If TLS/SSL is enabled, configure it:
  79 + if site_ssl
  80 + if site_ssl[:letsencrypt]
  81 + le_base_dir = site_ssl[:le_base_dir] || '/etc/letsencrypt/live'
  82 + le_sub_dir = site_ssl[:le_sub_dir] || site_sname
  83 + path_crt = "#{le_base_dir}/#{le_sub_dir}/fullchain.pem"
  84 + path_key = "#{le_base_dir}/#{le_sub_dir}/privkey.pem"
  85 +
  86 + else
  87 + path_crt = "#{priv_dir}/#{site_sname}.crt"
  88 + path_key = "#{priv_dir}/#{site_sname}.key"
  89 +
  90 + if site_ssl[:cert].nil?
  91 + Chef::Log.error('Missing SSL certificate')
  92 + raise 'Missing SSL certificate'
  93 + end
  94 +
  95 + if site_ssl[:key].nil?
  96 + Chef::Log.error('Missing SSL key file')
  97 + raise 'Missing SSL key file'
  98 + end
  99 +
  100 + file path_crt do
  101 + mode 0644
  102 + content site_ssl[:cert]
  103 + sensitive true
  104 + action :create_if_missing
  105 + end
  106 +
  107 + file path_key do
  108 + mode 0644
  109 + content site_ssl[:key]
  110 + sensitive true
  111 + action :create_if_missing
  112 + end
  113 + end
  114 +
  115 + # Configure a high modulus DH param
  116 + path_dhparam = "#{priv_dir}/#{site_sname}.dhparam"
  117 + dh_modulus = site_ssl[:dh_modulus] || 4096
  118 + execute "openssl dhparam -out #{path_dhparam} #{dh_modulus}" do
  119 + not_if { ::File.exist?(path_dhparam) }
  120 + end
  121 +
  122 + else
  123 + path_crt = ''
  124 + path_key = ''
  125 + path_dhparam = ''
  126 + end
  127 +
  128 + # If basic auth is enabled, create htpasswd file
  129 + if site_auth
  130 + path_pass = "#{priv_dir}/#{site_sname}.htpasswd"
  131 + site_auth[:users].each do |auser, apass|
  132 + execute "Generate #{path_pass}" do
  133 + command "printf \"#{auser}:"\
  134 + "$( openssl passwd -apr1 '#{apass}' )"\
  135 + "\\n\" >> #{path_pass}"
  136 + action :run
  137 + sensitive true
  138 + not_if { ::File.exist?(path_pass) }
  139 + end
  140 + end
  141 + else
  142 + path_pass = ''
  143 + end
  144 +
  145 + site_includes = [path_rest]
  146 + upstreams = []
  147 + # upstreams element:
  148 + # {
  149 + # :name => 'string',
  150 + # :servers => [
  151 + # '127.0.0.1:9000',
  152 + # '/var/run/php-fpm.sock'
  153 + # ]
  154 + # }
  155 +
  156 + # Create necessary include files for each type of this site
  157 + site_types.each do |stype|
  158 + stype_subp = stype[:subpath] ? stype[:subpath].gsub(/^\/+|\/+$|\s/, '') : ''
  159 + stype_subp = stype_subp.length > 0 ? "#{stype_subp}/" : stype_subp
  160 + stype_ads = stype[:add_statements] || []
  161 + stype_ups = stype[:upstream_name] ||
  162 + "#{stype[:type]}_#{site_sname.gsub('.', '_')}"
  163 +
  164 + upstreams.push( {
  165 + :name => stype_ups,
  166 + :servers => stype[:upstream_servers] || []
  167 + } )
  168 +
  169 + case stype[:type]
  170 + # BASIC PHP SITE
  171 + when 'basic'
  172 + stype_intererror = stype.has_key?(:fastcgi_intercept_errors) ?
  173 + stype[:fastcgi_intercept_errors] : false
  174 +
  175 + template "#{inc_dir}/inc_type_basic_#{site_sname}" do
  176 + source 'inc_type_basic.erb'
  177 + mode 0644
  178 + action :create_if_missing
  179 + variables(
  180 + :index => site_index,
  181 + :subpath => stype_subp,
  182 + :upstream_name => stype_ups,
  183 + :add_statements => stype_ads,
  184 + :fastcgi_intercept_errors => stype_intererror
  185 + )
  186 + end
  187 + site_includes.push("#{inc_dir}/inc_type_basic_#{site_sname}")
  188 +
  189 + # STANDARD WORDPRESS SITE
  190 + when 'wordpress'
  191 + stype_intererror = stype.has_key?(:fastcgi_intercept_errors) ?
  192 + stype[:fastcgi_intercept_errors] : false
  193 +
  194 + template "#{inc_dir}/inc_type_wordpress_#{site_sname}" do
  195 + source 'inc_type_wordpress.erb'
  196 + mode 0644
  197 + action :create_if_missing
  198 + variables(
  199 + :index => site_index,
  200 + :subpath => stype_subp,
  201 + :upstream_name => stype_ups,
  202 + :add_statements => stype_ads,
  203 + :loginpage_statements => stype[:loginpage_statements] || [],
  204 + :fastcgi_intercept_errors => stype_intererror
  205 + )
  206 + end
  207 + site_includes.push("#{inc_dir}/inc_type_wordpress_#{site_sname}")
  208 +
  209 + # REVERSE PROXY WEBSERVER
  210 + when 'webserver'
  211 + template "#{inc_dir}/inc_type_webserver_#{site_sname}" do
  212 + source 'inc_type_webserver.erb'
  213 + mode 0644
  214 + action :create_if_missing
  215 + variables(
  216 + :subpath => stype_subp,
  217 + :upstream_name => stype_ups,
  218 + :add_statements => stype_ads
  219 + )
  220 + end
  221 + site_ins.push("map $http_upgrade $connection_upgrade {\n"\
  222 + " default upgrade;\n"\
  223 + " '' close;\n"\
  224 + "}")
  225 + site_includes.push("#{inc_dir}/inc_type_webserver_#{site_sname}")
  226 +
  227 + else
  228 + Chef::Log.error("Unknown site type: #{stype[:type]}")
  229 + raise 'Unknown site type'
  230 + end
  231 + end
  232 +
  233 + # Create the main config file for this site
  234 + template "#{node['nginx']['dir']}/sites-available/#{site_sname}" do
  235 + source 'nginx_site.conf.erb'
  236 + action :create_if_missing
  237 + mode 0644
  238 + notifies :restart, 'service[nginx]', :delayed
  239 + variables(
  240 + :server_name => site_sname,
  241 + :aliases => site_aliases,
  242 + :doc_root => site_doc_root,
  243 + :index => site_index,
  244 + :ssl => site_ssl,
  245 + :auth => site_auth,
  246 +
  247 + :access_log_options => site_alo,
  248 + :catch_all => site_catch_all,
  249 +
  250 + :path_crt => path_crt,
  251 + :path_key => path_key,
  252 + :path_pass => path_pass,
  253 + :path_dhparam => path_dhparam,
  254 +
  255 + :upstreams => upstreams,
  256 + :includes => site_includes,
  257 + :init_statements => site_ins,
  258 + :add_headers => site_aheads,
  259 + :server_statements_1 => site_ss1,
  260 + :server_statements_2 => site_ss2,
  261 +
  262 + :log_dir => node['nginx']['log_dir']
  263 + )
  264 + end
  265 +
  266 + nginx_site site_sname do
  267 + enable true
  268 + end
  269 +end
1 # 1 #
2 -# Author:: Earth U (<sysadmin@chromedia.com>) 2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
3 # Cookbook Name:: cfe-nginx-php-fpm 3 # Cookbook Name:: cfe-nginx-php-fpm
4 # Recipe:: php-fpm 4 # Recipe:: php-fpm
5 # 5 #
@@ -53,8 +53,6 @@ if node['php-fpm']['pools'] @@ -53,8 +53,6 @@ if node['php-fpm']['pools']
53 pool2['php_options'] = def_php_opts unless pool['php_options'] 53 pool2['php_options'] = def_php_opts unless pool['php_options']
54 pool2['user'] = node['nginx']['user'] unless pool['user'] 54 pool2['user'] = node['nginx']['user'] unless pool['user']
55 pool2['group'] = node['nginx']['user'] unless pool['group'] 55 pool2['group'] = node['nginx']['user'] unless pool['group']
56 - pool2['listen'] =  
57 - node['cfe-nginx-php-fpm']['php_fastcgi_socket'] unless pool['listen']  
58 56
59 node.default['php-fpm']['pools'][key] = pool2 57 node.default['php-fpm']['pools'][key] = pool2
60 end 58 end
1 # 1 #
2 -# Author:: Earth U (<sysadmin@chromedia.com>) 2 +# Author:: Earth U (<sysadmin @ chromedia.com>)
3 # Cookbook Name:: cfe-nginx-php-fpm 3 # Cookbook Name:: cfe-nginx-php-fpm
4 # Recipe:: postfix 4 # Recipe:: postfix
5 # 5 #
1 -# Generated by Chef  
2 -#  
3 -  
4 -# No need to enable this if PHP and Nginx share the same filesystem  
5 -#fastcgi_index index.php;  
6 -  
7 -# You should have "cgi.fix_pathinfo = 0;" in php.ini  
8 -fastcgi_split_path_info ^(.+\.php)(/.+)$;  
9 -include fastcgi_params;  
10 -fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  
11 -  
12 -<% socket = @socket[0] == '/' ? "unix:#{@socket}" : @socket -%>  
13 -fastcgi_pass <%= socket %>;  
templates/default/inc_restrictions.erb renamed from templates/default/restrictions.conf.erb
@@ -2,18 +2,33 @@ @@ -2,18 +2,33 @@
2 # 2 #
3 # A basic PHP site config. 3 # A basic PHP site config.
4 4
5 -# Pass all .php files onto a php-fpm/php-fcgi server. 5 +<% @add_statements.each do |ads| -%>
  6 +<%= ads %>
  7 +
  8 +<% end -%>
  9 +# Pass all .php files onto a PHP-FPM fastcgi server.
6 #location ~ [^/]\.php(/|$) { 10 #location ~ [^/]\.php(/|$) {
7 # Customized location directive to account for URL subpathing: 11 # Customized location directive to account for URL subpathing:
8 location ~ ^/<%= @subpath %>.+\.php(/|$) { 12 location ~ ^/<%= @subpath %>.+\.php(/|$) {
9 try_files $uri =404; 13 try_files $uri =404;
10 14
11 - # Enable only if implementing custom error pages  
12 - #fastcgi_intercept_errors on; 15 + # No need to enable this if PHP and Nginx share the same filesystem
  16 + #fastcgi_index index.php;
  17 +
  18 +<% if @fastcgi_intercept_errors -%>
  19 + # Enable if implementing custom error pages
  20 + fastcgi_intercept_errors on;
  21 +
  22 +<% end -%>
  23 + # You should have "cgi.fix_pathinfo = 0;" in php.ini
  24 + fastcgi_split_path_info ^(.+\.php)(/.+)$;
  25 + include fastcgi_params;
  26 + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
13 27
14 - include <%= @basic_php_fastcgi %>; 28 + fastcgi_pass <%= @upstream_name %>;
15 } 29 }
16 30
17 location ~ ^/<%= @subpath %> { 31 location ~ ^/<%= @subpath %> {
18 - try_files $uri $uri/ /<%= @subpath %><%= @index %>?$args; 32 +<% str = @fastcgi_intercept_errors ? '=404' : "/#{@subpath}#{@index}?$args" -%>
  33 + try_files $uri $uri/ <%= str %>;
19 } 34 }
@@ -6,6 +6,10 @@ if ($http_user_agent ~ "MSIE") { @@ -6,6 +6,10 @@ if ($http_user_agent ~ "MSIE") {
6 return 303 https://browser-update.org/update.html; 6 return 303 https://browser-update.org/update.html;
7 } 7 }
8 8
  9 +<% @add_statements.each do |ads| -%>
  10 +<%= ads %>
  11 +
  12 +<% end -%>
9 location ~ ^/<%= @subpath %> { 13 location ~ ^/<%= @subpath %> {
10 proxy_pass http://<%= @upstream_name %>; 14 proxy_pass http://<%= @upstream_name %>;
11 proxy_http_version 1.1; 15 proxy_http_version 1.1;
@@ -6,6 +6,10 @@ @@ -6,6 +6,10 @@
6 # Add trailing slash to */wp-admin requests. 6 # Add trailing slash to */wp-admin requests.
7 rewrite /<%= @subpath %>wp-admin$ $scheme://$host$uri/ permanent; 7 rewrite /<%= @subpath %>wp-admin$ $scheme://$host$uri/ permanent;
8 8
  9 +<% @add_statements.each do |ads| -%>
  10 +<%= ads %>
  11 +
  12 +<% end -%>
9 # Deny access to any files with a .php extension in the uploads directory 13 # Deny access to any files with a .php extension in the uploads directory
10 # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) 14 # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
11 location ~* /<%= @subpath %>(.+/)*(?:uploads|files)/.*\.php$ { 15 location ~* /<%= @subpath %>(.+/)*(?:uploads|files)/.*\.php$ {
@@ -26,7 +30,12 @@ location ~ ^/<%= @subpath %>(wp-admin|wp-login\.php) { @@ -26,7 +30,12 @@ location ~ ^/<%= @subpath %>(wp-admin|wp-login\.php) {
26 fastcgi_intercept_errors on; 30 fastcgi_intercept_errors on;
27 31
28 <% end -%> 32 <% end -%>
29 - include <%= @basic_php_fastcgi %>; 33 + # You should have "cgi.fix_pathinfo = 0;" in php.ini
  34 + fastcgi_split_path_info ^(.+\.php)(/.+)$;
  35 + include fastcgi_params;
  36 + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  37 +
  38 + fastcgi_pass <%= @upstream_name %>;
30 } 39 }
31 } 40 }
32 41
@@ -40,9 +49,15 @@ location ~ ^/<%= @subpath %>.+\.php(/|$) { @@ -40,9 +49,15 @@ location ~ ^/<%= @subpath %>.+\.php(/|$) {
40 fastcgi_intercept_errors on; 49 fastcgi_intercept_errors on;
41 50
42 <% end -%> 51 <% end -%>
43 - include <%= @basic_php_fastcgi %>; 52 + # You should have "cgi.fix_pathinfo = 0;" in php.ini
  53 + fastcgi_split_path_info ^(.+\.php)(/.+)$;
  54 + include fastcgi_params;
  55 + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  56 +
  57 + fastcgi_pass <%= @upstream_name %>;
44 } 58 }
45 59
46 location ~ ^/<%= @subpath %> { 60 location ~ ^/<%= @subpath %> {
47 - try_files $uri $uri/ /<%= @subpath %><%= @index %>?$args; 61 +<% str = @fastcgi_intercept_errors ? '=404' : "/#{@subpath}#{@index}?$args" -%>
  62 + try_files $uri $uri/ <%= str %>;
48 } 63 }
1 # Generated by Chef 1 # Generated by Chef
2 # 2 #
3 -<%  
4 -@init_statements.each do |ins|  
5 --%>  
6 -<%= ins %>  
7 -  
8 -<%  
9 -end  
10 3
11 -@upstreams.each do |us|  
12 --%> 4 +<% ## -%>
  5 +<% ## Initial directives -%>
  6 +<% ## -%>
  7 +<% @init_statements.each do |ins| -%>
  8 +<%= ins %>
  9 +<% end -%>
  10 +<% ## -%>
  11 +<% ## List upstreams -%>
  12 +<% ## Example @upstreams element: -%>
  13 +<% ## { -%>
  14 +<% ## :name => 'string', -%>
  15 +<% ## :servers => [ -%>
  16 +<% ## '127.0.0.1:9000', -%>
  17 +<% ## '/var/run/php-fpm.sock' -%>
  18 +<% ## ] -%>
  19 +<% ## } -%>
  20 +<% ## -%>
  21 +<% @upstreams.each do |us| -%>
  22 +<% us_servers = us[:servers].inject([]) do |acc, serv| -%>
  23 +<% acc << ( serv[0] == '/' ? "unix:#{serv}" : serv ) -%>
  24 +<% acc -%>
  25 +<% end -%>
13 upstream <%= us[:name] %> { 26 upstream <%= us[:name] %> {
14 - server <%= us[:ip] %>:<%= us[:port] %>; 27 +<% us_servers.each do |serv| -%>
  28 + server <%= serv %>;
  29 +<% end -%>
15 } 30 }
16 31
17 -<%  
18 -end  
19 -  
20 -servers = [@server_name]  
21 -@aliases.each do |aname|  
22 - servers << aname  
23 -end  
24 -servers.uniq!  
25 -  
26 -if @catch_all  
27 --%> 32 +<% end -%>
  33 +<% ## -%>
  34 +<% ## Server block for default nameless server -%>
  35 +<% ## -%>
  36 +<% if @catch_all -%>
28 server { 37 server {
29 listen 80 default_server; 38 listen 80 default_server;
30 server_name _; 39 server_name _;
31 return 444; 40 return 444;
32 } 41 }
33 42
34 -<%  
35 -end  
36 -if @ssl  
37 - if @catch_all  
38 --%> 43 +<% end -%>
  44 +<% ## -%>
  45 +<% ## Main server block -%>
  46 +<% ## -%>
  47 +<% servers = @aliases.inject([@server_name]) do |acc, elem| -%>
  48 +<% acc << elem -%>
  49 +<% end -%>
  50 +<% servers.uniq! -%>
  51 +<% if @ssl -%>
  52 +<% if @catch_all -%>
39 server { 53 server {
40 listen 443 default_server; 54 listen 443 default_server;
41 server_name _; 55 server_name _;
42 return 444; 56 return 444;
43 } 57 }
44 58
45 -<%  
46 - end  
47 --%> 59 +<% end -%>
48 server { 60 server {
49 listen 80; 61 listen 80;
50 server_name <%= servers.join(' ') %>; 62 server_name <%= servers.join(' ') %>;
@@ -57,53 +69,66 @@ server { @@ -57,53 +69,66 @@ server {
57 ssl_certificate <%= @path_crt %>; 69 ssl_certificate <%= @path_crt %>;
58 ssl_certificate_key <%= @path_key %>; 70 ssl_certificate_key <%= @path_key %>;
59 <% unless @ssl[:self_signed] -%> 71 <% unless @ssl[:self_signed] -%>
  72 +<% if @ssl[:cipher_suite] == 'modern' -%>
60 73
61 # Modern cipher suite: 74 # Modern cipher suite:
62 - #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK; 75 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
  76 +<% else -%>
  77 +
63 # Medium compatibility cipher suite (compatible with IE7 WinXP): 78 # Medium compatibility cipher suite (compatible with IE7 WinXP):
64 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; 79 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
  80 +<% end -%>
65 ssl_prefer_server_ciphers on; 81 ssl_prefer_server_ciphers on;
66 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 82 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
67 ssl_session_cache shared:SSL:10m; 83 ssl_session_cache shared:SSL:10m;
68 ssl_dhparam <%= @path_dhparam %>; 84 ssl_dhparam <%= @path_dhparam %>;
69 <% end -%> 85 <% end -%>
70 -  
71 -<%  
72 - hsts = "max-age=#{@ssl[:hsts_max_age]};"  
73 - hsts << 'includeSubDomains;' if @ssl[:hsts_include_subdomains]  
74 --%> 86 +<% hage = @ssl[:hsts_max_age] || '15758000' -%>
  87 +<% hsub = @ssl.has_key?(:hsts_subdomains) ? @ssl[:hsts_subdomains] : true -%>
  88 +<% hsts = "max-age=#{hage};" -%>
  89 +<% hsts << 'includeSubDomains;' if hsub -%>
75 add_header Strict-Transport-Security "<%= hsts %>"; 90 add_header Strict-Transport-Security "<%= hsts %>";
76 -<%  
77 -else  
78 --%> 91 +<% else -%>
79 server { 92 server {
80 listen 80; 93 listen 80;
81 94
82 -<%  
83 -end  
84 --%>  
85 - add_header X-Frame-Options SAMEORIGIN;  
86 - add_header X-Content-Type-Options nosniff; 95 +<% end -%>
  96 +<% @add_headers.each do |header, value| -%>
  97 + add_header <%= header %> <%= value %>;
  98 +<% end -%>
  99 +
  100 + # Add CSP headers here:
  101 + # [https://www.owasp.org/index.php/Content_Security_Policy]
  102 + # [http://www.html5rocks.com/en/tutorials/security/content-security-policy/]
  103 + #
  104 + #add_header Content-Security-Policy "default-src 'self'";
  105 + #add_header X-Content-Security-Policy "default-src 'self'";
87 106
88 server_name <%= servers.join(' ') %>; 107 server_name <%= servers.join(' ') %>;
89 - 108 +<% if @doc_root -%>
90 root <%= @doc_root %>; 109 root <%= @doc_root %>;
  110 +<% end -%>
  111 +<% if @index -%>
91 index <%= @index %>; 112 index <%= @index %>;
  113 +<% end -%>
92 114
93 <% if @auth -%> 115 <% if @auth -%>
94 auth_basic "<%= @auth[:msg] %>"; 116 auth_basic "<%= @auth[:msg] %>";
95 auth_basic_user_file <%= @path_pass %>; 117 auth_basic_user_file <%= @path_pass %>;
96 118
97 <% end -%> 119 <% end -%>
98 - access_log <%= node['nginx']['log_dir'] %>/<%= @server_name %>.access.log<% if @access_log_options %> <%= @access_log_options %><% end %>;  
99 - error_log <%= node['nginx']['log_dir'] %>/<%= @server_name %>.error.log; 120 + access_log <%= @log_dir %>/<%= @server_name %>.access.log<% if @access_log_options %> <%= @access_log_options %><% end %>;
  121 + error_log <%= @log_dir %>/<%= @server_name %>.error.log;
  122 +
  123 +<% @server_statements_1.each do |s1| -%>
  124 + <%= sm %>
  125 +<% end -%>
100 126
101 - include <%= @path_rest %>;  
102 <% @includes.each do |inc| -%> 127 <% @includes.each do |inc| -%>
103 include <%= inc %>; 128 include <%= inc %>;
104 <% end -%> 129 <% end -%>
105 130
106 -<% @custom_statements.each do |sm| -%>  
107 - <%= sm %> 131 +<% @server_statements_2.each do |s2| -%>
  132 + <%= s2 %>
108 <% end -%> 133 <% end -%>
109 } 134 }