Commit 1794df1896eff59620e669ec5ddeba236a6ecc88

Authored by nollieheel
Committed by Earth Ugat
1 parent 0975ffb2

Bump to v0.4.2. Add new site type 'webserver_basic', add mitigations for HTTPOXY attacks.

  1 +## 0.4.2 - 2016-09-09
  2 +### Security
  3 +- Add proxy and fastcgi directives to prevent HTTPOXY attacks as described [here](https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ "Mitigate HTTPOXY with Nginx")
  4 +
  5 +### Added
  6 +- Add more appropriate keywords for virtual site types
  7 +- Add a new site type `webserver_basic` with a customizable template
  8 +
1 # 0.4.1 9 # 0.4.1
2 10
3 Add attribute to customize listen options for virtual host 11 Add attribute to customize listen options for virtual host
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 Installs PHP5-FPM, Nginx, Postfix, and MariaDB client on a server. Also sets up webserver configs for all virtual servers, including TLS and basic auth. 3 Installs PHP5-FPM, Nginx, Postfix, and MariaDB client on a server. Also sets up webserver configs for all virtual servers, including TLS and basic auth.
4 4
5 -Can also auto-generate config files for certain site types, such as Wordpress, etc. (right now it's: `wordpress`, `basic`, and `webserver`). 5 +Can also auto-generate config files for certain site types, such as Wordpress, etc. (right now it's: `wordpress`, `basic_php`, `webserver_basic`, and `webserver_ws`).
6 6
7 ## Supported Platforms 7 ## Supported Platforms
8 8
@@ -150,12 +150,14 @@ default['cfe-nginx-php-fpm']['nginx']['sites'] = [ @@ -150,12 +150,14 @@ default['cfe-nginx-php-fpm']['nginx']['sites'] = [
150 # Each type element of this array is a hash containing different attributes. 150 # Each type element of this array is a hash containing different attributes.
151 # 151 #
152 # Mandatory attributes are: 152 # Mandatory attributes are:
153 - # :type => One of: 'basic' (basic PHP site) 153 + # :type => One of: 'basic_php' (basic PHP site)
154 # 'wordpress' (standard Wordpress site) 154 # 'wordpress' (standard Wordpress site)
155 - # 'webserver' (proxy webserver) 155 + # 'webserver_ws' (proxy webserver with websocket)
  156 + # 'webserver_basic' (proxy generic webserver)
156 # :upstream_servers => An array containing upstream server endpoints. 157 # :upstream_servers => An array containing upstream server endpoints.
157 # Unix socket example: ['/var/run/php-fpm.sock'] 158 # Unix socket example: ['/var/run/php-fpm.sock']
158 # Tcp port example: ['127.0.0.1:9000'] 159 # Tcp port example: ['127.0.0.1:9000']
  160 + # (This is optional for type 'webserver_basic')
159 # 161 #
160 # Optional attributes are: 162 # Optional attributes are:
161 # :subpath => A string of the form: 'news/blog'. 163 # :subpath => A string of the form: 'news/blog'.
@@ -179,15 +181,28 @@ default['cfe-nginx-php-fpm']['nginx']['sites'] = [ @@ -179,15 +181,28 @@ default['cfe-nginx-php-fpm']['nginx']['sites'] = [
179 # or not. Default: false 181 # or not. Default: false
180 # 182 #
181 # Unique attributes for each type are indicated below: 183 # Unique attributes for each type are indicated below:
182 - # Basic PHP Site (:type => 'basic'): 184 + # Basic PHP Site (:type => 'basic_php'):
183 # :fastcgi_intercept_errors => Optional. Default: false 185 # :fastcgi_intercept_errors => Optional. Default: false
184 # Standard Wordpress Site (:type => 'wordpress'): 186 # Standard Wordpress Site (:type => 'wordpress'):
185 # :fastcgi_intercept_errors => Optional. Default: false 187 # :fastcgi_intercept_errors => Optional. Default: false
186 # :loginpage_statements => An array of strings to be put on the 188 # :loginpage_statements => An array of strings to be put on the
187 # config for the /wp-login.php 189 # config for the /wp-login.php
188 # and /wp-admin pages. Default: [] 190 # and /wp-admin pages. Default: []
189 - # Proxy Webserver (:type => 'webserver'): 191 + # Proxy Websocket Webserver (:type => 'webserver_ws'):
190 # (none) 192 # (none)
  193 + # Proxy Generic Webserver (:type => 'webserver_basic'):
  194 + # :source => The name of the config template.
  195 + # Default is 'inc_type_webserver_basic.erb'.
  196 + # :cookbook => The name of the cookbook where the template
  197 + # will be taken from. Default is this cookbook.
  198 + # In combination with the :source attribute above,
  199 + # any custom template in a wrapper cookbook can be
  200 + # used. A template file 'inc_type_webserver_basic.erb'
  201 + # exists as an example.
  202 + # :custom_params => A hash that will be passed into the template
  203 + # (along with the optional attributes mentioned
  204 + # above) as the variable called cparams.
  205 + # Default: {}
191 # 206 #
192 #:types => [] 207 #:types => []
193 #} 208 #}
@@ -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.4.1' 7 +version '0.4.2'
8 8
9 { 9 {
10 'openssl' => '4.4.0', 10 'openssl' => '4.4.0',
@@ -179,25 +179,27 @@ node[cb]['nginx']['sites'].each do |site| @@ -179,25 +179,27 @@ node[cb]['nginx']['sites'].each do |site|
179 :log_static => stype_logstatic 179 :log_static => stype_logstatic
180 } 180 }
181 181
182 - site_upstreams.push( {  
183 - :name => stype_ups,  
184 - :servers => stype[:upstream_servers] || []  
185 - } ) 182 + if stype[:upstream_servers] && stype[:upstream_servers].length > 0
  183 + site_upstreams.push( {
  184 + :name => stype_ups,
  185 + :servers => stype[:upstream_servers] || []
  186 + } )
  187 + end
186 188
187 case stype[:type] 189 case stype[:type]
188 # BASIC PHP SITE 190 # BASIC PHP SITE
189 - when 'basic' 191 + when 'basic', 'basic_php'
190 vars[:index] = site_index 192 vars[:index] = site_index
191 vars[:fastcgi_intercept_errors] = 193 vars[:fastcgi_intercept_errors] =
192 stype.has_key?(:fastcgi_intercept_errors) ? 194 stype.has_key?(:fastcgi_intercept_errors) ?
193 stype[:fastcgi_intercept_errors] : false 195 stype[:fastcgi_intercept_errors] : false
194 196
195 - template "#{inc_dir}/inc_type_basic_#{site_sname}" do 197 + template "#{inc_dir}/type_basic_php_#{site_sname}" do
196 source 'inc_type_basic.erb' 198 source 'inc_type_basic.erb'
197 mode 0644 199 mode 0644
198 variables vars 200 variables vars
199 end 201 end
200 - site_includes.push("#{inc_dir}/inc_type_basic_#{site_sname}") 202 + site_includes.push("#{inc_dir}/type_basic_php_#{site_sname}")
201 203
202 # STANDARD WORDPRESS SITE 204 # STANDARD WORDPRESS SITE
203 when 'wordpress' 205 when 'wordpress'
@@ -214,9 +216,9 @@ node[cb]['nginx']['sites'].each do |site| @@ -214,9 +216,9 @@ node[cb]['nginx']['sites'].each do |site|
214 end 216 end
215 site_includes.push("#{inc_dir}/inc_type_wordpress_#{site_sname}") 217 site_includes.push("#{inc_dir}/inc_type_wordpress_#{site_sname}")
216 218
217 - # REVERSE PROXY WEBSERVER  
218 - when 'webserver'  
219 - template "#{inc_dir}/inc_type_webserver_#{site_sname}" do 219 + # REVERSE PROXY WEBSERVER WITH WEBSOCKET
  220 + when 'webserver', 'webserver_ws'
  221 + template "#{inc_dir}/inc_type_webserver_ws_#{site_sname}" do
220 source 'inc_type_webserver.erb' 222 source 'inc_type_webserver.erb'
221 mode 0644 223 mode 0644
222 variables vars 224 variables vars
@@ -225,7 +227,19 @@ node[cb]['nginx']['sites'].each do |site| @@ -225,7 +227,19 @@ node[cb]['nginx']['sites'].each do |site|
225 " default upgrade;\n"\ 227 " default upgrade;\n"\
226 " '' close;\n"\ 228 " '' close;\n"\
227 "}") 229 "}")
228 - site_includes.push("#{inc_dir}/inc_type_webserver_#{site_sname}") 230 + site_includes.push("#{inc_dir}/inc_type_webserver_ws_#{site_sname}")
  231 +
  232 + # GENERIC REVERSE PROXY WEBSERVER
  233 + when 'webserver_basic'
  234 + vars[:cparams] = stype[:custom_params] || {}
  235 +
  236 + template "#{inc_dir}/inc_type_webserver_basic_#{site_sname}" do
  237 + source stype[:source] || 'inc_type_webserver_basic.erb'
  238 + cookbook stype[:cookbook] || cookbook_name
  239 + mode 0644
  240 + variables vars
  241 + end
  242 + site_includes.push("#{inc_dir}/inc_type_webserver_basic_#{site_sname}")
229 243
230 else 244 else
231 Chef::Log.error("Unknown site type: #{stype[:type]}") 245 Chef::Log.error("Unknown site type: #{stype[:type]}")
@@ -36,6 +36,9 @@ location ~ ^/<%= @subpath %>.+\.php(/|$) { @@ -36,6 +36,9 @@ location ~ ^/<%= @subpath %>.+\.php(/|$) {
36 include fastcgi_params; 36 include fastcgi_params;
37 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 37 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
38 38
  39 + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
  40 + fastcgi_param HTTP_PROXY "";
  41 +
39 fastcgi_pass <%= @upstream_name %>; 42 fastcgi_pass <%= @upstream_name %>;
40 } 43 }
41 44
@@ -22,8 +22,13 @@ location ~* ^/<%= @subpath %>.+\.(<%= @static_types.join('|') %>)$ { @@ -22,8 +22,13 @@ location ~* ^/<%= @subpath %>.+\.(<%= @static_types.join('|') %>)$ {
22 22
23 <% end -%> 23 <% end -%>
24 location ~ ^/<%= @subpath %> { 24 location ~ ^/<%= @subpath %> {
  25 + proxy_redirect off;
25 proxy_pass http://<%= @upstream_name %>; 26 proxy_pass http://<%= @upstream_name %>;
26 proxy_http_version 1.1; 27 proxy_http_version 1.1;
  28 +
  29 + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
  30 + proxy_set_header Proxy "";
  31 +
27 proxy_set_header Upgrade $http_upgrade; 32 proxy_set_header Upgrade $http_upgrade;
28 proxy_set_header Connection $connection_upgrade; 33 proxy_set_header Connection $connection_upgrade;
29 proxy_set_header X-Real-IP $remote_addr; 34 proxy_set_header X-Real-IP $remote_addr;
  1 +# Generated by Chef
  2 +<% -%>
  3 +<% # This is an example template. Use this as a guide for your wrapper.-%>
  4 +<% # It expects a :cparams hash with the following keys:-%>
  5 +<% # :proxy_host-%>
  6 +<% # :proxy_port-%>
  7 +
  8 +<% if @static_types -%>
  9 +# Send expires headers and (probably?) turn off 404 error logging.
  10 +location ~* ^/<%= @subpath %>.+\.(<%= @static_types.join('|') %>)$ {
  11 + expires max;
  12 +<% unless @log_static -%>
  13 + log_not_found off;
  14 + access_log off;
  15 +<% end -%>
  16 +}
  17 +
  18 +<% end -%>
  19 +location ~ ^/<%= @subpath %> {
  20 + proxy_redirect off;
  21 + proxy_pass http://<%= @cparams[:proxy_host] %>:<%= @cparams[:proxy_port] %>;
  22 + proxy_set_header Connection "";
  23 +
  24 + proxy_http_version 1.1;
  25 + proxy_pass_request_headers on;
  26 +
  27 + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
  28 + proxy_set_header Proxy "";
  29 +
  30 + proxy_set_header X-Real-IP $remote_addr;
  31 + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  32 + proxy_set_header Host $http_host;
  33 +}
@@ -46,6 +46,9 @@ location ~ ^/<%= @subpath %>(wp-admin|wp-login\.php) { @@ -46,6 +46,9 @@ location ~ ^/<%= @subpath %>(wp-admin|wp-login\.php) {
46 include fastcgi_params; 46 include fastcgi_params;
47 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 47 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
48 48
  49 + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
  50 + fastcgi_param HTTP_PROXY "";
  51 +
49 fastcgi_pass <%= @upstream_name %>; 52 fastcgi_pass <%= @upstream_name %>;
50 } 53 }
51 } 54 }
@@ -65,6 +68,9 @@ location ~ ^/<%= @subpath %>.+\.php(/|$) { @@ -65,6 +68,9 @@ location ~ ^/<%= @subpath %>.+\.php(/|$) {
65 include fastcgi_params; 68 include fastcgi_params;
66 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 69 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
67 70
  71 + # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
  72 + fastcgi_param HTTP_PROXY "";
  73 +
68 fastcgi_pass <%= @upstream_name %>; 74 fastcgi_pass <%= @upstream_name %>;
69 } 75 }
70 76