Skip to content
This repository has been archived by the owner on Dec 31, 2022. It is now read-only.

Commit

Permalink
feat(webserver): add support for force_ssl attribute
Browse files Browse the repository at this point in the history
Resolves #189
  • Loading branch information
ajgon committed Oct 2, 2018
1 parent e8164a1 commit 3bd46f5
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 6 deletions.
1 change: 1 addition & 0 deletions attributes/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
default['defaults']['webserver']['remove_default_sites'] = %w[
default default.conf 000-default 000-default.conf default-ssl default-ssl.conf
]
default['defaults']['webserver']['force_ssl'] = false

## apache2

Expand Down
7 changes: 7 additions & 0 deletions docs/source/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,13 @@ webserver
SSL requests are enabled. Note that SSL itself is controlled by the
``app['enable_ssl']`` setting in Opsworks.

- ``app['webserver']['force_ssl']``

- **Supported values:** ``true``, ``false``
- **Default** ``false``
- When this parameter is set to ``true`` all requests passed to http will
be redirected to https, with 301 status code.

- ``app['webserver']['site_config_template']``

- **Default** ``appserver.apache2.conf.erb`` or ``appserver.nginx.conf.erb``
Expand Down
2 changes: 1 addition & 1 deletion libraries/drivers_webserver_apache2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Apache2 < Drivers::Webserver::Base
packages debian: 'apache2', rhel: %w[httpd24 mod24_ssl]
output filter: %i[
dhparams keepalive_timeout limit_request_body log_dir log_level proxy_timeout
ssl_for_legacy_browsers extra_config extra_config_ssl port ssl_port
ssl_for_legacy_browsers extra_config extra_config_ssl port ssl_port force_ssl
]
notifies :deploy,
action: :reload, resource: { debian: 'service[apache2]', rhel: 'service[httpd]' }, timer: :delayed
Expand Down
2 changes: 1 addition & 1 deletion libraries/drivers_webserver_nginx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Nginx < Drivers::Webserver::Base
output filter: %i[
build_type client_body_timeout client_header_timeout client_max_body_size dhparams keepalive_timeout
log_dir log_level proxy_read_timeout proxy_send_timeout send_timeout ssl_for_legacy_browsers
extra_config extra_config_ssl enable_upgrade_method port ssl_port
extra_config extra_config_ssl enable_upgrade_method port ssl_port force_ssl
]
notifies :deploy, action: :reload, resource: 'service[nginx]', timer: :delayed
notifies :undeploy, action: :reload, resource: 'service[nginx]', timer: :delayed
Expand Down
30 changes: 30 additions & 0 deletions spec/unit/recipes/configure_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,21 @@
expect(chef_run).to create_link("/etc/nginx/sites-enabled/#{aws_opsworks_app['shortname']}.conf")
end

it 'creates proper redirects for force ssl' do
chef_run = ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy[aws_opsworks_app['shortname']]['webserver']['force_ssl'] = true
solo_node.set['deploy'] = deploy
solo_node.set['nginx'] = node['nginx']
end.converge(described_recipe)
expect(chef_run)
.to render_file("/etc/nginx/sites-available/#{aws_opsworks_app['shortname']}.conf")
.with_content('return 301 https://$host$request_uri;')
expect(chef_run)
.not_to render_file("/etc/nginx/sites-available/#{aws_opsworks_app['shortname']}.conf")
.with_content('# http support')
end

it 'enables ssl rules for legacy browsers in nginx config' do
chef_run = ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
Expand Down Expand Up @@ -625,6 +640,21 @@
expect(chef_run).to create_link("/etc/apache2/sites-enabled/#{aws_opsworks_app['shortname']}.conf")
end

it 'creates proper redirects for force ssl' do
chef_run = ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
deploy[aws_opsworks_app['shortname']]['webserver']['adapter'] = 'apache2'
deploy[aws_opsworks_app['shortname']]['webserver']['force_ssl'] = true
solo_node.set['deploy'] = deploy
end.converge(described_recipe)
expect(chef_run)
.to render_file("/etc/apache2/sites-available/#{aws_opsworks_app['shortname']}.conf")
.with_content('RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]')
expect(chef_run)
.not_to render_file("/etc/apache2/sites-available/#{aws_opsworks_app['shortname']}.conf")
.with_content('# http support')
end

it 'enables ssl rules for legacy browsers in apache2 config' do
chefrun = ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04') do |solo_node|
deploy = node['deploy']
Expand Down
14 changes: 13 additions & 1 deletion templates/default/appserver.apache2.passenger.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ Header always unset "X-Powered-By"
ServerName <%= node['hostname'] %>
ServerAlias <%= @application[:domains].join(" ") %>

<% if @application[:enable_ssl] && @out[:force_ssl] %>
<% if @out[:ssl_port].to_i == 443 %>
RewriteEngine On
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
<% else %>
RewriteEngine On
RewriteRule ^/?(.*) https://%{SERVER_NAME}:<%= @out[:ssl_port] %>/$1 [R=301,L]
<% end %>

<% else %>
# http support
DocumentRoot <%= File.join(@deploy_dir, 'current', 'public') %>

<Directory <%= File.join(@deploy_dir, 'current') %>>
Expand Down Expand Up @@ -52,13 +63,14 @@ Header always unset "X-Powered-By"
</Location>

RewriteEngine on
<% end %>

<%= @out[:extra_config] %>

</VirtualHost>

<% if @application[:enable_ssl] %>
<% unless @out[:ssl_port] == 443 %>
<% unless @out[:ssl_port].to_i == 443 %>
Listen <%= @out[:ssl_port] %>
<% end -%>

Expand Down
15 changes: 13 additions & 2 deletions templates/default/appserver.apache2.upstream.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ Listen <%= @out[:port] %>
ServerName <%= node['hostname'] %>
ServerAlias <%= @application[:domains].join(" ") %>

<% if @application[:enable_ssl] && @out[:force_ssl] %>
<% if @out[:ssl_port].to_i == 443 %>
RewriteEngine On
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
<% else %>
RewriteEngine On
RewriteRule ^/?(.*) https://%{SERVER_NAME}:<%= @out[:ssl_port] %>/$1 [R=301,L]
<% end %>

<% else %>
# http support
DocumentRoot <%= File.join(@deploy_dir, 'current', 'public') %>

<Directory <%= File.join(@deploy_dir, 'current') %>>
Expand Down Expand Up @@ -54,13 +65,13 @@ Listen <%= @out[:port] %>
Order deny,allow
Allow from all
</Proxy>
<% end %>

<%= @out[:extra_config] %>

</VirtualHost>

<% if @application[:enable_ssl] %>
<% unless @out[:ssl_port] == 443 %>
<% unless @out[:ssl_port].to_i == 443 %>
Listen <%= @out[:ssl_port] %>
<% end -%>

Expand Down
12 changes: 11 additions & 1 deletion templates/default/appserver.nginx.conf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ server {
keepalive_timeout <%= @out[:keepalive_timeout] || '15' %>;
send_timeout <%= @out[:send_timeout] || '10' %>;

<% if @application[:enable_ssl] && @out[:force_ssl] %>
# Force all http requests to https
<% if @out[:ssl_port].to_i == 443 %>
return 301 https://$host$request_uri;
<% else %>
return 301 https://$host:<%= @out[:ssl_port] %>$request_uri;
<% end %>
<% else %>
# http support
location / {
try_files $uri/index.html $uri/index.htm @<%= @name %>;
}
Expand Down Expand Up @@ -51,7 +60,8 @@ server {
proxy_pass http://<%= @name %>_<%= @application[:domains].first %>;
break;
}
}
}
<% end %>

location /nginx_status {
stub_status on;
Expand Down

0 comments on commit 3bd46f5

Please sign in to comment.