Commit eee846a4dc6bc83e294e2fc5472231d1faa4f750
1 parent
70b9bd40
Bump to v0.3.0.
Add support for multiple upstream servers in nginx config. Add support for LetsEncrypt certificate configurations.
Showing
17 changed files
with
518 additions
and
337 deletions
@@ -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'], |
@@ -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:: 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" |
recipes/nginx_configure.rb
0 → 100644
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 |
templates/default/inc_basic_php_fastcgi.erb
deleted
100644 → 0
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 | } |