У меня есть веб-сайт с 20 различными сертификатами SSL, обслуживаемыми с помощью SNI. Текущий файл конфигурации довольно длинный и имеет много дубликатов, так как у меня их 20 <VirtualHost *:443>
блоки, в основном с одинаковыми значениями, для ServerAdmin
, DocumentRoot
, ErrorLog
, и т.д.
Единственные разные значения: ServerName, ServerAlias, SSLCertificateFile, SSLCertificateKeyFile
.
Есть ли решение DRY (Don't Repeat Yourself) для этого набора конфигурации?
Из apache 2.4 вы можете использовать mod_macro
Пример использования:
a2enmod macro
Создать файл /etc/apache2/conf-available/001-macro.conf
:
<IfModule !macro_module>
Error "mod_macro is required. To enable it run: a2enmod macro"
</IfModule>
<Macro VHostLog $domain $port>
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/error_$domain_$port.log
CustomLog ${APACHE_LOG_DIR}/access_$domain_$port.log vhost_combined
</Macro>
<Macro RedirectTo $protocol $domain>
<If "'${well_known_enabled}' == 'On' && %{REQUEST_URI} =~ m#^/\.well-known(/|$)#">
# Do nothing
</If>
<ElseIf "tolower(req('Host')) != '$domain' || tolower(%{REQUEST_SCHEME}) != '$protocol'">
Redirect permanent / $protocol://$domain/
</ElseIf>
</Macro>
<Macro EnableSSL>
<IfModule !ssl_module>
Error "mod_ssl is required. To enable it run: a2enmod ssl"
</IfModule>
SSLEngine On
SSLCertificateFile /opt/letsencrypt/${hostname}-fullchain.crt
SSLCertificateKeyFile /opt/letsencrypt/${hostname}.key
</Macro>
<Macro DirGrantAll $dir>
<Directory "$dir">
Require all granted
</Directory>
</Macro>
### VHostStandard
<Macro VHost $port $domain>
Use VHostCustom $port $domain ${doc_root}/$domain
Use DirGrantAll ${doc_root}/$domain
</Macro>
<Macro VHostHTTP $domain>
Use VHostCustomHTTP $domain ${doc_root}/$domain
Use DirGrantAll ${doc_root}/$domain
</Macro>
<Macro VHostHTTPS $domain>
Use VHostCustomHTTPS $domain ${doc_root}/$domain
Use DirGrantAll ${doc_root}/$domain
</Macro>
### VHostCustom
<Macro VHostCustom $port $domain $dir>
ServerName $domain
DocumentRoot "$dir"
Use VHostLog $domain $port
</Macro>
<Macro VHostCustomHTTP $domain $dir>
Use VHostCustom 80 $domain $dir
</Macro>
<Macro VHostCustomHTTPS $domain $dir>
Use VHostCustom 443 $domain $dir
Use EnableSSL
</Macro>
### VHostRedirect
<Macro VHostRedirect $port $server $redirect_protocol $redirect_domain>
Use VHostCustom $port $server ${safe_doc_root}
<Location />
Require all granted
</Location>
Use RedirectTo $redirect_protocol $redirect_domain
</Macro>
<Macro VHostRedirectHTTP $server $redirect_protocol $redirect_domain>
Use VHostRedirect 80 $server $redirect_protocol $redirect_domain
</Macro>
<Macro VHostRedirectHTTPS $server $redirect_protocol $redirect_domain>
Use VHostRedirect 443 $server $redirect_protocol $redirect_domain
</Macro>
### VHostAlias
<Macro VHostAlias $port $server $redirect_protocol $redirect_domain>
<VirtualHost *:$port>
Use VHostRedirect $port $server $redirect_protocol $redirect_domain
</VirtualHost>
</Macro>
<Macro VHostAliasHTTP $server $redirect_protocol $redirect_domain>
Use VHostAlias 80 $server $redirect_protocol $redirect_domain
</Macro>
<Macro VHostAliasHTTPS $server $redirect_protocol $redirect_domain>
Use VHostAlias 443 $server $redirect_protocol $redirect_domain
</Macro>
Включить конф
a2enconf 001-macro.conf
Например, в конфигурации вашего VHost напишите:
Use VHostHTTP www.example.com
Некоторые директивы требуются для работы некоторых макросов, указанных выше.
В /etc/apache2/apache2.conf
:
PassEnv hostname
PassEnv doc_root
PassEnv safe_doc_root
В /etc/apache2/envvars
:
export hostname=$(hostname -s)
export doc_root=/var/www/html
export safe_doc_root=/var/www/empty
Перезагрузите apache
systemctl restart apache2
Это всего лишь пример моих ранних экспериментов. Я также проверю, если, например, ansible
лучше бы подошло.
В макросах выше у меня всегда есть один сертификат на имя хоста. Конечно, вам нужно адаптировать это, чтобы использовать разные сертификаты на VHosts.