aboutsummaryrefslogtreecommitdiff
path: root/modules/profile/manifests/apache.pp
blob: 382633bb3f8c60d802356b43ce973d019066db91 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
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)?$',
    ]
  }

  exec { 'Start-apache':
    command => "/usr/bin/systemctl start httpd",
    before  => Class["::letsencrypt"],
    unless  => "/usr/bin/systemctl is-active httpd",
  }

  $letsencrypt_certonly_default = {
    plugin        => "webroot",
    webroot_paths => ["/srv/http/"],
    notify        => Class['Apache::Service'],
    require       => [Exec['Start-apache'],Apache::Vhost["redirect_no_ssl"],Apache::Custom_config["letsencrypt.conf"]],
    manage_cron   => true,
  }

  class { '::letsencrypt':
    install_method  => "package",
    package_name    => "certbot",
    package_command => "certbot",
    email           => lookup('letsencrypt::email'),
  }

  $real_hostname = lookup("base_installation::real_hostname", { "default_value" => undef })
  unless empty($real_hostname) {
    if (lookup("letsencrypt::try_for_real_hostname", { "default_value" => 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;
    }
  }

  lookup("letsencrypt::hosts", { "default_value" => [] }).each |$host| {
    if ($host != $real_hostname) { # Done above already
      letsencrypt::certonly { $host: ;
        default: * => $letsencrypt_certonly_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",
  }
}