From: Ismaël Bouya Date: Tue, 20 Feb 2018 10:32:40 +0000 (+0100) Subject: Merge branch 'letsencrypt' X-Git-Url: https://git.immae.eu/?a=commitdiff_plain;h=73bca64c33744027a0e800ce6c98a549ec924c6e;hp=428fcf14be3943fc01d234a5e622c7f8706bcb73;p=perso%2FImmae%2FProjets%2FPuppet.git Merge branch 'letsencrypt' --- diff --git a/.gitmodules b/.gitmodules index e893f13..35df238 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,12 +31,18 @@ [submodule "modules/postgresql"] path = modules/postgresql url = git://git.immae.eu/github/puppetlabs/puppetlabs-postgresql.git -[submodule "modules/nginx"] - path = modules/nginx - url = git://git.immae.eu/github/voxpupuli/puppet-nginx.git [submodule "modules/archive"] path = modules/archive url = git://git.immae.eu/github/voxpupuli/puppet-archive.git +[submodule "modules/apache"] + path = modules/apache + url = git://git.immae.eu/github/puppetlabs/puppetlabs-apache.git +[submodule "modules/letsencrypt"] + path = modules/letsencrypt + url = git://git.immae.eu/github/voxpupuli/puppet-letsencrypt.git [submodule "python/ovh"] path = python/ovh url = git://git.immae.eu/github/ovh/python-ovh +[submodule "modules/ssl"] + path = modules/ssl + url = git://git.immae.eu/github/fnerdwq/puppet-ssl diff --git a/environments/production/data/types/vps-ovhssd-1.yaml b/environments/production/data/types/vps-ovhssd-1.yaml index 968bf6b..9130ad1 100644 --- a/environments/production/data/types/vps-ovhssd-1.yaml +++ b/environments/production/data/types/vps-ovhssd-1.yaml @@ -3,5 +3,7 @@ classes: base_installation: stage: "setup" +base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.ovh.net" base_installation::grub_device: "/dev/sdb" base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt" +ssl::try_letsencrypt_for_real_hostname: false diff --git a/modules/apache b/modules/apache new file mode 160000 index 0000000..42c1b5c --- /dev/null +++ b/modules/apache @@ -0,0 +1 @@ +Subproject commit 42c1b5cae109630a53be89eda10c5c761c6d3689 diff --git a/modules/letsencrypt b/modules/letsencrypt new file mode 160000 index 0000000..55ac1e9 --- /dev/null +++ b/modules/letsencrypt @@ -0,0 +1 @@ +Subproject commit 55ac1e9c731b6dbfc380cd282c39f273223fcd53 diff --git a/modules/nginx b/modules/nginx deleted file mode 160000 index a7f40a8..0000000 --- a/modules/nginx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a7f40a8893e394cc57695ff81ea53254bcf1ff3a diff --git a/modules/profile/files/apache/document_root.conf b/modules/profile/files/apache/document_root.conf new file mode 100644 index 0000000..ed9a9ab --- /dev/null +++ b/modules/profile/files/apache/document_root.conf @@ -0,0 +1,6 @@ +DocumentRoot "/srv/http" + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + diff --git a/modules/profile/files/apache/googleb6d69446ff4ca3e5.html b/modules/profile/files/apache/googleb6d69446ff4ca3e5.html new file mode 100644 index 0000000..f732bac --- /dev/null +++ b/modules/profile/files/apache/googleb6d69446ff4ca3e5.html @@ -0,0 +1 @@ +google-site-verification: googleb6d69446ff4ca3e5.html diff --git a/modules/profile/files/apache/immae.conf b/modules/profile/files/apache/immae.conf new file mode 100644 index 0000000..5e0f3c4 --- /dev/null +++ b/modules/profile/files/apache/immae.conf @@ -0,0 +1,13 @@ +ErrorDocument 500 /maintenance_immae.html +ErrorDocument 501 /maintenance_immae.html +ErrorDocument 502 /maintenance_immae.html +ErrorDocument 503 /maintenance_immae.html +ErrorDocument 504 /maintenance_immae.html +Alias /maintenance_immae.html /srv/http/maintenance_immae.html + +RedirectMatch ^/licen[cs]es?_et_tip(ping)?$ https://www.immae.eu/licences_et_tip.html +RedirectMatch ^/licen[cs]es?_and_tip(ping)?$ https://www.immae.eu/licenses_and_tipping.html +RedirectMatch ^/licen[cs]es?$ https://www.immae.eu/licenses_and_tipping.html +RedirectMatch ^/tip(ping)?$ https://www.immae.eu/licenses_and_tipping.html + +AliasMatch "(.*)/googleb6d69446ff4ca3e5.html" /srv/http/googleb6d69446ff4ca3e5.html diff --git a/modules/profile/files/apache/index.html b/modules/profile/files/apache/index.html new file mode 100644 index 0000000..0274251 --- /dev/null +++ b/modules/profile/files/apache/index.html @@ -0,0 +1,9 @@ + + + + Hello World HTML + + +

It works!

+ + diff --git a/modules/profile/files/apache/letsencrypt.conf b/modules/profile/files/apache/letsencrypt.conf new file mode 100644 index 0000000..b2eaae2 --- /dev/null +++ b/modules/profile/files/apache/letsencrypt.conf @@ -0,0 +1,6 @@ +Alias /.well-known/acme-challenge /srv/http/.well-known/acme-challenge + + Require all granted + AllowOverride None + ErrorDocument 404 "Not Found" + diff --git a/modules/profile/files/apache/maintenance_immae.html b/modules/profile/files/apache/maintenance_immae.html new file mode 100644 index 0000000..90f265f --- /dev/null +++ b/modules/profile/files/apache/maintenance_immae.html @@ -0,0 +1,58 @@ + + + + Maintenance + + + + + +
+

Erreur serveur ou maintenance en cours !

+
+

Une mise à jour ou une opération de maintenance est en cours sur le site. Retentez dans quelques instants ou patientez, la page se rechargera automatiquement.

+
+
+ +
+

Server error or website in maintenance!

+
+

An update or a maintenance is on track on the website. Please try again in a few seconds or wait, the page will reload automatically.

+
+
+ + diff --git a/modules/profile/manifests/apache.pp b/modules/profile/manifests/apache.pp new file mode 100644 index 0000000..605b701 --- /dev/null +++ b/modules/profile/manifests/apache.pp @@ -0,0 +1,173 @@ +class profile::apache { + class { 'apache': + root_directory_secured => true, + root_directory_options => ["All"], + default_mods => false, + default_vhost => false, + log_formats => { + combined => '%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %p', + common => '%h %l %u %t \"%r\" %>s %b', + } + } + + ::apache::custom_config { 'log_config.conf': + content => 'CustomLog "/var/log/httpd/access_log" combined', + filename => 'log_config.conf' + } + + ::apache::custom_config { 'protocols.conf': + content => 'Protocols h2 http/1.1', + filename => 'protocols.conf' + } + + ::apache::custom_config { 'document_root.conf': + source => "puppet:///modules/profile/apache/document_root.conf", + filename => "document_root.conf" + } + + ::apache::custom_config { 'immae.conf': + source => "puppet:///modules/profile/apache/immae.conf", + filename => 'immae.conf' + } + + ::apache::custom_config { 'letsencrypt.conf': + source => "puppet:///modules/profile/apache/letsencrypt.conf", + filename => 'letsencrypt.conf' + } + + $apache_vhost_default = { + no_proxy_uris => [ + "/maintenance_immae.html", + "/googleb6d69446ff4ca3e5.html", + "/.well-known/acme-challenge" + ], + no_proxy_uris_match => [ + '^/licen[cs]es?_et_tip(ping)?$', + '^/licen[cs]es?_and_tip(ping)?$', + '^/licen[cs]es?$', + '^/tip(ping)?$', + ] + } + + $letsencrypt_certonly_default = { + plugin => "webroot", + webroot_paths => ["/srv/http/"], + notify => Class['Apache::Service'], + require => [Apache::Vhost["redirect_no_ssl"],Apache::Custom_config["letsencrypt.conf"]], + manage_cron => true, + } + + class { '::letsencrypt': + install_method => "package", + package_name => "certbot", + package_command => "certbot", + # FIXME + email => 'sites+letsencrypt@mail.immae.eu', + } + + $real_hostname = lookup("base_installation::real_hostname") |$key| { {} } + unless empty($real_hostname) { + if (lookup("ssl::try_letsencrypt_for_real_hostname") |$key| { true }) { + letsencrypt::certonly { $real_hostname: + before => Apache::Vhost["default_ssl"]; + default: * => $::profile::apache::letsencrypt_certonly_default; + } + $ssl_cert = "/etc/letsencrypt/live/$real_hostname/cert.pem" + $ssl_key = "/etc/letsencrypt/live/$real_hostname/privkey.pem" + $ssl_chain = "/etc/letsencrypt/live/$real_hostname/chain.pem" + } else { + ssl::self_signed_certificate { $real_hostname: + common_name => $real_hostname, + country => "FR", + days => "3650", + organization => "Immae", + directory => "/etc/httpd/conf/ssl", + before => Apache::Vhost["default_ssl"], + } + + $ssl_key = "/etc/httpd/conf/ssl/$real_hostname.key" + $ssl_cert = "/etc/httpd/conf/ssl/$real_hostname.crt" + $ssl_chain = undef + } + + apache::vhost { "default_ssl": + port => '443', + docroot => '/srv/http', + servername => $real_hostname, + directoryindex => 'index.htm index.html', + ssl => true, + ssl_key => $ssl_key, + ssl_cert => $ssl_cert, + ssl_chain => $ssl_chain, + priority => 0; + default: * => $::profile::apache::apache_vhost_default; + } + } + + apache::vhost { "redirect_no_ssl": + port => '80', + error_log => false, + log_level => undef, + access_log => false, + docroot => false, + servername => "", + serveraliases => "*", + priority => 99, + rewrites => [ + { + rewrite_cond => '"%{REQUEST_URI}" "!^/\.well-known"', + rewrite_rule => '^(.+) https://%{HTTP_HOST}$1 [R=301]' + } + ] + } + + class { 'apache::mod::ssl': + ssl_protocol => [ 'all', '-SSLv3' ], + # Given by + # https://mozilla.github.io/server-side-tls/ssl-config-generator/ + ssl_cipher => "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS", + # FIXME: need SSLSessionTickets off + ssl_stapling => true, + ssl_stapling_return_errors => false, + # FIXME: SSLStaplingResponderTimeout 5 + ssl_ca => '/etc/ssl/certs/ca-certificates.crt', + } + class { 'apache::mod::alias': } + class { 'apache::mod::autoindex': } + # Included by ssl + # class { 'apache::mod::mime': } + class { 'apache::mod::deflate': } + class { 'apache::mod::rewrite': } + + class { 'apache::mod::dir': + indexes => ["index.html"] + } + + file { [ + "/srv/http", + "/srv/http/.well-known"]: + ensure => "directory", + mode => "0755", + owner => "root", + group => "root", + } + + file { "/srv/http/index.html": + mode => "0644", + owner => "root", + group => "root", + source => "puppet:///modules/profile/apache/index.html", + } + file { "/srv/http/maintenance_immae.html": + mode => "0644", + owner => "root", + group => "root", + source => "puppet:///modules/profile/apache/maintenance_immae.html", + } + file { "/srv/http/googleb6d69446ff4ca3e5.html": + mode => "0644", + owner => "root", + group => "root", + source => "puppet:///modules/profile/apache/googleb6d69446ff4ca3e5.html", + } +} diff --git a/modules/profile/manifests/tools.pp b/modules/profile/manifests/tools.pp new file mode 100644 index 0000000..52e3cea --- /dev/null +++ b/modules/profile/manifests/tools.pp @@ -0,0 +1,3 @@ +class profile::tools { + ensure_packages(['vim', 'bash-completion']) +} diff --git a/modules/role/manifests/cryptoportfolio.pp b/modules/role/manifests/cryptoportfolio.pp index 0f26527..d2323a4 100644 --- a/modules/role/manifests/cryptoportfolio.pp +++ b/modules/role/manifests/cryptoportfolio.pp @@ -1,7 +1,9 @@ class role::cryptoportfolio { include "base_installation" + include "profile::tools" include "profile::postgresql" + include "profile::apache" $password_seed = lookup("base_installation::puppet_pass_seed") |$key| { {} } @@ -47,11 +49,24 @@ class role::cryptoportfolio { order => "b0", } - class { 'nginx': } + letsencrypt::certonly { $cf_front_app_host: ; + default: * => $::profile::apache::letsencrypt_certonly_default; + } - nginx::resource::server { $cf_front_app_host: - listen_port => 80, - proxy => 'http://localhost:8000', + class { 'apache::mod::headers': } + apache::vhost { $cf_front_app_host: + port => '443', + docroot => false, + manage_docroot => false, + proxy_dest => "http://localhost:8000", + request_headers => 'set X-Forwarded-Proto "https"', + ssl => true, + ssl_cert => "/etc/letsencrypt/live/$cf_front_app_host/cert.pem", + ssl_key => "/etc/letsencrypt/live/$cf_front_app_host/privkey.pem", + ssl_chain => "/etc/letsencrypt/live/$cf_front_app_host/chain.pem", + require => Letsencrypt::Certonly[$cf_front_app_host], + proxy_preserve_host => true; + default: * => $::profile::apache::apache_vhost_default; } user { $cf_user: diff --git a/modules/ssl b/modules/ssl new file mode 160000 index 0000000..c1cef11 --- /dev/null +++ b/modules/ssl @@ -0,0 +1 @@ +Subproject commit c1cef11d63da71c7599e905ff0598d21799ab8cc