1
0
mirror of https://github.com/certbot/certbot.git synced 2025-08-08 04:02:10 +03:00

Distribution specific override functionality based on class inheritance (#5202)

Class inheritance based approach to distro specific overrides.

How it works:
The certbot-apache plugin entrypoint has been changed to entrypoint.ENTRYPOINT which is a variable containing appropriate override class for system, if available.

Override classes register themselves using decorator override.register() which takes a list of distribution fingerprints (ID & LIKE variables in /etc/os-release, or platform.linux_distribution() as a fallback). These end up as keys in dict override.OVERRIDE_CLASSES and values for the keys are references to the class that called the decorator, hence allowing self-registration of override classes when they are imported. The only file importing these override classes is entrypoint.py, so adding new override classes would need only one import in addition to the actual override class file.

Generic changes:

    Parser initialization has been moved to separate class method, allowing easy override where needed.
    Cleaned up configurator.py a bit, and moved some helper functions to newly created apache_util.py
    Split Debian specific code from configurator.py to debian_override.py
    Changed define_cmd to apache_cmd because the parameters are for every distribution supporting this behavior, and we're able to use the value to build the additional configuration dump commands.
    Moved add_parser_mod() from configurator to parser add_mod()
    Added two new configuration dump parsing methods to update_runtime_variables() in parser: update_includes() and update_modules().
    Changed init_modules() in parser to accommodate the changes above. (ie. don't throw existing self.modules out).
    Moved OS based constants to their respective override classes.
    Refactored configurator class discovery in tests to help easier test case creation using distribution based override configurator class.
    tests.util.get_apache_configurator() now takes keyword argument os_info which is string of the desired mock OS fingerprint response that's used for picking the right override class.

This PR includes two major generic additions that should vastly improve our parsing accuracy and quality:

    Includes are parsed from config dump from httpd binary. This is mandatory for some distributions (Like OpenSUSE) to get visibility over the whole configuration tree because of Include statements passed on in command line, and not via root httpd.conf file.
    Modules are parsed from config dump from httpd binary. This lets us jump into correct IfModule directives if for some reason we have missed the module availability (because of one being included on command line or such).

Distribution specific changes
Because of the generic changes, there are two distributions (or distribution families) that do not provide such functionality, so it had to be overridden in their respective override files. These distributions are:

    CentOS, because it deliberately limits httpd binary stdout using SELinux as a feature. We are doing opportunistic config dumps here however, in case SELinux enforcing is off.
    Gentoo, because it does not provide a way to invoke httpd with command line parsed from its specific configuration file. Gentoo relies heavily on Define statements that are passed over from APACHE2_OPTS variable /etc/conf.d/apache2 file and most of the configuration in root Apache configuration are dependent on these values.

Debian

    Moved the Debian specific parts from configurator.py to Debian specific override.

CentOS

    Parsing of /etc/sysconfig/httpd file for additional Define statements. This could hold other parameters too, but parsing everything off it would require a full Apache lexer. For CLI parameters, I think Defines are the most common ones. This is done in addition of opportunistic parsing of httpd binary config dump.
    Added CentOS default Apache configuration tree for realistic test cases.

Gentoo

    Parsing Defines from /etc/conf.d/apache2 variable APACHE2_OPTS, which holds additional Define statements to enable certain functionalities, enabling parts of the configuration in the Apache2 DOM. This is done instead of trying to parse httpd binary configuration dumps.
    Added default Apache configuration from Gentoo to testdata, including /etc/conf.d/apache2 file for realistic test cases.


* Distribution specific override functionality based on class inheritance

* Need to patch get_systemd_os_like to as travis has proper os-release

* Added pydoc

* Move parser initialization to a method and fix Python 3 __new__ errors

* Parser changes to parse HTTPD config

* Try to get modules and includes from httpd process for better visibility over the configuration

* Had to disable duplicate-code because of test setup (PyCQA/pylint/issues/214)

* CentOS tests and linter fixes

* Gentoo override, tests and linter fixes

* Mock the process call in all the tests that require it

* Fix CentOS test mock

* Restore reseting modules list functionality for cleanup

* Move OS fingerprinting and constant mocks to parent class

* Fixes requested in review

* New entrypoint structure and started moving OS constants to override classes

* OS constants move continued, test and linter fixes

* Removed dead code

* Apache compatibility test changest to reflect OS constant restructure

* Test fix

* Requested changes

* Moved Debian specific tests to own test file

* Removed decorator based override class registration in favor of entrypoint dict

* Fix for update_includes for some versions of Augeas

* Take fedora fix into account in tests

* Review fixes
This commit is contained in:
Joona Hoikkala
2017-12-04 21:49:18 +02:00
committed by Brad Warren
parent 73ba9af442
commit dc78fd731e
68 changed files with 4383 additions and 748 deletions

View File

@@ -41,7 +41,7 @@ load-plugins=linter_plugin
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=fixme,locally-disabled,abstract-class-not-used,abstract-class-little-used,bad-continuation,too-few-public-methods,no-self-use,invalid-name,too-many-instance-attributes,cyclic-import
disable=fixme,locally-disabled,abstract-class-not-used,abstract-class-little-used,bad-continuation,too-few-public-methods,no-self-use,invalid-name,too-many-instance-attributes,cyclic-import,duplicate-code
# abstract-class-not-used cannot be disabled locally (at least in
# pylint 1.4.1), same for abstract-class-little-used

View File

@@ -0,0 +1,96 @@
""" Utility functions for certbot-apache plugin """
import os
from certbot import util
def get_mod_deps(mod_name):
"""Get known module dependencies.
.. note:: This does not need to be accurate in order for the client to
run. This simply keeps things clean if the user decides to revert
changes.
.. warning:: If all deps are not included, it may cause incorrect parsing
behavior, due to enable_mod's shortcut for updating the parser's
currently defined modules (`.ApacheParser.add_mod`)
This would only present a major problem in extremely atypical
configs that use ifmod for the missing deps.
"""
deps = {
"ssl": ["setenvif", "mime"]
}
return deps.get(mod_name, [])
def get_file_path(vhost_path):
"""Get file path from augeas_vhost_path.
Takes in Augeas path and returns the file name
:param str vhost_path: Augeas virtual host path
:returns: filename of vhost
:rtype: str
"""
if not vhost_path or not vhost_path.startswith("/files/"):
return None
return _split_aug_path(vhost_path)[0]
def get_internal_aug_path(vhost_path):
"""Get the Augeas path for a vhost with the file path removed.
:param str vhost_path: Augeas virtual host path
:returns: Augeas path to vhost relative to the containing file
:rtype: str
"""
return _split_aug_path(vhost_path)[1]
def _split_aug_path(vhost_path):
"""Splits an Augeas path into a file path and an internal path.
After removing "/files", this function splits vhost_path into the
file path and the remaining Augeas path.
:param str vhost_path: Augeas virtual host path
:returns: file path and internal Augeas path
:rtype: `tuple` of `str`
"""
# Strip off /files
file_path = vhost_path[6:]
internal_path = []
# Remove components from the end of file_path until it becomes valid
while not os.path.exists(file_path):
file_path, _, internal_path_part = file_path.rpartition("/")
internal_path.append(internal_path_part)
return file_path, "/".join(reversed(internal_path))
def parse_define_file(filepath, varname):
""" Parses Defines from a variable in configuration file
:param str filepath: Path of file to parse
:param str varname: Name of the variable
:returns: Dict of Define:Value pairs
:rtype: `dict`
"""
return_vars = {}
# Get list of words in the variable
a_opts = util.get_var_from_file(varname, filepath).split()
for i, v in enumerate(a_opts):
# Handle Define statements and make sure it has an argument
if v == "-D" and len(a_opts) >= i+2:
var_parts = a_opts[i+1].partition("=")
return_vars[var_parts[0]] = var_parts[2]
return return_vars

View File

@@ -3,6 +3,7 @@
import fnmatch
import logging
import os
import pkg_resources
import re
import socket
import time
@@ -19,6 +20,7 @@ from certbot import util
from certbot.plugins import common
from certbot.plugins.util import path_surgery
from certbot_apache import apache_util
from certbot_apache import augeas_configurator
from certbot_apache import constants
from certbot_apache import display_ops
@@ -85,27 +87,50 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
description = "Apache Web Server plugin - Beta"
OS_DEFAULTS = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/sites-available",
vhost_files="*",
logs_root="/var/log/apache2",
version_cmd=['apache2ctl', '-v'],
apache_cmd="apache2ctl",
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
def constant(self, key):
"""Get constant for OS_DEFAULTS"""
return self.OS_DEFAULTS.get(key)
@classmethod
def add_parser_arguments(cls, add):
add("enmod", default=constants.os_constant("enmod"),
add("enmod", default=cls.OS_DEFAULTS["enmod"],
help="Path to the Apache 'a2enmod' binary.")
add("dismod", default=constants.os_constant("dismod"),
add("dismod", default=cls.OS_DEFAULTS["dismod"],
help="Path to the Apache 'a2dismod' binary.")
add("le-vhost-ext", default=constants.os_constant("le_vhost_ext"),
add("le-vhost-ext", default=cls.OS_DEFAULTS["le_vhost_ext"],
help="SSL vhost configuration extension.")
add("server-root", default=constants.os_constant("server_root"),
add("server-root", default=cls.OS_DEFAULTS["server_root"],
help="Apache server root directory.")
add("vhost-root", default=None,
help="Apache server VirtualHost configuration root")
add("logs-root", default=constants.os_constant("logs_root"),
add("logs-root", default=cls.OS_DEFAULTS["logs_root"],
help="Apache server logs directory")
add("challenge-location",
default=constants.os_constant("challenge_location"),
default=cls.OS_DEFAULTS["challenge_location"],
help="Directory path for challenge configuration.")
add("handle-modules", default=constants.os_constant("handle_mods"),
add("handle-modules", default=cls.OS_DEFAULTS["handle_mods"],
help="Let installer handle enabling required modules for you." +
"(Only Ubuntu/Debian currently)")
add("handle-sites", default=constants.os_constant("handle_sites"),
add("handle-sites", default=cls.OS_DEFAULTS["handle_sites"],
help="Let installer handle enabling sites for you." +
"(Only Ubuntu/Debian currently)")
util.add_deprecated_argument(add, argument_name="ctl", nargs=1)
@@ -166,7 +191,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
raise errors.NoInstallationError("Problem in Augeas installation")
# Verify Apache is installed
restart_cmd = constants.os_constant("restart_cmd")[0]
restart_cmd = self.constant("restart_cmd")[0]
if not util.exe_exists(restart_cmd):
if not path_surgery(restart_cmd):
raise errors.NoInstallationError(
@@ -192,20 +217,20 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
# Parse vhost-root if defined on cli
if not self.conf("vhost-root"):
self.vhostroot = constants.os_constant("vhost_root")
self.vhostroot = self.constant("vhost_root")
else:
self.vhostroot = os.path.abspath(self.conf("vhost-root"))
self.parser = parser.ApacheParser(
self.aug, self.conf("server-root"), self.conf("vhost-root"),
self.version, configurator=self)
self.parser = self.get_parser()
# Check for errors in parsing files with Augeas
self.check_parsing_errors("httpd.aug")
# Get all of the available vhosts
self.vhosts = self.get_virtual_hosts()
install_ssl_options_conf(self.mod_ssl_conf, self.updated_mod_ssl_conf_digest)
self.install_ssl_options_conf(self.mod_ssl_conf,
self.updated_mod_ssl_conf_digest)
# Prevent two Apache plugins from modifying a config at once
try:
@@ -230,6 +255,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
self.aug.remove("/test/path")
return matches
def get_parser(self):
"""Initializes the ApacheParser"""
return parser.ApacheParser(
self.aug, self.conf("server-root"), self.conf("vhost-root"),
self.version, configurator=self)
def deploy_cert(self, domain, cert_path, key_path,
chain_path=None, fullchain_path=None):
"""Deploys certificate to specified virtual host.
@@ -585,7 +616,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
if addr.get_port() == "443":
is_ssl = True
filename = get_file_path(self.aug.get("/augeas/files%s/path" % get_file_path(path)))
filename = apache_util.get_file_path(
self.aug.get("/augeas/files%s/path" % apache_util.get_file_path(path)))
if filename is None:
return None
@@ -624,7 +656,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
new_vhost = self._create_vhost(path)
if not new_vhost:
continue
internal_path = get_internal_aug_path(new_vhost.path)
internal_path = apache_util.get_internal_aug_path(new_vhost.path)
realpath = os.path.realpath(new_vhost.filep)
if realpath not in file_paths:
file_paths[realpath] = new_vhost.filep
@@ -640,7 +672,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
for v in vhs:
if v.filep == file_paths[realpath]:
internal_paths[realpath].remove(
get_internal_aug_path(v.path))
apache_util.get_internal_aug_path(v.path))
else:
new_vhs.append(v)
vhs = new_vhs
@@ -828,7 +860,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
Duplicates vhost and adds default ssl options
New vhost will reside as (nonssl_vhost.path) +
``certbot_apache.constants.os_constant("le_vhost_ext")``
``self.constant("le_vhost_ext")``
.. note:: This function saves the configuration
@@ -1702,17 +1734,13 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
return redirects
def enable_site(self, vhost):
"""Enables an available site, Apache reload required.
.. note:: Does not make sure that the site correctly works or that all
modules are enabled appropriately.
.. todo:: This function should number subdomains before the domain
vhost
.. todo:: Make sure link is not broken...
.. note:: The distribution specific override replaces functionality
of this method where available.
:param vhost: vhost to enable
:type vhost: :class:`~certbot_apache.obj.VirtualHost`
@@ -1724,39 +1752,16 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
if vhost.enabled:
return
# Handle non-debian systems
if not self.conf("handle-sites"):
if not self.parser.parsed_in_original(vhost.filep):
# Add direct include to root conf
self.parser.add_include(self.parser.loc["default"], vhost.filep)
vhost.enabled = True
return
if not self.parser.parsed_in_original(vhost.filep):
# Add direct include to root conf
logger.info("Enabling site %s by adding Include to root configuration",
vhost.filep)
self.save_notes += "Enabled site %s\n" % vhost.filep
self.parser.add_include(self.parser.loc["default"], vhost.filep)
vhost.enabled = True
return
enabled_path = ("%s/sites-enabled/%s" %
(self.parser.root, os.path.basename(vhost.filep)))
self.reverter.register_file_creation(False, enabled_path)
try:
os.symlink(vhost.filep, enabled_path)
except OSError as err:
if os.path.islink(enabled_path) and os.path.realpath(
enabled_path) == vhost.filep:
# Already in shape
vhost.enabled = True
return
else:
logger.warning(
"Could not symlink %s to %s, got error: %s", enabled_path,
vhost.filep, err.strerror)
errstring = ("Encountered error while trying to enable a " +
"newly created VirtualHost located at {0} by " +
"linking to it from {1}")
raise errors.NotSupportedError(errstring.format(vhost.filep,
enabled_path))
vhost.enabled = True
logger.info("Enabling available site: %s", vhost.filep)
self.save_notes += "Enabled site %s\n" % vhost.filep
def enable_mod(self, mod_name, temp=False):
def enable_mod(self, mod_name, temp=False): # pylint: disable=unused-argument
"""Enables module in Apache.
Both enables and reloads Apache so module is active.
@@ -1764,64 +1769,18 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
:param str mod_name: Name of the module to enable. (e.g. 'ssl')
:param bool temp: Whether or not this is a temporary action.
:raises .errors.NotSupportedError: If the filesystem layout is not
supported.
:raises .errors.MisconfigurationError: If a2enmod or a2dismod cannot be
run.
.. note:: The distribution specific override replaces functionality
of this method where available.
:raises .errors.MisconfigurationError: We cannot enable modules in
generic fashion.
"""
# Support Debian specific setup
avail_path = os.path.join(self.parser.root, "mods-available")
enabled_path = os.path.join(self.parser.root, "mods-enabled")
if not os.path.isdir(avail_path) or not os.path.isdir(enabled_path):
raise errors.NotSupportedError(
"Unsupported directory layout. You may try to enable mod %s "
"and try again." % mod_name)
deps = _get_mod_deps(mod_name)
# Enable all dependencies
for dep in deps:
if (dep + "_module") not in self.parser.modules:
self._enable_mod_debian(dep, temp)
self._add_parser_mod(dep)
note = "Enabled dependency of %s module - %s" % (mod_name, dep)
if not temp:
self.save_notes += note + os.linesep
logger.debug(note)
# Enable actual module
self._enable_mod_debian(mod_name, temp)
self._add_parser_mod(mod_name)
if not temp:
self.save_notes += "Enabled %s module in Apache\n" % mod_name
logger.info("Enabled Apache %s module", mod_name)
# Modules can enable additional config files. Variables may be defined
# within these new configuration sections.
# Reload is not necessary as DUMP_RUN_CFG uses latest config.
self.parser.update_runtime_variables()
def _add_parser_mod(self, mod_name):
"""Shortcut for updating parser modules."""
self.parser.modules.add(mod_name + "_module")
self.parser.modules.add("mod_" + mod_name + ".c")
def _enable_mod_debian(self, mod_name, temp):
"""Assumes mods-available, mods-enabled layout."""
# Generate reversal command.
# Try to be safe here... check that we can probably reverse before
# applying enmod command
if not util.exe_exists(self.conf("dismod")):
raise errors.MisconfigurationError(
"Unable to find a2dismod, please make sure a2enmod and "
"a2dismod are configured correctly for certbot.")
self.reverter.register_undo_command(
temp, [self.conf("dismod"), mod_name])
util.run_script([self.conf("enmod"), mod_name])
mod_message = ("Apache needs to have module \"{0}\" active for the " +
"requested installation options. Unfortunately Certbot is unable " +
"to install or enable it for you. Please install the module, and " +
"run Certbot again.")
raise errors.MisconfigurationError(mod_message.format(mod_name))
def restart(self):
"""Runs a config test and reloads the Apache server.
@@ -1840,7 +1799,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""
try:
util.run_script(constants.os_constant("restart_cmd"))
util.run_script(self.constant("restart_cmd"))
except errors.SubprocessError as err:
raise errors.MisconfigurationError(str(err))
@@ -1851,7 +1810,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""
try:
util.run_script(constants.os_constant("conftest_cmd"))
util.run_script(self.constant("conftest_cmd"))
except errors.SubprocessError as err:
raise errors.MisconfigurationError(str(err))
@@ -1867,11 +1826,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""
try:
stdout, _ = util.run_script(constants.os_constant("version_cmd"))
stdout, _ = util.run_script(self.constant("version_cmd"))
except errors.SubprocessError:
raise errors.PluginError(
"Unable to run %s -v" %
constants.os_constant("version_cmd"))
self.constant("version_cmd"))
regex = re.compile(r"Apache/([0-9\.]*)", re.IGNORECASE)
matches = regex.findall(stdout)
@@ -1943,86 +1902,15 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
if not self._chall_out:
self.revert_challenge_config()
self.restart()
self.parser.init_modules()
self.parser.reset_modules()
def install_ssl_options_conf(self, options_ssl, options_ssl_digest):
"""Copy Certbot's SSL options file into the system's config dir if required."""
# XXX if we ever try to enforce a local privilege boundary (eg, running
# certbot for unprivileged users via setuid), this function will need
# to be modified.
return common.install_version_controlled_file(options_ssl, options_ssl_digest,
self.constant("MOD_SSL_CONF_SRC"), constants.ALL_SSL_OPTIONS_HASHES)
def _get_mod_deps(mod_name):
"""Get known module dependencies.
.. note:: This does not need to be accurate in order for the client to
run. This simply keeps things clean if the user decides to revert
changes.
.. warning:: If all deps are not included, it may cause incorrect parsing
behavior, due to enable_mod's shortcut for updating the parser's
currently defined modules (`.ApacheConfigurator._add_parser_mod`)
This would only present a major problem in extremely atypical
configs that use ifmod for the missing deps.
"""
deps = {
"ssl": ["setenvif", "mime"]
}
return deps.get(mod_name, [])
def get_file_path(vhost_path):
"""Get file path from augeas_vhost_path.
Takes in Augeas path and returns the file name
:param str vhost_path: Augeas virtual host path
:returns: filename of vhost
:rtype: str
"""
if not vhost_path or not vhost_path.startswith("/files/"):
return None
return _split_aug_path(vhost_path)[0]
def get_internal_aug_path(vhost_path):
"""Get the Augeas path for a vhost with the file path removed.
:param str vhost_path: Augeas virtual host path
:returns: Augeas path to vhost relative to the containing file
:rtype: str
"""
return _split_aug_path(vhost_path)[1]
def _split_aug_path(vhost_path):
"""Splits an Augeas path into a file path and an internal path.
After removing "/files", this function splits vhost_path into the
file path and the remaining Augeas path.
:param str vhost_path: Augeas virtual host path
:returns: file path and internal Augeas path
:rtype: `tuple` of `str`
"""
# Strip off /files
file_path = vhost_path[6:]
internal_path = []
# Remove components from the end of file_path until it becomes valid
while not os.path.exists(file_path):
file_path, _, internal_path_part = file_path.rpartition("/")
internal_path.append(internal_path_part)
return file_path, "/".join(reversed(internal_path))
def install_ssl_options_conf(options_ssl, options_ssl_digest):
"""Copy Certbot's SSL options file into the system's config dir if required."""
# XXX if we ever try to enforce a local privilege boundary (eg, running
# certbot for unprivileged users via setuid), this function will need
# to be modified.
return common.install_version_controlled_file(options_ssl, options_ssl_digest,
constants.os_constant("MOD_SSL_CONF_SRC"), constants.ALL_SSL_OPTIONS_HASHES)

View File

@@ -1,151 +1,6 @@
"""Apache plugin constants."""
import pkg_resources
from certbot import util
CLI_DEFAULTS_DEFAULT = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/sites-available",
vhost_files="*",
logs_root="/var/log/apache2",
version_cmd=['apache2ctl', '-v'],
define_cmd=['apache2ctl', '-t', '-D', 'DUMP_RUN_CFG'],
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
CLI_DEFAULTS_DEBIAN = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/sites-available",
vhost_files="*",
logs_root="/var/log/apache2",
version_cmd=['apache2ctl', '-v'],
define_cmd=['apache2ctl', '-t', '-D', 'DUMP_RUN_CFG'],
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod="a2enmod",
dismod="a2dismod",
le_vhost_ext="-le-ssl.conf",
handle_mods=True,
handle_sites=True,
challenge_location="/etc/apache2",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
CLI_DEFAULTS_CENTOS = dict(
server_root="/etc/httpd",
vhost_root="/etc/httpd/conf.d",
vhost_files="*.conf",
logs_root="/var/log/httpd",
version_cmd=['apachectl', '-v'],
define_cmd=['apachectl', '-t', '-D', 'DUMP_RUN_CFG'],
restart_cmd=['apachectl', 'graceful'],
conftest_cmd=['apachectl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/httpd/conf.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "centos-options-ssl-apache.conf")
)
CLI_DEFAULTS_GENTOO = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/vhosts.d",
vhost_files="*.conf",
logs_root="/var/log/apache2",
version_cmd=['/usr/sbin/apache2', '-v'],
define_cmd=['apache2ctl', 'virtualhosts'],
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2/vhosts.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
CLI_DEFAULTS_DARWIN = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/other",
vhost_files="*.conf",
logs_root="/var/log/apache2",
version_cmd=['/usr/sbin/httpd', '-v'],
define_cmd=['/usr/sbin/httpd', '-t', '-D', 'DUMP_RUN_CFG'],
restart_cmd=['apachectl', 'graceful'],
conftest_cmd=['apachectl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2/other",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
CLI_DEFAULTS_SUSE = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/vhosts.d",
vhost_files="*.conf",
logs_root="/var/log/apache2",
version_cmd=['apache2ctl', '-v'],
define_cmd=['apache2ctl', '-t', '-D', 'DUMP_RUN_CFG'],
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod="a2enmod",
dismod="a2dismod",
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2/vhosts.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
CLI_DEFAULTS_ARCH = dict(
server_root="/etc/httpd",
vhost_root="/etc/httpd/conf",
vhost_files="*.conf",
logs_root="/var/log/httpd",
version_cmd=['apachectl', '-v'],
define_cmd=['apachectl', '-t', '-D', 'DUMP_RUN_CFG'],
restart_cmd=['apachectl', 'graceful'],
conftest_cmd=['apachectl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/httpd/conf",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
CLI_DEFAULTS = {
"default": CLI_DEFAULTS_DEFAULT,
"debian": CLI_DEFAULTS_DEBIAN,
"ubuntu": CLI_DEFAULTS_DEBIAN,
"centos": CLI_DEFAULTS_CENTOS,
"centos linux": CLI_DEFAULTS_CENTOS,
"fedora": CLI_DEFAULTS_CENTOS,
"red hat enterprise linux server": CLI_DEFAULTS_CENTOS,
"rhel": CLI_DEFAULTS_CENTOS,
"amazon": CLI_DEFAULTS_CENTOS,
"gentoo": CLI_DEFAULTS_GENTOO,
"gentoo base system": CLI_DEFAULTS_GENTOO,
"darwin": CLI_DEFAULTS_DARWIN,
"opensuse": CLI_DEFAULTS_SUSE,
"suse": CLI_DEFAULTS_SUSE,
"arch": CLI_DEFAULTS_ARCH,
}
"""CLI defaults."""
MOD_SSL_CONF_DEST = "options-ssl-apache.conf"
"""Name of the mod_ssl config file as saved in `IConfig.config_dir`."""
@@ -191,39 +46,3 @@ UIR_ARGS = ["always", "set", "Content-Security-Policy",
HEADER_ARGS = {"Strict-Transport-Security": HSTS_ARGS,
"Upgrade-Insecure-Requests": UIR_ARGS}
def os_constant(key):
"""
Get a constant value for operating system
:param key: name of cli constant
:return: value of constant for active os
"""
os_info = util.get_os_info()
try:
constants = CLI_DEFAULTS[os_info[0].lower()]
except KeyError:
constants = os_like_constants()
if not constants:
constants = CLI_DEFAULTS["default"]
return constants[key]
def os_like_constants():
"""
Try to get constants for distribution with
similar layout and configuration, indicated by
/etc/os-release variable "LIKE"
:returns: Constants dictionary
:rtype: `dict`
"""
os_like = util.get_systemd_os_like()
if os_like:
for os_name in os_like:
if os_name in CLI_DEFAULTS.keys():
return CLI_DEFAULTS[os_name]
return {}

View File

@@ -0,0 +1,47 @@
""" Entry point for Apache Plugin """
from certbot import util
from certbot_apache import configurator
from certbot_apache import override_arch
from certbot_apache import override_darwin
from certbot_apache import override_debian
from certbot_apache import override_centos
from certbot_apache import override_gentoo
from certbot_apache import override_suse
OVERRIDE_CLASSES = {
"arch": override_arch.ArchConfigurator,
"darwin": override_darwin.DarwinConfigurator,
"debian": override_debian.DebianConfigurator,
"ubuntu": override_debian.DebianConfigurator,
"centos": override_centos.CentOSConfigurator,
"centos linux": override_centos.CentOSConfigurator,
"fedora": override_centos.CentOSConfigurator,
"red hat enterprise linux server": override_centos.CentOSConfigurator,
"rhel": override_centos.CentOSConfigurator,
"amazon": override_centos.CentOSConfigurator,
"gentoo": override_gentoo.GentooConfigurator,
"gentoo base system": override_gentoo.GentooConfigurator,
"opensuse": override_suse.OpenSUSEConfigurator,
"suse": override_suse.OpenSUSEConfigurator,
}
def get_configurator():
""" Get correct configurator class based on the OS fingerprint """
os_info = util.get_os_info()
override_class = None
try:
override_class = OVERRIDE_CLASSES[os_info[0].lower()]
except KeyError:
# OS not found in the list
os_like = util.get_systemd_os_like()
if os_like:
for os_name in os_like:
if os_name in OVERRIDE_CLASSES.keys():
override_class = OVERRIDE_CLASSES[os_name]
if not override_class:
# No override class found, return the generic configurator
override_class = configurator.ApacheConfigurator
return override_class
ENTRYPOINT = get_configurator()

View File

@@ -0,0 +1,31 @@
""" Distribution specific override class for Arch Linux """
import pkg_resources
import zope.interface
from certbot import interfaces
from certbot_apache import configurator
@zope.interface.provider(interfaces.IPluginFactory)
class ArchConfigurator(configurator.ApacheConfigurator):
"""Arch Linux specific ApacheConfigurator override class"""
OS_DEFAULTS = dict(
server_root="/etc/httpd",
vhost_root="/etc/httpd/conf",
vhost_files="*.conf",
logs_root="/var/log/httpd",
version_cmd=['apachectl', '-v'],
apache_cmd="apachectl",
restart_cmd=['apachectl', 'graceful'],
conftest_cmd=['apachectl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/httpd/conf",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)

View File

@@ -0,0 +1,59 @@
""" Distribution specific override class for CentOS family (RHEL, Fedora) """
import pkg_resources
import zope.interface
from certbot import interfaces
from certbot_apache import apache_util
from certbot_apache import configurator
from certbot_apache import parser
@zope.interface.provider(interfaces.IPluginFactory)
class CentOSConfigurator(configurator.ApacheConfigurator):
"""CentOS specific ApacheConfigurator override class"""
OS_DEFAULTS = dict(
server_root="/etc/httpd",
vhost_root="/etc/httpd/conf.d",
vhost_files="*.conf",
logs_root="/var/log/httpd",
version_cmd=['apachectl', '-v'],
apache_cmd="apachectl",
restart_cmd=['apachectl', 'graceful'],
conftest_cmd=['apachectl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/httpd/conf.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "centos-options-ssl-apache.conf")
)
def get_parser(self):
"""Initializes the ApacheParser"""
return CentOSParser(
self.aug, self.conf("server-root"), self.conf("vhost-root"),
self.version, configurator=self)
class CentOSParser(parser.ApacheParser):
"""CentOS specific ApacheParser override class"""
def __init__(self, *args, **kwargs):
# CentOS specific configuration file for Apache
self.sysconfig_filep = "/etc/sysconfig/httpd"
super(CentOSParser, self).__init__(*args, **kwargs)
def update_runtime_variables(self, *args, **kwargs):
""" Override for update_runtime_variables for custom parsing """
# Opportunistic, works if SELinux not enforced
super(CentOSParser, self).update_runtime_variables(*args, **kwargs)
self.parse_sysconfig_var()
def parse_sysconfig_var(self):
""" Parses Apache CLI options from CentOS configuration file """
defines = apache_util.parse_define_file(self.sysconfig_filep, "OPTIONS")
for k in defines.keys():
self.variables[k] = defines[k]

View File

@@ -0,0 +1,31 @@
""" Distribution specific override class for macOS """
import pkg_resources
import zope.interface
from certbot import interfaces
from certbot_apache import configurator
@zope.interface.provider(interfaces.IPluginFactory)
class DarwinConfigurator(configurator.ApacheConfigurator):
"""macOS specific ApacheConfigurator override class"""
OS_DEFAULTS = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/other",
vhost_files="*.conf",
logs_root="/var/log/apache2",
version_cmd=['/usr/sbin/httpd', '-v'],
apache_cmd="/usr/sbin/httpd",
restart_cmd=['apachectl', 'graceful'],
conftest_cmd=['apachectl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2/other",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)

View File

@@ -0,0 +1,144 @@
""" Distribution specific override class for Debian family (Ubuntu/Debian) """
import logging
import os
import pkg_resources
import zope.interface
from certbot import errors
from certbot import interfaces
from certbot import util
from certbot_apache import apache_util
from certbot_apache import configurator
logger = logging.getLogger(__name__)
@zope.interface.provider(interfaces.IPluginFactory)
class DebianConfigurator(configurator.ApacheConfigurator):
"""Debian specific ApacheConfigurator override class"""
OS_DEFAULTS = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/sites-available",
vhost_files="*",
logs_root="/var/log/apache2",
version_cmd=['apache2ctl', '-v'],
apache_cmd="apache2ctl",
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod="a2enmod",
dismod="a2dismod",
le_vhost_ext="-le-ssl.conf",
handle_mods=True,
handle_sites=True,
challenge_location="/etc/apache2",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
def enable_site(self, vhost):
"""Enables an available site, Apache reload required.
.. note:: Does not make sure that the site correctly works or that all
modules are enabled appropriately.
:param vhost: vhost to enable
:type vhost: :class:`~certbot_apache.obj.VirtualHost`
:raises .errors.NotSupportedError: If filesystem layout is not
supported.
"""
if vhost.enabled:
return
enabled_path = ("%s/sites-enabled/%s" %
(self.parser.root,
os.path.basename(vhost.filep)))
if not os.path.isdir(os.path.dirname(enabled_path)):
# For some reason, sites-enabled / sites-available do not exist
# Call the parent method
return super(DebianConfigurator, self).enable_site(vhost)
self.reverter.register_file_creation(False, enabled_path)
try:
os.symlink(vhost.filep, enabled_path)
except OSError as err:
if os.path.islink(enabled_path) and os.path.realpath(
enabled_path) == vhost.filep:
# Already in shape
vhost.enabled = True
return
else:
logger.warning(
"Could not symlink %s to %s, got error: %s", enabled_path,
vhost.filep, err.strerror)
errstring = ("Encountered error while trying to enable a " +
"newly created VirtualHost located at {0} by " +
"linking to it from {1}")
raise errors.NotSupportedError(errstring.format(vhost.filep,
enabled_path))
vhost.enabled = True
logger.info("Enabling available site: %s", vhost.filep)
self.save_notes += "Enabled site %s\n" % vhost.filep
def enable_mod(self, mod_name, temp=False):
# pylint: disable=unused-argument
"""Enables module in Apache.
Both enables and reloads Apache so module is active.
:param str mod_name: Name of the module to enable. (e.g. 'ssl')
:param bool temp: Whether or not this is a temporary action.
:raises .errors.NotSupportedError: If the filesystem layout is not
supported.
:raises .errors.MisconfigurationError: If a2enmod or a2dismod cannot be
run.
"""
avail_path = os.path.join(self.parser.root, "mods-available")
enabled_path = os.path.join(self.parser.root, "mods-enabled")
if not os.path.isdir(avail_path) or not os.path.isdir(enabled_path):
raise errors.NotSupportedError(
"Unsupported directory layout. You may try to enable mod %s "
"and try again." % mod_name)
deps = apache_util.get_mod_deps(mod_name)
# Enable all dependencies
for dep in deps:
if (dep + "_module") not in self.parser.modules:
self._enable_mod_debian(dep, temp)
self.parser.add_mod(dep)
note = "Enabled dependency of %s module - %s" % (mod_name, dep)
if not temp:
self.save_notes += note + os.linesep
logger.debug(note)
# Enable actual module
self._enable_mod_debian(mod_name, temp)
self.parser.add_mod(mod_name)
if not temp:
self.save_notes += "Enabled %s module in Apache\n" % mod_name
logger.info("Enabled Apache %s module", mod_name)
# Modules can enable additional config files. Variables may be defined
# within these new configuration sections.
# Reload is not necessary as DUMP_RUN_CFG uses latest config.
self.parser.update_runtime_variables()
def _enable_mod_debian(self, mod_name, temp):
"""Assumes mods-available, mods-enabled layout."""
# Generate reversal command.
# Try to be safe here... check that we can probably reverse before
# applying enmod command
if not util.exe_exists(self.conf("dismod")):
raise errors.MisconfigurationError(
"Unable to find a2dismod, please make sure a2enmod and "
"a2dismod are configured correctly for certbot.")
self.reverter.register_undo_command(
temp, [self.conf("dismod"), mod_name])
util.run_script([self.conf("enmod"), mod_name])

View File

@@ -0,0 +1,58 @@
""" Distribution specific override class for Gentoo Linux """
import pkg_resources
import zope.interface
from certbot import interfaces
from certbot_apache import apache_util
from certbot_apache import configurator
from certbot_apache import parser
@zope.interface.provider(interfaces.IPluginFactory)
class GentooConfigurator(configurator.ApacheConfigurator):
"""Gentoo specific ApacheConfigurator override class"""
OS_DEFAULTS = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/vhosts.d",
vhost_files="*.conf",
logs_root="/var/log/apache2",
version_cmd=['/usr/sbin/apache2', '-v'],
apache_cmd="apache2ctl",
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod=None,
dismod=None,
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2/vhosts.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)
def get_parser(self):
"""Initializes the ApacheParser"""
return GentooParser(
self.aug, self.conf("server-root"), self.conf("vhost-root"),
self.version, configurator=self)
class GentooParser(parser.ApacheParser):
"""Gentoo specific ApacheParser override class"""
def __init__(self, *args, **kwargs):
# Gentoo specific configuration file for Apache2
self.apacheconfig_filep = "/etc/conf.d/apache2"
super(GentooParser, self).__init__(*args, **kwargs)
def update_runtime_variables(self):
""" Override for update_runtime_variables for custom parsing """
self.parse_sysconfig_var()
def parse_sysconfig_var(self):
""" Parses Apache CLI options from Gentoo configuration file """
defines = apache_util.parse_define_file(self.apacheconfig_filep,
"APACHE2_OPTS")
for k in defines.keys():
self.variables[k] = defines[k]

View File

@@ -0,0 +1,31 @@
""" Distribution specific override class for OpenSUSE """
import pkg_resources
import zope.interface
from certbot import interfaces
from certbot_apache import configurator
@zope.interface.provider(interfaces.IPluginFactory)
class OpenSUSEConfigurator(configurator.ApacheConfigurator):
"""OpenSUSE specific ApacheConfigurator override class"""
OS_DEFAULTS = dict(
server_root="/etc/apache2",
vhost_root="/etc/apache2/vhosts.d",
vhost_files="*.conf",
logs_root="/var/log/apache2",
version_cmd=['apache2ctl', '-v'],
apache_cmd="apache2ctl",
restart_cmd=['apache2ctl', 'graceful'],
conftest_cmd=['apache2ctl', 'configtest'],
enmod="a2enmod",
dismod="a2dismod",
le_vhost_ext="-le-ssl.conf",
handle_mods=False,
handle_sites=False,
challenge_location="/etc/apache2/vhosts.d",
MOD_SSL_CONF_SRC=pkg_resources.resource_filename(
"certbot_apache", "options-ssl-apache.conf")
)

View File

@@ -11,8 +11,6 @@ import six
from certbot import errors
from certbot_apache import constants
logger = logging.getLogger(__name__)
@@ -40,14 +38,9 @@ class ApacheParser(object):
# issues with aug.load() after adding new files / defines to parse tree
self.configurator = configurator
# This uses the binary, so it can be done first.
# https://httpd.apache.org/docs/2.4/mod/core.html#define
# https://httpd.apache.org/docs/2.4/mod/core.html#ifdefine
# This only handles invocation parameters and Define directives!
self.modules = set()
self.parser_paths = {}
self.variables = {}
if version >= (2, 4):
self.update_runtime_variables()
self.aug = aug
# Find configuration root and make sure augeas can parse it.
@@ -55,24 +48,26 @@ class ApacheParser(object):
self.loc = {"root": self._find_config_root()}
self.parse_file(self.loc["root"])
if version >= (2, 4):
# Look up variables from httpd and add to DOM if not already parsed
self.update_runtime_variables()
# This problem has been fixed in Augeas 1.0
self.standardize_excl()
# Temporarily set modules to be empty, so that find_dirs can work
# https://httpd.apache.org/docs/2.4/mod/core.html#ifmodule
# This needs to come before locations are set.
self.modules = set()
self.init_modules()
# Parse LoadModule directives from configuration files
self.parse_modules()
# Set up rest of locations
self.loc.update(self._set_locations())
# list of the active include paths, before modifications
self.existing_paths = copy.deepcopy(self.parser_paths)
# Must also attempt to parse additional virtual host root
if vhostroot:
self.parse_file(os.path.abspath(vhostroot) + "/" +
constants.os_constant("vhost_files"))
self.configurator.constant("vhost_files"))
# check to see if there were unparsed define statements
if version < (2, 4):
@@ -103,50 +98,61 @@ class ApacheParser(object):
# Create a new path
self.existing_paths[new_dir] = [new_file]
def init_modules(self):
def add_mod(self, mod_name):
"""Shortcut for updating parser modules."""
if mod_name + "_module" not in self.modules:
self.modules.add(mod_name + "_module")
if "mod_" + mod_name + ".c" not in self.modules:
self.modules.add("mod_" + mod_name + ".c")
def reset_modules(self):
"""Reset the loaded modules list. This is called from cleanup to clear
temporarily loaded modules."""
self.modules = set()
self.update_modules()
self.parse_modules()
def parse_modules(self):
"""Iterates on the configuration until no new modules are loaded.
..todo:: This should be attempted to be done with a binary to avoid
the iteration issue. Else... parse and enable mods at same time.
"""
# Since modules are being initiated... clear existing set.
self.modules = set()
mods = set()
matches = self.find_dir("LoadModule")
iterator = iter(matches)
# Make sure prev_size != cur_size for do: while: iteration
prev_size = -1
while len(self.modules) != prev_size:
prev_size = len(self.modules)
while len(mods) != prev_size:
prev_size = len(mods)
for match_name, match_filename in six.moves.zip(
iterator, iterator):
mod_name = self.get_arg(match_name)
mod_filename = self.get_arg(match_filename)
if mod_name and mod_filename:
self.modules.add(mod_name)
self.modules.add(os.path.basename(mod_filename)[:-2] + "c")
mods.add(mod_name)
mods.add(os.path.basename(mod_filename)[:-2] + "c")
else:
logger.debug("Could not read LoadModule directive from " +
"Augeas path: {0}".format(match_name[6:]))
self.modules.update(mods)
def update_runtime_variables(self):
""""
"""Update Includes, Defines and Includes from httpd config dump data"""
self.update_defines()
self.update_includes()
self.update_modules()
.. note:: Compile time variables (apache2ctl -V) are not used within
the dynamic configuration files. These should not be parsed or
interpreted.
.. todo:: Create separate compile time variables...
simply for arg_get()
"""
stdout = self._get_runtime_cfg()
def update_defines(self):
"""Get Defines from httpd process"""
variables = dict()
matches = re.compile(r"Define: ([^ \n]*)").findall(stdout)
define_cmd = [self.configurator.constant("apache_cmd"), "-t", "-D",
"DUMP_RUN_CFG"]
matches = self.parse_from_subprocess(define_cmd, r"Define: ([^ \n]*)")
try:
matches.remove("DUMP_RUN_CFG")
except ValueError:
@@ -163,15 +169,54 @@ class ApacheParser(object):
self.variables = variables
def _get_runtime_cfg(self): # pylint: disable=no-self-use
"""Get runtime configuration info.
def update_includes(self):
"""Get includes from httpd process, and add them to DOM if needed"""
:returns: stdout from DUMP_RUN_CFG
# Find_dir iterates over configuration for Include and IncludeOptional
# directives to make sure we see the full include tree present in the
# configuration files
_ = self.find_dir("Include")
inc_cmd = [self.configurator.constant("apache_cmd"), "-t", "-D",
"DUMP_INCLUDES"]
matches = self.parse_from_subprocess(inc_cmd, r"\(.*\) (.*)")
if matches:
for i in matches:
if not self.parsed_in_current(i):
self.parse_file(i)
def update_modules(self):
"""Get loaded modules from httpd process, and add them to DOM"""
mod_cmd = [self.configurator.constant("apache_cmd"), "-t", "-D",
"DUMP_MODULES"]
matches = self.parse_from_subprocess(mod_cmd, r"(.*)_module")
for mod in matches:
self.add_mod(mod.strip())
def parse_from_subprocess(self, command, regexp):
"""Get values from stdout of subprocess command
:param list command: Command to run
:param str regexp: Regexp for parsing
:returns: list parsed from command output
:rtype: list
"""
stdout = self._get_runtime_cfg(command)
return re.compile(regexp).findall(stdout)
def _get_runtime_cfg(self, command): # pylint: disable=no-self-use
"""Get runtime configuration info.
:param command: Command to run
:returns: stdout from command
"""
try:
proc = subprocess.Popen(
constants.os_constant("define_cmd"),
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
@@ -180,10 +225,10 @@ class ApacheParser(object):
except (OSError, ValueError):
logger.error(
"Error running command %s for runtime parameters!%s",
constants.os_constant("define_cmd"), os.linesep)
command, os.linesep)
raise errors.MisconfigurationError(
"Error accessing loaded Apache parameters: %s",
constants.os_constant("define_cmd"))
command)
# Small errors that do not impede
if proc.returncode != 0:
logger.warning("Error in checking parameter list: %s", stderr)

View File

@@ -0,0 +1,123 @@
"""Test for certbot_apache.configurator for Centos overrides"""
import os
import unittest
import mock
from certbot_apache import obj
from certbot_apache import override_centos
from certbot_apache.tests import util
def get_vh_truth(temp_dir, config_name):
"""Return the ground truth for the specified directory."""
prefix = os.path.join(
temp_dir, config_name, "httpd/conf.d")
aug_pre = "/files" + prefix
vh_truth = [
obj.VirtualHost(
os.path.join(prefix, "centos.example.com.conf"),
os.path.join(aug_pre, "centos.example.com.conf/VirtualHost"),
set([obj.Addr.fromstring("*:80")]),
False, True, "centos.example.com"),
obj.VirtualHost(
os.path.join(prefix, "ssl.conf"),
os.path.join(aug_pre, "ssl.conf/VirtualHost"),
set([obj.Addr.fromstring("_default_:443")]),
True, True, None)
]
return vh_truth
class MultipleVhostsTestCentOS(util.ApacheTest):
"""Multiple vhost tests for CentOS / RHEL family of distros"""
_multiprocess_can_split_ = True
def setUp(self): # pylint: disable=arguments-differ
test_dir = "centos7_apache/apache"
config_root = "centos7_apache/apache/httpd"
vhost_root = "centos7_apache/apache/httpd/conf.d"
super(MultipleVhostsTestCentOS, self).setUp(test_dir=test_dir,
config_root=config_root,
vhost_root=vhost_root)
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
os_info="centos")
self.vh_truth = get_vh_truth(
self.temp_dir, "centos7_apache/apache")
def test_get_parser(self):
self.assertTrue(isinstance(self.config.parser,
override_centos.CentOSParser))
@mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg")
def test_opportunistic_httpd_runtime_parsing(self, mock_get):
define_val = (
'Define: TEST1\n'
'Define: TEST2\n'
'Define: DUMP_RUN_CFG\n'
)
mod_val = (
'Loaded Modules:\n'
' mock_module (static)\n'
' another_module (static)\n'
)
def mock_get_cfg(command):
"""Mock httpd process stdout"""
if command == ['apachectl', '-t', '-D', 'DUMP_RUN_CFG']:
return define_val
elif command == ['apachectl', '-t', '-D', 'DUMP_MODULES']:
return mod_val
return ""
mock_get.side_effect = mock_get_cfg
self.config.parser.modules = set()
self.config.parser.variables = {}
with mock.patch("certbot.util.get_os_info") as mock_osi:
# Make sure we have the have the CentOS httpd constants
mock_osi.return_value = ("centos", "7")
self.config.parser.update_runtime_variables()
self.assertEquals(mock_get.call_count, 3)
self.assertEquals(len(self.config.parser.modules), 4)
self.assertEquals(len(self.config.parser.variables), 2)
self.assertTrue("TEST2" in self.config.parser.variables.keys())
self.assertTrue("mod_another.c" in self.config.parser.modules)
def test_get_virtual_hosts(self):
"""Make sure all vhosts are being properly found."""
vhs = self.config.get_virtual_hosts()
self.assertEqual(len(vhs), 2)
found = 0
for vhost in vhs:
for centos_truth in self.vh_truth:
if vhost == centos_truth:
found += 1
break
else:
raise Exception("Missed: %s" % vhost) # pragma: no cover
self.assertEqual(found, 2)
@mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg")
def test_get_sysconfig_vars(self, mock_cfg):
"""Make sure we read the sysconfig OPTIONS variable correctly"""
# Return nothing for the process calls
mock_cfg.return_value = ""
self.config.parser.sysconfig_filep = os.path.realpath(
os.path.join(self.config.parser.root, "../sysconfig/httpd"))
self.config.parser.variables = {}
with mock.patch("certbot.util.get_os_info") as mock_osi:
# Make sure we have the have the CentOS httpd constants
mock_osi.return_value = ("centos", "7")
self.config.parser.update_runtime_variables()
self.assertTrue("mock_define" in self.config.parser.variables.keys())
self.assertTrue("mock_define_too" in self.config.parser.variables.keys())
self.assertTrue("mock_value" in self.config.parser.variables.keys())
self.assertEqual("TRUE", self.config.parser.variables["mock_value"])
if __name__ == "__main__":
unittest.main() # pragma: no cover

View File

@@ -18,7 +18,7 @@ class ComplexParserTest(util.ParserTest):
self.setup_variables()
# This needs to happen after due to setup_variables not being run
# until after
self.parser.init_modules() # pylint: disable=protected-access
self.parser.parse_modules() # pylint: disable=protected-access
def tearDown(self):
shutil.rmtree(self.temp_dir)

View File

@@ -3,12 +3,12 @@
import os
import shutil
import socket
import tempfile
import unittest
import mock
# six is used in mock.patch()
import six # pylint: disable=unused-import
import tempfile
from acme import challenges
@@ -19,7 +19,7 @@ from certbot import errors
from certbot.tests import acme_util
from certbot.tests import util as certbot_util
from certbot_apache import configurator
from certbot_apache import apache_util
from certbot_apache import constants
from certbot_apache import parser
from certbot_apache import obj
@@ -34,39 +34,24 @@ class MultipleVhostsTest(util.ApacheTest):
def setUp(self): # pylint: disable=arguments-differ
super(MultipleVhostsTest, self).setUp()
from certbot_apache.constants import os_constant
orig_os_constant = os_constant
def mock_os_constant(key, vhost_path=self.vhost_path):
"""Mock default vhost path"""
if key == "vhost_root":
return vhost_path
else:
return orig_os_constant(key)
with mock.patch("certbot_apache.constants.os_constant") as mock_c:
mock_c.side_effect = mock_os_constant
self.config = util.get_apache_configurator(
self.config_path, None, self.config_dir, self.work_dir)
self.config = self.mock_deploy_cert(self.config)
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
self.config = self.mock_deploy_cert(self.config)
self.vh_truth = util.get_vh_truth(
self.temp_dir, "debian_apache_2_4/multiple_vhosts")
def mock_deploy_cert(self, config):
"""A test for a mock deploy cert"""
self.config.real_deploy_cert = self.config.deploy_cert
config.real_deploy_cert = self.config.deploy_cert
def mocked_deploy_cert(*args, **kwargs):
"""a helper to mock a deployed cert"""
with mock.patch("certbot_apache.configurator.ApacheConfigurator.enable_mod"):
g_mod = "certbot_apache.configurator.ApacheConfigurator.enable_mod"
with mock.patch(g_mod):
config.real_deploy_cert(*args, **kwargs)
self.config.deploy_cert = mocked_deploy_cert
return self.config
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
@mock.patch("certbot_apache.configurator.ApacheConfigurator.init_augeas")
@mock.patch("certbot_apache.configurator.path_surgery")
def test_prepare_no_install(self, mock_surgery, _init_augeas):
@@ -130,6 +115,10 @@ class MultipleVhostsTest(util.ApacheTest):
# Weak test..
ApacheConfigurator.add_parser_arguments(mock.MagicMock())
def test_constant(self):
self.assertEqual(self.config.constant("server_root"), "/etc/apache2")
self.assertEqual(self.config.constant("nonexistent"), None)
@certbot_util.patch_get_utility()
def test_get_all_names(self, mock_getutility):
mock_utility = mock_getutility()
@@ -163,13 +152,12 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertTrue("certbot.demo" in names)
def test_get_bad_path(self):
from certbot_apache.configurator import get_file_path
self.assertEqual(get_file_path(None), None)
self.assertEqual(get_file_path("nonexistent"), None)
self.assertEqual(apache_util.get_file_path(None), None)
self.assertEqual(apache_util.get_file_path("nonexistent"), None)
self.assertEqual(self.config._create_vhost("nonexistent"), None) # pylint: disable=protected-access
def test_get_aug_internal_path(self):
from certbot_apache.configurator import get_internal_aug_path
from certbot_apache.apache_util import get_internal_aug_path
internal_paths = [
"Virtualhost", "IfModule/VirtualHost", "VirtualHost", "VirtualHost",
"Macro/VirtualHost", "IfModule/VirtualHost", "VirtualHost",
@@ -319,190 +307,23 @@ class MultipleVhostsTest(util.ApacheTest):
# pylint: disable=protected-access
self.assertEqual(len(self.config._non_default_vhosts()), 8)
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
@mock.patch("certbot_apache.parser.subprocess.Popen")
def test_enable_mod(self, mock_popen, mock_exe_exists, mock_run_script):
mock_popen().communicate.return_value = ("Define: DUMP_RUN_CFG", "")
mock_popen().returncode = 0
mock_exe_exists.return_value = True
self.config.enable_mod("ssl")
self.assertTrue("ssl_module" in self.config.parser.modules)
self.assertTrue("mod_ssl.c" in self.config.parser.modules)
self.assertTrue(mock_run_script.called)
def test_enable_mod_unsupported_dirs(self):
shutil.rmtree(os.path.join(self.config.parser.root, "mods-enabled"))
self.assertRaises(
errors.NotSupportedError, self.config.enable_mod, "ssl")
@mock.patch("certbot.util.exe_exists")
def test_enable_mod_no_disable(self, mock_exe_exists):
mock_exe_exists.return_value = False
self.assertRaises(
errors.MisconfigurationError, self.config.enable_mod, "ssl")
def test_enable_site_already_enabled(self):
self.assertTrue(self.vh_truth[1].enabled)
self.config.enable_site(self.vh_truth[1])
def test_enable_site_failure(self):
self.config.parser.root = "/tmp/nonexistent"
self.assertRaises(
errors.NotSupportedError,
self.config.enable_site,
obj.VirtualHost("asdf", "afsaf", set(), False, False))
def test_enable_site_nondebian(self):
mock_c = "certbot_apache.configurator.ApacheConfigurator.conf"
def conf_side_effect(arg):
""" Mock function for ApacheConfigurator.conf """
confvars = {"handle-sites": False}
if arg in confvars:
return confvars[arg]
inc_path = "/path/to/wherever"
vhost = self.vh_truth[0]
with mock.patch(mock_c) as mock_conf:
mock_conf.side_effect = conf_side_effect
vhost.enabled = False
vhost.filep = inc_path
self.assertFalse(self.config.parser.find_dir("Include", inc_path))
self.assertFalse(
os.path.dirname(inc_path) in self.config.parser.existing_paths)
self.config.enable_site(vhost)
self.assertTrue(self.config.parser.find_dir("Include", inc_path))
self.assertTrue(
os.path.dirname(inc_path) in self.config.parser.existing_paths)
self.assertTrue(
os.path.basename(inc_path) in self.config.parser.existing_paths[
os.path.dirname(inc_path)])
def test_deploy_cert_enable_new_vhost(self):
# Create
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0])
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
self.config.parser.modules.add("socache_shmcb_module")
self.assertFalse(ssl_vhost.enabled)
self.config.deploy_cert(
"encryption-example.demo", "example/cert.pem", "example/key.pem",
"example/cert_chain.pem", "example/fullchain.pem")
self.assertTrue(ssl_vhost.enabled)
# Make sure that we don't error out if symlink already exists
ssl_vhost.enabled = False
self.assertFalse(ssl_vhost.enabled)
self.config.deploy_cert(
"encryption-example.demo", "example/cert.pem", "example/key.pem",
"example/cert_chain.pem", "example/fullchain.pem")
self.assertTrue(ssl_vhost.enabled)
def test_deploy_cert_newssl(self):
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir,
self.work_dir, version=(2, 4, 16))
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
# Get the default 443 vhost
self.config.assoc["random.demo"] = self.vh_truth[1]
self.config = self.mock_deploy_cert(self.config)
self.config.deploy_cert(
"random.demo", "example/cert.pem", "example/key.pem",
"example/cert_chain.pem", "example/fullchain.pem")
self.config.save()
# Verify ssl_module was enabled.
self.assertTrue(self.vh_truth[1].enabled)
self.assertTrue("ssl_module" in self.config.parser.modules)
loc_cert = self.config.parser.find_dir(
"sslcertificatefile", "example/fullchain.pem",
self.vh_truth[1].path)
loc_key = self.config.parser.find_dir(
"sslcertificateKeyfile", "example/key.pem", self.vh_truth[1].path)
# Verify one directive was found in the correct file
self.assertEqual(len(loc_cert), 1)
self.assertEqual(
configurator.get_file_path(loc_cert[0]),
self.vh_truth[1].filep)
self.assertEqual(len(loc_key), 1)
self.assertEqual(
configurator.get_file_path(loc_key[0]),
self.vh_truth[1].filep)
def test_deploy_cert_newssl_no_fullchain(self):
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir,
self.work_dir, version=(2, 4, 16))
self.config = self.mock_deploy_cert(self.config)
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
# Get the default 443 vhost
self.config.assoc["random.demo"] = self.vh_truth[1]
self.assertRaises(errors.PluginError,
lambda: self.config.deploy_cert(
"random.demo", "example/cert.pem",
"example/key.pem"))
def test_deploy_cert_old_apache_no_chain(self):
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir,
self.work_dir, version=(2, 4, 7))
self.config = self.mock_deploy_cert(self.config)
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
# Get the default 443 vhost
self.config.assoc["random.demo"] = self.vh_truth[1]
self.assertRaises(errors.PluginError,
lambda: self.config.deploy_cert(
"random.demo", "example/cert.pem",
"example/key.pem"))
def test_deploy_cert_not_parsed_path(self):
# Make sure that we add include to root config for vhosts when
# handle-sites is false
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
tmp_path = os.path.realpath(tempfile.mkdtemp("vhostroot"))
os.chmod(tmp_path, 0o755)
mock_p = "certbot_apache.configurator.ApacheConfigurator._get_ssl_vhost_path"
mock_a = "certbot_apache.parser.ApacheParser.add_include"
mock_c = "certbot_apache.configurator.ApacheConfigurator.conf"
orig_conf = self.config.conf
def conf_side_effect(arg):
""" Mock function for ApacheConfigurator.conf """
confvars = {"handle-sites": False}
if arg in confvars:
return confvars[arg]
else:
return orig_conf("arg")
with mock.patch(mock_c) as mock_conf:
mock_conf.side_effect = conf_side_effect
with mock.patch(mock_p) as mock_path:
mock_path.return_value = os.path.join(tmp_path, "whatever.conf")
with mock.patch(mock_a) as mock_add:
self.config.deploy_cert(
"encryption-example.demo",
"example/cert.pem", "example/key.pem",
"example/cert_chain.pem")
# Test that we actually called add_include
self.assertTrue(mock_add.called)
shutil.rmtree(tmp_path)
def test_deploy_cert(self):
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
self.config.parser.modules.add("socache_shmcb_module")
# Patch _add_dummy_ssl_directives to make sure we write them correctly
# pylint: disable=protected-access
orig_add_dummy = self.config._add_dummy_ssl_directives
@@ -531,7 +352,6 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertTrue(
"insert_key_file_path" in find_args(vhostpath,
"SSLCertificateKeyFile"))
# pylint: disable=protected-access
self.config._add_dummy_ssl_directives = mock_add_dummy_ssl
@@ -557,17 +377,17 @@ class MultipleVhostsTest(util.ApacheTest):
# Verify one directive was found in the correct file
self.assertEqual(len(loc_cert), 1)
self.assertEqual(
configurator.get_file_path(loc_cert[0]),
apache_util.get_file_path(loc_cert[0]),
self.vh_truth[1].filep)
self.assertEqual(len(loc_key), 1)
self.assertEqual(
configurator.get_file_path(loc_key[0]),
apache_util.get_file_path(loc_key[0]),
self.vh_truth[1].filep)
self.assertEqual(len(loc_chain), 1)
self.assertEqual(
configurator.get_file_path(loc_chain[0]),
apache_util.get_file_path(loc_chain[0]),
self.vh_truth[1].filep)
# One more time for chain directive setting
@@ -877,7 +697,9 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertEqual(mock_restart.call_count, 1)
@mock.patch("certbot_apache.configurator.ApacheConfigurator.restart")
def test_cleanup(self, mock_restart):
@mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg")
def test_cleanup(self, mock_cfg, mock_restart):
mock_cfg.return_value = ""
_, achall1, achall2 = self.get_achalls()
self.config._chall_out.add(achall1) # pylint: disable=protected-access
@@ -890,7 +712,9 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertTrue(mock_restart.called)
@mock.patch("certbot_apache.configurator.ApacheConfigurator.restart")
def test_cleanup_no_errors(self, mock_restart):
@mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg")
def test_cleanup_no_errors(self, mock_cfg, mock_restart):
mock_cfg.return_value = ""
_, achall1, achall2 = self.get_achalls()
self.config._chall_out.add(achall1) # pylint: disable=protected-access
@@ -951,10 +775,9 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertTrue(isinstance(self.config.get_chall_pref(""), list))
def test_install_ssl_options_conf(self):
from certbot_apache.configurator import install_ssl_options_conf
path = os.path.join(self.work_dir, "test_it")
other_path = os.path.join(self.work_dir, "other_test_it")
install_ssl_options_conf(path, other_path)
self.config.install_ssl_options_conf(path, other_path)
self.assertTrue(os.path.isfile(path))
self.assertTrue(os.path.isfile(other_path))
@@ -994,20 +817,17 @@ class MultipleVhostsTest(util.ApacheTest):
errors.PluginError,
self.config.enhance, "certbot.demo", "unknown_enhancement")
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
def test_ocsp_stapling(self, mock_exe, mock_run_script):
def test_ocsp_stapling(self, mock_exe):
self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c")
self.config.parser.modules.add("socache_shmcb_module")
self.config.get_version = mock.Mock(return_value=(2, 4, 7))
mock_exe.return_value = True
# This will create an ssl vhost for certbot.demo
self.config.enhance("certbot.demo", "staple-ocsp")
self.assertTrue("socache_shmcb_module" in self.config.parser.modules)
self.assertTrue(mock_run_script.called)
# Get the ssl vhost for certbot.demo
ssl_vhost = self.config.assoc["certbot.demo"]
@@ -1077,14 +897,13 @@ class MultipleVhostsTest(util.ApacheTest):
def test_http_header_hsts(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c")
self.config.parser.modules.add("headers_module")
mock_exe.return_value = True
# This will create an ssl vhost for certbot.demo
self.config.enhance("certbot.demo", "ensure-http-header",
"Strict-Transport-Security")
self.assertTrue("headers_module" in self.config.parser.modules)
# Get the ssl vhost for certbot.demo
ssl_vhost = self.config.assoc["certbot.demo"]
@@ -1115,6 +934,8 @@ class MultipleVhostsTest(util.ApacheTest):
def test_http_header_uir(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c")
self.config.parser.modules.add("headers_module")
mock_exe.return_value = True
# This will create an ssl vhost for certbot.demo
@@ -1151,6 +972,7 @@ class MultipleVhostsTest(util.ApacheTest):
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
def test_redirect_well_formed_http(self, mock_exe, _):
self.config.parser.modules.add("rewrite_module")
self.config.parser.update_runtime_variables = mock.Mock()
mock_exe.return_value = True
self.config.get_version = mock.Mock(return_value=(2, 2))
@@ -1173,8 +995,6 @@ class MultipleVhostsTest(util.ApacheTest):
self.assertTrue(rw_engine[0].startswith(self.vh_truth[3].path[:-3]))
self.assertTrue(rw_rule[0].startswith(self.vh_truth[3].path[:-3]))
self.assertTrue("rewrite_module" in self.config.parser.modules)
def test_rewrite_rule_exists(self):
# Skip the enable mod
self.config.parser.modules.add("rewrite_module")
@@ -1196,6 +1016,7 @@ class MultipleVhostsTest(util.ApacheTest):
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
def test_redirect_with_existing_rewrite(self, mock_exe, _):
self.config.parser.modules.add("rewrite_module")
self.config.parser.update_runtime_variables = mock.Mock()
mock_exe.return_value = True
self.config.get_version = mock.Mock(return_value=(2, 2, 0))
@@ -1228,6 +1049,7 @@ class MultipleVhostsTest(util.ApacheTest):
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
def test_redirect_with_old_https_redirection(self, mock_exe, _):
self.config.parser.modules.add("rewrite_module")
self.config.parser.update_runtime_variables = mock.Mock()
mock_exe.return_value = True
self.config.get_version = mock.Mock(return_value=(2, 2, 0))
@@ -1365,6 +1187,57 @@ class MultipleVhostsTest(util.ApacheTest):
self.config.aug.match.side_effect = RuntimeError
self.assertFalse(self.config._check_aug_version())
def test_enable_site_nondebian(self):
inc_path = "/path/to/wherever"
vhost = self.vh_truth[0]
vhost.enabled = False
vhost.filep = inc_path
self.assertFalse(self.config.parser.find_dir("Include", inc_path))
self.assertFalse(
os.path.dirname(inc_path) in self.config.parser.existing_paths)
self.config.enable_site(vhost)
self.assertTrue(self.config.parser.find_dir("Include", inc_path))
self.assertTrue(
os.path.dirname(inc_path) in self.config.parser.existing_paths)
self.assertTrue(
os.path.basename(inc_path) in self.config.parser.existing_paths[
os.path.dirname(inc_path)])
def test_deploy_cert_not_parsed_path(self):
# Make sure that we add include to root config for vhosts when
# handle-sites is false
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
self.config.parser.modules.add("socache_shmcb_module")
tmp_path = os.path.realpath(tempfile.mkdtemp("vhostroot"))
os.chmod(tmp_path, 0o755)
mock_p = "certbot_apache.configurator.ApacheConfigurator._get_ssl_vhost_path"
mock_a = "certbot_apache.parser.ApacheParser.add_include"
with mock.patch(mock_p) as mock_path:
mock_path.return_value = os.path.join(tmp_path, "whatever.conf")
with mock.patch(mock_a) as mock_add:
self.config.deploy_cert(
"encryption-example.demo",
"example/cert.pem", "example/key.pem",
"example/cert_chain.pem")
# Test that we actually called add_include
self.assertTrue(mock_add.called)
shutil.rmtree(tmp_path)
@mock.patch("certbot_apache.parser.ApacheParser.parsed_in_original")
def test_choose_vhost_and_servername_addition_parsed(self, mock_parsed):
ret_vh = self.vh_truth[8]
ret_vh.enabled = True
self.config.enable_site(ret_vh)
# Make sure that we return early
self.assertFalse(mock_parsed.called)
def test_enable_mod_unsupported(self):
self.assertRaises(errors.MisconfigurationError,
self.config.enable_mod,
"whatever")
class AugeasVhostsTest(util.ApacheTest):
"""Test vhosts with illegal names dependent on augeas version."""
# pylint: disable=protected-access
@@ -1378,12 +1251,8 @@ class AugeasVhostsTest(util.ApacheTest):
vhost_root=vr)
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
self.config_path, self.vhost_path, self.config_dir,
self.work_dir)
def test_choosevhost_with_illegal_name(self):
self.config.aug = mock.MagicMock()
@@ -1461,15 +1330,11 @@ class MultiVhostsTest(util.ApacheTest):
vhost_root=vr)
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
self.config_path, self.vhost_path,
self.config_dir, self.work_dir, conf_vhost_path=self.vhost_path)
self.vh_truth = util.get_vh_truth(
self.temp_dir, "debian_apache_2_4/multi_vhosts")
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
def test_make_vhost_ssl(self):
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[1])
@@ -1569,11 +1434,11 @@ class InstallSslOptionsConfTest(util.ApacheTest):
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
def _call(self):
from certbot_apache.configurator import install_ssl_options_conf
install_ssl_options_conf(self.config.mod_ssl_conf, self.config.updated_mod_ssl_conf_digest)
self.config.install_ssl_options_conf(self.config.mod_ssl_conf,
self.config.updated_mod_ssl_conf_digest)
def _current_ssl_options_hash(self):
return crypto_util.sha256sum(constants.os_constant("MOD_SSL_CONF_SRC"))
return crypto_util.sha256sum(self.config.constant("MOD_SSL_CONF_SRC"))
def _assert_current_file(self):
self.assertTrue(os.path.isfile(self.config.mod_ssl_conf))
@@ -1608,7 +1473,8 @@ class InstallSslOptionsConfTest(util.ApacheTest):
self._call()
self.assertFalse(mock_logger.warning.called)
self.assertTrue(os.path.isfile(self.config.mod_ssl_conf))
self.assertEqual(crypto_util.sha256sum(constants.os_constant("MOD_SSL_CONF_SRC")),
self.assertEqual(crypto_util.sha256sum(
self.config.constant("MOD_SSL_CONF_SRC")),
self._current_ssl_options_hash())
self.assertNotEqual(crypto_util.sha256sum(self.config.mod_ssl_conf),
self._current_ssl_options_hash())
@@ -1623,7 +1489,8 @@ class InstallSslOptionsConfTest(util.ApacheTest):
self.assertEqual(mock_logger.warning.call_args[0][0],
"%s has been manually modified; updated file "
"saved to %s. We recommend updating %s for security purposes.")
self.assertEqual(crypto_util.sha256sum(constants.os_constant("MOD_SSL_CONF_SRC")),
self.assertEqual(crypto_util.sha256sum(
self.config.constant("MOD_SSL_CONF_SRC")),
self._current_ssl_options_hash())
# only print warning once
with mock.patch("certbot.plugins.common.logger") as mock_logger:

View File

@@ -1,44 +0,0 @@
"""Test for certbot_apache.configurator."""
import mock
import unittest
from certbot_apache import constants
class ConstantsTest(unittest.TestCase):
@mock.patch("certbot.util.get_os_info")
def test_get_debian_value(self, os_info):
os_info.return_value = ('Debian', '', '')
self.assertEqual(constants.os_constant("vhost_root"),
"/etc/apache2/sites-available")
@mock.patch("certbot.util.get_os_info")
def test_get_centos_value(self, os_info):
os_info.return_value = ('CentOS Linux', '', '')
self.assertEqual(constants.os_constant("vhost_root"),
"/etc/httpd/conf.d")
@mock.patch("certbot.util.get_systemd_os_like")
@mock.patch("certbot.util.get_os_info")
def test_get_default_values(self, os_info, os_like):
os_info.return_value = ('Nonexistent Linux', '', '')
os_like.return_value = {}
self.assertFalse(constants.os_constant("handle_mods"))
self.assertEqual(constants.os_constant("server_root"), "/etc/apache2")
self.assertEqual(constants.os_constant("vhost_root"),
"/etc/apache2/sites-available")
@mock.patch("certbot.util.get_systemd_os_like")
@mock.patch("certbot.util.get_os_info")
def test_get_darwin_like_values(self, os_info, os_like):
os_info.return_value = ('Nonexistent Linux', '', '')
os_like.return_value = ["something", "nonexistent", "darwin"]
self.assertFalse(constants.os_constant("enmod"))
self.assertEqual(constants.os_constant("vhost_root"),
"/etc/apache2/other")
if __name__ == "__main__":
unittest.main() # pragma: no cover

View File

@@ -0,0 +1,209 @@
"""Test for certbot_apache.configurator for Debian overrides"""
import os
import shutil
import unittest
import mock
from certbot import errors
from certbot_apache import apache_util
from certbot_apache import obj
from certbot_apache.tests import util
class MultipleVhostsTestDebian(util.ApacheTest):
"""Multiple vhost tests for Debian family of distros"""
_multiprocess_can_split_ = True
def setUp(self): # pylint: disable=arguments-differ
super(MultipleVhostsTestDebian, self).setUp()
self.config = util.get_apache_configurator(
self.config_path, None, self.config_dir, self.work_dir,
os_info="debian")
self.config = self.mock_deploy_cert(self.config)
self.vh_truth = util.get_vh_truth(self.temp_dir,
"debian_apache_2_4/multiple_vhosts")
def mock_deploy_cert(self, config):
"""A test for a mock deploy cert"""
config.real_deploy_cert = self.config.deploy_cert
def mocked_deploy_cert(*args, **kwargs):
"""a helper to mock a deployed cert"""
g_mod = "certbot_apache.configurator.ApacheConfigurator.enable_mod"
d_mod = "certbot_apache.override_debian.DebianConfigurator.enable_mod"
with mock.patch(g_mod):
with mock.patch(d_mod):
config.real_deploy_cert(*args, **kwargs)
self.config.deploy_cert = mocked_deploy_cert
return self.config
def test_enable_mod_unsupported_dirs(self):
shutil.rmtree(os.path.join(self.config.parser.root, "mods-enabled"))
self.assertRaises(
errors.NotSupportedError, self.config.enable_mod, "ssl")
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
@mock.patch("certbot_apache.parser.subprocess.Popen")
def test_enable_mod(self, mock_popen, mock_exe_exists, mock_run_script):
mock_popen().communicate.return_value = ("Define: DUMP_RUN_CFG", "")
mock_popen().returncode = 0
mock_exe_exists.return_value = True
self.config.enable_mod("ssl")
self.assertTrue("ssl_module" in self.config.parser.modules)
self.assertTrue("mod_ssl.c" in self.config.parser.modules)
self.assertTrue(mock_run_script.called)
def test_deploy_cert_enable_new_vhost(self):
# Create
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0])
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
self.assertFalse(ssl_vhost.enabled)
self.config.deploy_cert(
"encryption-example.demo", "example/cert.pem", "example/key.pem",
"example/cert_chain.pem", "example/fullchain.pem")
self.assertTrue(ssl_vhost.enabled)
# Make sure that we don't error out if symlink already exists
ssl_vhost.enabled = False
self.assertFalse(ssl_vhost.enabled)
self.config.deploy_cert(
"encryption-example.demo", "example/cert.pem", "example/key.pem",
"example/cert_chain.pem", "example/fullchain.pem")
self.assertTrue(ssl_vhost.enabled)
def test_enable_site_failure(self):
self.config.parser.root = "/tmp/nonexistent"
with mock.patch("os.path.isdir") as mock_dir:
mock_dir.return_value = True
with mock.patch("os.path.islink") as mock_link:
mock_link.return_value = False
self.assertRaises(
errors.NotSupportedError,
self.config.enable_site,
obj.VirtualHost("asdf", "afsaf", set(), False, False))
def test_deploy_cert_newssl(self):
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir,
self.work_dir, version=(2, 4, 16))
self.config = self.mock_deploy_cert(self.config)
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
# Get the default 443 vhost
self.config.assoc["random.demo"] = self.vh_truth[1]
self.config.deploy_cert(
"random.demo", "example/cert.pem", "example/key.pem",
"example/cert_chain.pem", "example/fullchain.pem")
self.config.save()
# Verify ssl_module was enabled.
self.assertTrue(self.vh_truth[1].enabled)
self.assertTrue("ssl_module" in self.config.parser.modules)
loc_cert = self.config.parser.find_dir(
"sslcertificatefile", "example/fullchain.pem",
self.vh_truth[1].path)
loc_key = self.config.parser.find_dir(
"sslcertificateKeyfile", "example/key.pem", self.vh_truth[1].path)
# Verify one directive was found in the correct file
self.assertEqual(len(loc_cert), 1)
self.assertEqual(
apache_util.get_file_path(loc_cert[0]),
self.vh_truth[1].filep)
self.assertEqual(len(loc_key), 1)
self.assertEqual(
apache_util.get_file_path(loc_key[0]),
self.vh_truth[1].filep)
def test_deploy_cert_newssl_no_fullchain(self):
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir,
self.work_dir, version=(2, 4, 16))
self.config = self.mock_deploy_cert(self.config)
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
# Get the default 443 vhost
self.config.assoc["random.demo"] = self.vh_truth[1]
self.assertRaises(errors.PluginError,
lambda: self.config.deploy_cert(
"random.demo", "example/cert.pem",
"example/key.pem"))
def test_deploy_cert_old_apache_no_chain(self):
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir,
self.work_dir, version=(2, 4, 7))
self.config = self.mock_deploy_cert(self.config)
self.config.parser.modules.add("ssl_module")
self.config.parser.modules.add("mod_ssl.c")
# Get the default 443 vhost
self.config.assoc["random.demo"] = self.vh_truth[1]
self.assertRaises(errors.PluginError,
lambda: self.config.deploy_cert(
"random.demo", "example/cert.pem",
"example/key.pem"))
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
def test_ocsp_stapling_enable_mod(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c")
self.config.get_version = mock.Mock(return_value=(2, 4, 7))
mock_exe.return_value = True
self.config.enhance("certbot.demo", "staple-ocsp")
self.assertTrue("socache_shmcb_module" in self.config.parser.modules)
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
def test_ensure_http_header_enable_mod(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock()
self.config.parser.modules.add("mod_ssl.c")
mock_exe.return_value = True
# This will create an ssl vhost for certbot.demo
self.config.enhance("certbot.demo", "ensure-http-header",
"Strict-Transport-Security")
self.assertTrue("headers_module" in self.config.parser.modules)
@mock.patch("certbot.util.run_script")
@mock.patch("certbot.util.exe_exists")
def test_redirect_enable_mod(self, mock_exe, _):
self.config.parser.update_runtime_variables = mock.Mock()
mock_exe.return_value = True
self.config.get_version = mock.Mock(return_value=(2, 2))
# This will create an ssl vhost for certbot.demo
self.config.enhance("certbot.demo", "redirect")
self.assertTrue("rewrite_module" in self.config.parser.modules)
def test_enable_site_already_enabled(self):
self.assertTrue(self.vh_truth[1].enabled)
self.config.enable_site(self.vh_truth[1])
def test_enable_site_call_parent(self):
with mock.patch(
"certbot_apache.configurator.ApacheConfigurator.enable_site") as e_s:
self.config.parser.root = "/tmp/nonexistent"
vh = self.vh_truth[0]
vh.enabled = False
self.config.enable_site(vh)
self.assertTrue(e_s.called)
@mock.patch("certbot.util.exe_exists")
def test_enable_mod_no_disable(self, mock_exe_exists):
mock_exe_exists.return_value = False
self.assertRaises(
errors.MisconfigurationError, self.config.enable_mod, "ssl")
if __name__ == "__main__":
unittest.main() # pragma: no cover

View File

@@ -0,0 +1,41 @@
"""Test for certbot_apache.entrypoint for override class resolution"""
import unittest
import mock
from certbot_apache import configurator
from certbot_apache import entrypoint
class EntryPointTest(unittest.TestCase):
"""Entrypoint tests"""
_multiprocess_can_split_ = True
def test_get_configurator(self):
with mock.patch("certbot.util.get_os_info") as mock_info:
for distro in entrypoint.OVERRIDE_CLASSES.keys():
mock_info.return_value = (distro, "whatever")
self.assertEqual(entrypoint.get_configurator(),
entrypoint.OVERRIDE_CLASSES[distro])
def test_nonexistent_like(self):
with mock.patch("certbot.util.get_os_info") as mock_info:
mock_info.return_value = ("nonexistent", "irrelevant")
with mock.patch("certbot.util.get_systemd_os_like") as mock_like:
for like in entrypoint.OVERRIDE_CLASSES.keys():
mock_like.return_value = [like]
self.assertEqual(entrypoint.get_configurator(),
entrypoint.OVERRIDE_CLASSES[like])
def test_nonexistent_generic(self):
with mock.patch("certbot.util.get_os_info") as mock_info:
mock_info.return_value = ("nonexistent", "irrelevant")
with mock.patch("certbot.util.get_systemd_os_like") as mock_like:
mock_like.return_value = ["unknonwn"]
self.assertEqual(entrypoint.get_configurator(),
configurator.ApacheConfigurator)
if __name__ == "__main__":
unittest.main() # pragma: no cover

View File

@@ -0,0 +1,86 @@
"""Test for certbot_apache.configurator for Gentoo overrides"""
import os
import unittest
from certbot_apache import override_gentoo
from certbot_apache import obj
from certbot_apache.tests import util
def get_vh_truth(temp_dir, config_name):
"""Return the ground truth for the specified directory."""
prefix = os.path.join(
temp_dir, config_name, "apache2/vhosts.d")
aug_pre = "/files" + prefix
vh_truth = [
obj.VirtualHost(
os.path.join(prefix, "gentoo.example.com.conf"),
os.path.join(aug_pre, "gentoo.example.com.conf/VirtualHost"),
set([obj.Addr.fromstring("*:80")]),
False, True, "gentoo.example.com"),
obj.VirtualHost(
os.path.join(prefix, "00_default_vhost.conf"),
os.path.join(aug_pre, "00_default_vhost.conf/IfDefine/VirtualHost"),
set([obj.Addr.fromstring("*:80")]),
False, True, "localhost"),
obj.VirtualHost(
os.path.join(prefix, "00_default_ssl_vhost.conf"),
os.path.join(aug_pre,
"00_default_ssl_vhost.conf" +
"/IfDefine/IfDefine/IfModule/VirtualHost"),
set([obj.Addr.fromstring("_default_:443")]),
True, True, "localhost")
]
return vh_truth
class MultipleVhostsTestGentoo(util.ApacheTest):
"""Multiple vhost tests for non-debian distro"""
_multiprocess_can_split_ = True
def setUp(self): # pylint: disable=arguments-differ
test_dir = "gentoo_apache/apache"
config_root = "gentoo_apache/apache/apache2"
vhost_root = "gentoo_apache/apache/apache2/vhosts.d"
super(MultipleVhostsTestGentoo, self).setUp(test_dir=test_dir,
config_root=config_root,
vhost_root=vhost_root)
self.config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir, self.work_dir,
os_info="gentoo")
self.vh_truth = get_vh_truth(
self.temp_dir, "gentoo_apache/apache")
def test_get_parser(self):
self.assertTrue(isinstance(self.config.parser,
override_gentoo.GentooParser))
def test_get_virtual_hosts(self):
"""Make sure all vhosts are being properly found."""
vhs = self.config.get_virtual_hosts()
self.assertEqual(len(vhs), 3)
found = 0
for vhost in vhs:
for gentoo_truth in self.vh_truth:
if vhost == gentoo_truth:
found += 1
break
else:
raise Exception("Missed: %s" % vhost) # pragma: no cover
self.assertEqual(found, 3)
def test_get_sysconfig_vars(self):
"""Make sure we read the Gentoo APACHE2_OPTS variable correctly"""
defines = ['DEFAULT_VHOST', 'INFO',
'SSL', 'SSL_DEFAULT_VHOST', 'LANGUAGE']
self.config.parser.apacheconfig_filep = os.path.realpath(
os.path.join(self.config.parser.root, "../conf.d/apache2"))
self.config.parser.variables = {}
self.config.parser.update_runtime_variables()
for define in defines:
self.assertTrue(define in self.config.parser.variables.keys())
if __name__ == "__main__":
unittest.main() # pragma: no cover

View File

@@ -120,17 +120,18 @@ class BasicParserTest(util.ParserTest):
@mock.patch("certbot_apache.parser.ApacheParser.find_dir")
@mock.patch("certbot_apache.parser.ApacheParser.get_arg")
def test_init_modules_bad_syntax(self, mock_arg, mock_find):
def test_parse_modules_bad_syntax(self, mock_arg, mock_find):
mock_find.return_value = ["1", "2", "3", "4", "5", "6", "7", "8"]
mock_arg.return_value = None
with mock.patch("certbot_apache.parser.logger") as mock_logger:
self.parser.init_modules()
self.parser.parse_modules()
# Make sure that we got None return value and logged the file
self.assertTrue(mock_logger.debug.called)
@mock.patch("certbot_apache.parser.ApacheParser.find_dir")
@mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg")
def test_update_runtime_variables(self, mock_cfg):
mock_cfg.return_value = (
def test_update_runtime_variables(self, mock_cfg, _):
define_val = (
'ServerRoot: "/etc/apache2"\n'
'Main DocumentRoot: "/var/www"\n'
'Main ErrorLog: "/var/log/apache2/error.log"\n'
@@ -147,11 +148,113 @@ class BasicParserTest(util.ParserTest):
'User: name="www-data" id=33 not_used\n'
'Group: name="www-data" id=33 not_used\n'
)
inc_val = (
'Included configuration files:\n'
' (*) /etc/apache2/apache2.conf\n'
' (146) /etc/apache2/mods-enabled/access_compat.load\n'
' (146) /etc/apache2/mods-enabled/alias.load\n'
' (146) /etc/apache2/mods-enabled/auth_basic.load\n'
' (146) /etc/apache2/mods-enabled/authn_core.load\n'
' (146) /etc/apache2/mods-enabled/authn_file.load\n'
' (146) /etc/apache2/mods-enabled/authz_core.load\n'
' (146) /etc/apache2/mods-enabled/authz_host.load\n'
' (146) /etc/apache2/mods-enabled/authz_user.load\n'
' (146) /etc/apache2/mods-enabled/autoindex.load\n'
' (146) /etc/apache2/mods-enabled/deflate.load\n'
' (146) /etc/apache2/mods-enabled/dir.load\n'
' (146) /etc/apache2/mods-enabled/env.load\n'
' (146) /etc/apache2/mods-enabled/filter.load\n'
' (146) /etc/apache2/mods-enabled/mime.load\n'
' (146) /etc/apache2/mods-enabled/mpm_event.load\n'
' (146) /etc/apache2/mods-enabled/negotiation.load\n'
' (146) /etc/apache2/mods-enabled/reqtimeout.load\n'
' (146) /etc/apache2/mods-enabled/setenvif.load\n'
' (146) /etc/apache2/mods-enabled/socache_shmcb.load\n'
' (146) /etc/apache2/mods-enabled/ssl.load\n'
' (146) /etc/apache2/mods-enabled/status.load\n'
' (147) /etc/apache2/mods-enabled/alias.conf\n'
' (147) /etc/apache2/mods-enabled/autoindex.conf\n'
' (147) /etc/apache2/mods-enabled/deflate.conf\n'
)
mod_val = (
'Loaded Modules:\n'
' core_module (static)\n'
' so_module (static)\n'
' watchdog_module (static)\n'
' http_module (static)\n'
' log_config_module (static)\n'
' logio_module (static)\n'
' version_module (static)\n'
' unixd_module (static)\n'
' access_compat_module (shared)\n'
' alias_module (shared)\n'
' auth_basic_module (shared)\n'
' authn_core_module (shared)\n'
' authn_file_module (shared)\n'
' authz_core_module (shared)\n'
' authz_host_module (shared)\n'
' authz_user_module (shared)\n'
' autoindex_module (shared)\n'
' deflate_module (shared)\n'
' dir_module (shared)\n'
' env_module (shared)\n'
' filter_module (shared)\n'
' mime_module (shared)\n'
' mpm_event_module (shared)\n'
' negotiation_module (shared)\n'
' reqtimeout_module (shared)\n'
' setenvif_module (shared)\n'
' socache_shmcb_module (shared)\n'
' ssl_module (shared)\n'
' status_module (shared)\n'
)
def mock_get_vars(cmd):
"""Mock command output"""
if cmd[-1] == "DUMP_RUN_CFG":
return define_val
elif cmd[-1] == "DUMP_INCLUDES":
return inc_val
elif cmd[-1] == "DUMP_MODULES":
return mod_val
mock_cfg.side_effect = mock_get_vars
expected_vars = {"TEST": "", "U_MICH": "", "TLS": "443",
"example_path": "Documents/path"}
self.parser.update_runtime_variables()
self.assertEqual(self.parser.variables, expected_vars)
self.parser.modules = set()
with mock.patch(
"certbot_apache.parser.ApacheParser.parse_file") as mock_parse:
self.parser.update_runtime_variables()
self.assertEqual(self.parser.variables, expected_vars)
self.assertEqual(len(self.parser.modules), 58)
# None of the includes in inc_val should be in parsed paths.
# Make sure we tried to include them all.
self.assertEqual(mock_parse.call_count, 25)
@mock.patch("certbot_apache.parser.ApacheParser.find_dir")
@mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg")
def test_update_runtime_variables_alt_values(self, mock_cfg, _):
inc_val = (
'Included configuration files:\n'
' (*) {0}\n'
' (146) /etc/apache2/mods-enabled/access_compat.load\n'
' (146) {1}/mods-enabled/alias.load\n'
).format(self.parser.loc["root"],
os.path.dirname(self.parser.loc["root"]))
mock_cfg.return_value = inc_val
self.parser.modules = set()
with mock.patch(
"certbot_apache.parser.ApacheParser.parse_file") as mock_parse:
self.parser.update_runtime_variables()
# No matching modules should have been found
self.assertEqual(len(self.parser.modules), 0)
# Only one of the three includes do not exist in already parsed
# path derived from root configuration Include statements
self.assertEqual(mock_parse.call_count, 1)
@mock.patch("certbot_apache.parser.ApacheParser._get_runtime_cfg")
def test_update_runtime_vars_bad_output(self, mock_cfg):
@@ -162,7 +265,7 @@ class BasicParserTest(util.ParserTest):
self.assertRaises(
errors.PluginError, self.parser.update_runtime_variables)
@mock.patch("certbot_apache.constants.os_constant")
@mock.patch("certbot_apache.configurator.ApacheConfigurator.constant")
@mock.patch("certbot_apache.parser.subprocess.Popen")
def test_update_runtime_vars_bad_ctl(self, mock_popen, mock_const):
mock_popen.side_effect = OSError
@@ -198,7 +301,7 @@ class ParserInitTest(util.ApacheTest):
self.assertRaises(
errors.PluginError,
ApacheParser, self.aug, os.path.relpath(self.config_path),
"/dummy/vhostpath", version=(2, 2, 22))
"/dummy/vhostpath", version=(2, 2, 22), configurator=self.config)
def test_root_normalized(self):
from certbot_apache.parser import ApacheParser
@@ -210,7 +313,7 @@ class ParserInitTest(util.ApacheTest):
"debian_apache_2_4/////multiple_vhosts/../multiple_vhosts/apache2")
parser = ApacheParser(self.aug, path,
"/dummy/vhostpath")
"/dummy/vhostpath", configurator=self.config)
self.assertEqual(parser.root, self.config_path)
@@ -220,7 +323,7 @@ class ParserInitTest(util.ApacheTest):
"update_runtime_variables"):
parser = ApacheParser(
self.aug, os.path.relpath(self.config_path),
"/dummy/vhostpath")
"/dummy/vhostpath", configurator=self.config)
self.assertEqual(parser.root, self.config_path)
@@ -230,7 +333,7 @@ class ParserInitTest(util.ApacheTest):
"update_runtime_variables"):
parser = ApacheParser(
self.aug, self.config_path + os.path.sep,
"/dummy/vhostpath")
"/dummy/vhostpath", configurator=self.config)
self.assertEqual(parser.root, self.config_path)

View File

@@ -0,0 +1,9 @@
This directory holds configuration files for the Apache HTTP Server;
any files in this directory which have the ".conf" extension will be
processed as httpd configuration files. The directory is used in
addition to the directory /etc/httpd/conf.modules.d/, which contains
configuration files necessary to load modules.
Files are processed in alphabetical order.

View File

@@ -0,0 +1,94 @@
#
# Directives controlling the display of server-generated directory listings.
#
# Required modules: mod_authz_core, mod_authz_host,
# mod_autoindex, mod_alias
#
# To see the listing of a directory, the Options directive for the
# directory must include "Indexes", and the directory must not contain
# a file matching those listed in the DirectoryIndex directive.
#
#
# IndexOptions: Controls the appearance of server-generated directory
# listings.
#
IndexOptions FancyIndexing HTMLTable VersionSort
# We include the /icons/ alias for FancyIndexed directory listings. If
# you do not use FancyIndexing, you may comment this out.
#
Alias /icons/ "/usr/share/httpd/icons/"
<Directory "/usr/share/httpd/icons">
Options Indexes MultiViews FollowSymlinks
AllowOverride None
Require all granted
</Directory>
#
# AddIcon* directives tell the server which icon to show for different
# files or filename extensions. These are only displayed for
# FancyIndexed directories.
#
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*
AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif /core
AddIcon /icons/bomb.gif */core.*
AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^
#
# DefaultIcon is which icon to show for files which do not have an icon
# explicitly set.
#
DefaultIcon /icons/unknown.gif
#
# AddDescription allows you to place a short description after a file in
# server-generated indexes. These are only displayed for FancyIndexed
# directories.
# Format: AddDescription "description" filename
#
#AddDescription "GZIP compressed document" .gz
#AddDescription "tar archive" .tar
#AddDescription "GZIP compressed tar archive" .tgz
#
# ReadmeName is the name of the README file the server will look for by
# default, and append to directory listings.
#
# HeaderName is the name of a file which should be prepended to
# directory indexes.
ReadmeName README.html
HeaderName HEADER.html
#
# IndexIgnore is a set of filenames which directory indexing should ignore
# and not include in the listing. Shell-style wildcarding is permitted.
#
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t

View File

@@ -0,0 +1,7 @@
<VirtualHost *:80>
ServerName centos.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

View File

@@ -0,0 +1,211 @@
#
# When we also provide SSL we have to listen to the
# the HTTPS port in addition.
#
Listen 443 https
##
## SSL Global Context
##
## All SSL configuration in this context applies both to
## the main server and all SSL-enabled virtual hosts.
##
# Pass Phrase Dialog:
# Configure the pass phrase gathering process.
# The filtering dialog program (`builtin' is a internal
# terminal dialog) has to provide the pass phrase on stdout.
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
# Inter-Process Session Cache:
# Configure the SSL Session Cache: First the mechanism
# to use and second the expiring timeout (in seconds).
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
# Pseudo Random Number Generator (PRNG):
# Configure one or more sources to seed the PRNG of the
# SSL library. The seed data should be of good random quality.
# WARNING! On some platforms /dev/random blocks if not enough entropy
# is available. This means you then cannot use the /dev/random device
# because it would lead to very long connection times (as long as
# it requires to make more entropy available). But usually those
# platforms additionally provide a /dev/urandom device which doesn't
# block. So, if available, use this one instead. Read the mod_ssl User
# Manual for more details.
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
#SSLRandomSeed startup file:/dev/random 512
#SSLRandomSeed connect file:/dev/random 512
#SSLRandomSeed connect file:/dev/urandom 512
#
# Use "SSLCryptoDevice" to enable any supported hardware
# accelerators. Use "openssl engine -v" to list supported
# engine names. NOTE: If you enable an accelerator and the
# server does not start, consult the error logs and ensure
# your accelerator is functioning properly.
#
SSLCryptoDevice builtin
#SSLCryptoDevice ubsec
##
## SSL Virtual Host Context
##
<VirtualHost _default_:443>
# General setup for the virtual host, inherited from global configuration
#DocumentRoot "/var/www/html"
#ServerName www.example.com:443
# Use separate log files for the SSL virtual host; note that LogLevel
# is not inherited from httpd.conf.
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect. Disable SSLv2 access by default:
SSLProtocol all -SSLv2
# SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA
# Speed-optimized SSL Cipher configuration:
# If speed is your main concern (on busy HTTPS servers e.g.),
# you might want to force clients to specific, performance
# optimized ciphers. In this case, prepend those ciphers
# to the SSLCipherSuite list, and enable SSLHonorCipherOrder.
# Caveat: by giving precedence to RC4-SHA and AES128-SHA
# (as in the example below), most connections will no longer
# have perfect forward secrecy - if the server's key is
# compromised, captures of past or future traffic must be
# considered compromised, too.
#SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:MEDIUM:!aNULL:!MD5
#SSLHonorCipherOrder on
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
# pass phrase. Note that a kill -HUP will prompt again. A new
# certificate can be generated using the genkey(1) command.
# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you've both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
# concatenation of PEM encoded CA certificates which form the
# certificate chain for the server certificate. Alternatively
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# certificates for client authentication or alternatively one
# huge file containing all of them (file must be PEM encoded)
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth 10
# Access Control:
# With SSLRequire you can do per-directory access control based
# on arbitrary complex boolean expressions containing server
# variable checks and other lookup directives. The syntax is a
# mixture between C and Perl. See the mod_ssl documentation
# for more details.
#<Location />
#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#</Location>
# SSL Engine Options:
# Set various options for the SSL engine.
# o FakeBasicAuth:
# Translate the client X.509 into a Basic Authorisation. This means that
# the standard Auth/DBMAuth methods can be used for access control. The
# user name is the `one line' version of the client's X.509 certificate.
# Note that no password is obtained from the user. Every entry in the user
# file needs this password: `xxj31ZMTZzkVA'.
# o ExportCertData:
# This exports two additional environment variables: SSL_CLIENT_CERT and
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
# server (always existing) and the client (only existing when client
# authentication is used). This can be used to import the certificates
# into CGI scripts.
# o StdEnvVars:
# This exports the standard SSL/TLS related `SSL_*' environment variables.
# Per default this exportation is switched off for performance reasons,
# because the extraction step is an expensive operation and is usually
# useless for serving static content. So one usually enables the
# exportation for CGI and SSI requests only.
# o StrictRequire:
# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
# under a "Satisfy any" situation, i.e. when it applies access is denied
# and no other module can change it.
# o OptRenegotiate:
# This enables optimized SSL connection renegotiation handling when SSL
# directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
# SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant shutdown
# approach is that mod_ssl sends the close notify alert but doesn't wait for
# the close notify alert from client. When you need a different shutdown
# approach you can use one of the following variables:
# o ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is closed, i.e. no
# SSL close notify alert is send or allowed to received. This violates
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
# this when you receive I/O errors because of the standard approach where
# mod_ssl sends the close notify alert.
# o ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection is closed, i.e. a
# SSL close notify alert is send and mod_ssl waits for the close notify
# alert of the client. This is 100% SSL/TLS standard compliant, but in
# practice often causes hanging connections with brain-dead browsers. Use
# this only for browsers where you know that their SSL implementation
# works correctly.
# Notice: Most problems of broken clients are also related to the HTTP
# keep-alive facility, so you usually additionally want to disable
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
# "force-response-1.0" for this.
BrowserMatch "MSIE [2-5]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
# Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a
# compact non-error SSL logfile on a virtual host basis.
CustomLog logs/ssl_request_log "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

View File

@@ -0,0 +1,36 @@
#
# UserDir: The name of the directory that is appended onto a user's home
# directory if a ~user request is received.
#
# The path to the end user account 'public_html' directory must be
# accessible to the webserver userid. This usually means that ~userid
# must have permissions of 711, ~userid/public_html must have permissions
# of 755, and documents contained therein must be world-readable.
# Otherwise, the client will only receive a "403 Forbidden" message.
#
<IfModule mod_userdir.c>
#
# UserDir is disabled by default since it can confirm the presence
# of a username on the system (depending on home directory
# permissions).
#
UserDir disabled
#
# To enable requests to /~user/ to serve the user's public_html
# directory, remove the "UserDir disabled" line above, and uncomment
# the following line instead:
#
#UserDir public_html
</IfModule>
#
# Control access to UserDir directories. The following is an example
# for a site where these directories are restricted to read-only.
#
<Directory "/home/*/public_html">
AllowOverride FileInfo AuthConfig Limit Indexes
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
Require method GET POST OPTIONS
</Directory>

View File

@@ -0,0 +1,22 @@
#
# This configuration file enables the default "Welcome" page if there
# is no default index page present for the root URL. To disable the
# Welcome page, comment out all the lines below.
#
# NOTE: if this file is removed, it will be restored on upgrades.
#
<LocationMatch "^/+$">
Options -Indexes
ErrorDocument 403 /.noindex.html
</LocationMatch>
<Directory /usr/share/httpd/noindex>
AllowOverride None
Require all granted
</Directory>
Alias /.noindex.html /usr/share/httpd/noindex/index.html
Alias /noindex/css/bootstrap.min.css /usr/share/httpd/noindex/css/bootstrap.min.css
Alias /noindex/css/open-sans.css /usr/share/httpd/noindex/css/open-sans.css
Alias /images/apache_pb.gif /usr/share/httpd/noindex/images/apache_pb.gif
Alias /images/poweredby.png /usr/share/httpd/noindex/images/poweredby.png

View File

@@ -0,0 +1,77 @@
#
# This file loads most of the modules included with the Apache HTTP
# Server itself.
#
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule allowmethods_module modules/mod_allowmethods.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_anon_module modules/mod_authn_anon.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authn_dbd_module modules/mod_authn_dbd.so
LoadModule authn_dbm_module modules/mod_authn_dbm.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_socache_module modules/mod_authn_socache.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_dbd_module modules/mod_authz_dbd.so
LoadModule authz_dbm_module modules/mod_authz_dbm.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_owner_module modules/mod_authz_owner.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
LoadModule data_module modules/mod_data.so
LoadModule dbd_module modules/mod_dbd.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule dir_module modules/mod_dir.so
LoadModule dumpio_module modules/mod_dumpio.so
LoadModule echo_module modules/mod_echo.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
LoadModule ext_filter_module modules/mod_ext_filter.so
LoadModule filter_module modules/mod_filter.so
LoadModule headers_module modules/mod_headers.so
LoadModule include_module modules/mod_include.so
LoadModule info_module modules/mod_info.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule mime_module modules/mod_mime.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule remoteip_module modules/mod_remoteip.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule slotmem_plain_module modules/mod_slotmem_plain.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule socache_dbm_module modules/mod_socache_dbm.so
LoadModule socache_memcache_module modules/mod_socache_memcache.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule status_module modules/mod_status.so
LoadModule substitute_module modules/mod_substitute.so
LoadModule suexec_module modules/mod_suexec.so
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule userdir_module modules/mod_userdir.so
LoadModule version_module modules/mod_version.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
#LoadModule buffer_module modules/mod_buffer.so
#LoadModule watchdog_module modules/mod_watchdog.so
#LoadModule heartbeat_module modules/mod_heartbeat.so
#LoadModule heartmonitor_module modules/mod_heartmonitor.so
#LoadModule usertrack_module modules/mod_usertrack.so
#LoadModule dialup_module modules/mod_dialup.so
#LoadModule charset_lite_module modules/mod_charset_lite.so
#LoadModule log_debug_module modules/mod_log_debug.so
#LoadModule ratelimit_module modules/mod_ratelimit.so
#LoadModule reflector_module modules/mod_reflector.so
#LoadModule request_module modules/mod_request.so
#LoadModule sed_module modules/mod_sed.so
#LoadModule speling_module modules/mod_speling.so

View File

@@ -0,0 +1,3 @@
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule dav_lock_module modules/mod_dav_lock.so

View File

@@ -0,0 +1 @@
LoadModule lua_module modules/mod_lua.so

View File

@@ -0,0 +1,19 @@
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:
# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so

View File

@@ -0,0 +1,16 @@
# This file configures all the proxy modules:
LoadModule proxy_module modules/mod_proxy.so
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

View File

@@ -0,0 +1 @@
LoadModule ssl_module modules/mod_ssl.so

View File

@@ -0,0 +1,2 @@
# This file configures systemd module:
LoadModule systemd_module modules/mod_systemd.so

View File

@@ -0,0 +1,14 @@
# This configuration file loads a CGI module appropriate to the MPM
# which has been configured in 00-mpm.conf. mod_cgid should be used
# with a threaded MPM; mod_cgi with the prefork MPM.
<IfModule mpm_worker_module>
LoadModule cgid_module modules/mod_cgid.so
</IfModule>
<IfModule mpm_event_module>
LoadModule cgid_module modules/mod_cgid.so
</IfModule>
<IfModule mpm_prefork_module>
LoadModule cgi_module modules/mod_cgi.so
</IfModule>

View File

@@ -0,0 +1,353 @@
#
# This is the main Apache HTTP server configuration file. It contains the
# configuration directives that give the server its instructions.
# See <URL:http://httpd.apache.org/docs/2.4/> for detailed information.
# In particular, see
# <URL:http://httpd.apache.org/docs/2.4/mod/directives.html>
# for a discussion of each configuration directive.
#
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
#
# Configuration and logfile names: If the filenames you specify for many
# of the server's control files begin with "/" (or "drive:/" for Win32), the
# server will use that explicit path. If the filenames do *not* begin
# with "/", the value of ServerRoot is prepended -- so 'log/access_log'
# with ServerRoot set to '/www' will be interpreted by the
# server as '/www/log/access_log', where as '/log/access_log' will be
# interpreted as '/log/access_log'.
#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# Do not add a slash at the end of the directory path. If you point
# ServerRoot at a non-local disk, be sure to specify a local disk on the
# Mutex directive, if file-based mutexes are used. If you wish to share the
# same ServerRoot for multiple httpd daemons, you will need to change at
# least PidFile.
#
ServerRoot "/etc/httpd"
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80
#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so
#
Include conf.modules.d/*.conf
#
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User apache
Group apache
# 'Main' server configuration
#
# The directives in this section set up the values used by the 'main'
# server, which responds to any requests that aren't handled by a
# <VirtualHost> definition. These values also provide defaults for
# any <VirtualHost> containers you may define later in the file.
#
# All of these directives may appear inside <VirtualHost> containers,
# in which case these default settings will be overridden for the
# virtual host being defined.
#
#
# ServerAdmin: Your address, where problems with the server should be
# e-mailed. This address appears on some server-generated pages, such
# as error documents. e.g. admin@your-domain.com
#
ServerAdmin root@localhost
#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
#ServerName www.example.com:80
#
# Deny access to the entirety of your server's filesystem. You must
# explicitly permit access to web content directories in other
# <Directory> blocks below.
#
<Directory />
AllowOverride none
Require all denied
</Directory>
#
# Note that from this point forward you must specifically allow
# particular features to be enabled - so if something's not working as
# you might expect, make sure that you have specifically enabled it
# below.
#
#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "/var/www/html"
#
# Relax access to content within /var/www.
#
<Directory "/var/www">
AllowOverride None
# Allow open access:
Require all granted
</Directory>
# Further relax access to the default document root:
<Directory "/var/www/html">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.4/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride None
#
# Controls who can get stuff from this server.
#
Require all granted
</Directory>
#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<Files ".ht*">
Require all denied
</Files>
#
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog "logs/error_log"
#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel warn
<IfModule log_config_module>
#
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
#
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
# You need to enable mod_logio.c to use %I and %O
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
#
# The location and format of the access logfile (Common Logfile Format).
# If you do not define any access logfiles within a <VirtualHost>
# container, they will be logged here. Contrariwise, if you *do*
# define per-<VirtualHost> access logfiles, transactions will be
# logged therein and *not* in this file.
#
#CustomLog "logs/access_log" common
#
# If you prefer a logfile with access, agent, and referer information
# (Combined Logfile Format) you can use the following directive.
#
CustomLog "logs/access_log" combined
</IfModule>
<IfModule alias_module>
#
# Redirect: Allows you to tell clients about documents that used to
# exist in your server's namespace, but do not anymore. The client
# will make a new request for the document at its new location.
# Example:
# Redirect permanent /foo http://www.example.com/bar
#
# Alias: Maps web paths into filesystem paths and is used to
# access content that does not live under the DocumentRoot.
# Example:
# Alias /webpath /full/filesystem/path
#
# If you include a trailing / on /webpath then the server will
# require it to be present in the URL. You will also likely
# need to provide a <Directory> section to allow access to
# the filesystem path.
#
# ScriptAlias: This controls which directories contain server scripts.
# ScriptAliases are essentially the same as Aliases, except that
# documents in the target directory are treated as applications and
# run by the server when requested rather than as documents sent to the
# client. The same rules about trailing "/" apply to ScriptAlias
# directives as to Alias.
#
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
#
# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased
# CGI directory exists, if you have that configured.
#
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
<IfModule mime_module>
#
# TypesConfig points to the file containing the list of mappings from
# filename extension to MIME-type.
#
TypesConfig /etc/mime.types
#
# AddType allows you to add to or override the MIME configuration
# file specified in TypesConfig for specific file types.
#
#AddType application/x-gzip .tgz
#
# AddEncoding allows you to have certain browsers uncompress
# information on the fly. Note: Not all browsers support this.
#
#AddEncoding x-compress .Z
#AddEncoding x-gzip .gz .tgz
#
# If the AddEncoding directives above are commented-out, then you
# probably should define those extensions to indicate media types:
#
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
#
# AddHandler allows you to map certain file extensions to "handlers":
# actions unrelated to filetype. These can be either built into the server
# or added with the Action directive (see below)
#
# To use CGI scripts outside of ScriptAliased directories:
# (You will also need to add "ExecCGI" to the "Options" directive.)
#
#AddHandler cgi-script .cgi
# For type maps (negotiated resources):
#AddHandler type-map var
#
# Filters allow you to process content before it is sent to the client.
#
# To parse .shtml files for server-side includes (SSI):
# (You will also need to add "Includes" to the "Options" directive.)
#
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
</IfModule>
#
# Specify a default charset for all content served; this enables
# interpretation of all content as UTF-8 by default. To use the
# default browser choice (ISO-8859-1), or to allow the META tags
# in HTML content to override this choice, comment out this
# directive:
#
AddDefaultCharset UTF-8
<IfModule mime_magic_module>
#
# The mod_mime_magic module allows the server to use various hints from the
# contents of the file itself to determine its type. The MIMEMagicFile
# directive tells the module where the hint definitions are located.
#
MIMEMagicFile conf/magic
</IfModule>
#
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
#
# Some examples:
#ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
#
#
# EnableMMAP and EnableSendfile: On systems that support it,
# memory-mapping or the sendfile syscall may be used to deliver
# files. This usually improves server performance, but must
# be turned off when serving from networked-mounted
# filesystems or if support for these functions is otherwise
# broken on your system.
# Defaults if commented: EnableMMAP On, EnableSendfile Off
#
#EnableMMAP off
EnableSendfile on
# Supplemental configuration
#
# Load config files in the "/etc/httpd/conf.d" directory, if any.
IncludeOptional conf.d/*.conf

View File

@@ -0,0 +1,385 @@
# Magic data for mod_mime_magic Apache module (originally for file(1) command)
# The module is described in /manual/mod/mod_mime_magic.html
#
# The format is 4-5 columns:
# Column #1: byte number to begin checking from, ">" indicates continuation
# Column #2: type of data to match
# Column #3: contents of data to match
# Column #4: MIME type of result
# Column #5: MIME encoding of result (optional)
#------------------------------------------------------------------------------
# Localstuff: file(1) magic for locally observed files
# Add any locally observed files here.
#------------------------------------------------------------------------------
# end local stuff
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Java
0 short 0xcafe
>2 short 0xbabe application/java
#------------------------------------------------------------------------------
# audio: file(1) magic for sound formats
#
# from Jan Nicolai Langfeldt <janl@ifi.uio.no>,
#
# Sun/NeXT audio data
0 string .snd
>12 belong 1 audio/basic
>12 belong 2 audio/basic
>12 belong 3 audio/basic
>12 belong 4 audio/basic
>12 belong 5 audio/basic
>12 belong 6 audio/basic
>12 belong 7 audio/basic
>12 belong 23 audio/x-adpcm
# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format
# that uses little-endian encoding and has a different magic number
# (0x0064732E in little-endian encoding).
0 lelong 0x0064732E
>12 lelong 1 audio/x-dec-basic
>12 lelong 2 audio/x-dec-basic
>12 lelong 3 audio/x-dec-basic
>12 lelong 4 audio/x-dec-basic
>12 lelong 5 audio/x-dec-basic
>12 lelong 6 audio/x-dec-basic
>12 lelong 7 audio/x-dec-basic
# compressed (G.721 ADPCM)
>12 lelong 23 audio/x-dec-adpcm
# Bytes 0-3 of AIFF, AIFF-C, & 8SVX audio files are "FORM"
# AIFF audio data
8 string AIFF audio/x-aiff
# AIFF-C audio data
8 string AIFC audio/x-aiff
# IFF/8SVX audio data
8 string 8SVX audio/x-aiff
# Creative Labs AUDIO stuff
# Standard MIDI data
0 string MThd audio/unknown
#>9 byte >0 (format %d)
#>11 byte >1 using %d channels
# Creative Music (CMF) data
0 string CTMF audio/unknown
# SoundBlaster instrument data
0 string SBI audio/unknown
# Creative Labs voice data
0 string Creative\ Voice\ File audio/unknown
## is this next line right? it came this way...
#>19 byte 0x1A
#>23 byte >0 - version %d
#>22 byte >0 \b.%d
# [GRR 950115: is this also Creative Labs? Guessing that first line
# should be string instead of unknown-endian long...]
#0 long 0x4e54524b MultiTrack sound data
#0 string NTRK MultiTrack sound data
#>4 long x - version %ld
# Microsoft WAVE format (*.wav)
# [GRR 950115: probably all of the shorts and longs should be leshort/lelong]
# Microsoft RIFF
0 string RIFF audio/unknown
# - WAVE format
>8 string WAVE audio/x-wav
# MPEG audio.
0 beshort&0xfff0 0xfff0 audio/mpeg
# C64 SID Music files, from Linus Walleij <triad@df.lth.se>
0 string PSID audio/prs.sid
#------------------------------------------------------------------------------
# c-lang: file(1) magic for C programs or various scripts
#
# XPM icons (Greg Roelofs, newt@uchicago.edu)
# ideally should go into "images", but entries below would tag XPM as C source
0 string /*\ XPM image/x-xbm 7bit
# this first will upset you if you're a PL/1 shop... (are there any left?)
# in which case rm it; ascmagic will catch real C programs
# C or REXX program text
0 string /* text/plain
# C++ program text
0 string // text/plain
#------------------------------------------------------------------------------
# compress: file(1) magic for pure-compression formats (no archives)
#
# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, whap, etc.
#
# Formats for various forms of compressed data
# Formats for "compress" proper have been moved into "compress.c",
# because it tries to uncompress it to figure out what's inside.
# standard unix compress
0 string \037\235 application/octet-stream x-compress
# gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver)
0 string \037\213 application/octet-stream x-gzip
# According to gzip.h, this is the correct byte order for packed data.
0 string \037\036 application/octet-stream
#
# This magic number is byte-order-independent.
#
0 short 017437 application/octet-stream
# XXX - why *two* entries for "compacted data", one of which is
# byte-order independent, and one of which is byte-order dependent?
#
# compacted data
0 short 0x1fff application/octet-stream
0 string \377\037 application/octet-stream
# huf output
0 short 0145405 application/octet-stream
# Squeeze and Crunch...
# These numbers were gleaned from the Unix versions of the programs to
# handle these formats. Note that I can only uncrunch, not crunch, and
# I didn't have a crunched file handy, so the crunch number is untested.
# Keith Waclena <keith@cerberus.uchicago.edu>
#0 leshort 0x76FF squeezed data (CP/M, DOS)
#0 leshort 0x76FE crunched data (CP/M, DOS)
# Freeze
#0 string \037\237 Frozen file 2.1
#0 string \037\236 Frozen file 1.0 (or gzip 0.5)
# lzh?
#0 string \037\240 LZH compressed data
#------------------------------------------------------------------------------
# frame: file(1) magic for FrameMaker files
#
# This stuff came on a FrameMaker demo tape, most of which is
# copyright, but this file is "published" as witness the following:
#
0 string \<MakerFile application/x-frame
0 string \<MIFFile application/x-frame
0 string \<MakerDictionary application/x-frame
0 string \<MakerScreenFon application/x-frame
0 string \<MML application/x-frame
0 string \<Book application/x-frame
0 string \<Maker application/x-frame
#------------------------------------------------------------------------------
# html: file(1) magic for HTML (HyperText Markup Language) docs
#
# from Daniel Quinlan <quinlan@yggdrasil.com>
# and Anna Shergold <anna@inext.co.uk>
#
0 string \<!DOCTYPE\ HTML text/html
0 string \<!doctype\ html text/html
0 string \<HEAD text/html
0 string \<head text/html
0 string \<TITLE text/html
0 string \<title text/html
0 string \<html text/html
0 string \<HTML text/html
0 string \<!-- text/html
0 string \<h1 text/html
0 string \<H1 text/html
# XML eXtensible Markup Language, from Linus Walleij <triad@df.lth.se>
0 string \<?xml text/xml
#------------------------------------------------------------------------------
# images: file(1) magic for image formats (see also "c-lang" for XPM bitmaps)
#
# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
# additions by janl@ifi.uio.no as well as others. Jan also suggested
# merging several one- and two-line files into here.
#
# XXX - byte order for GIF and TIFF fields?
# [GRR: TIFF allows both byte orders; GIF is probably little-endian]
#
# [GRR: what the hell is this doing in here?]
#0 string xbtoa btoa'd file
# PBMPLUS
# PBM file
0 string P1 image/x-portable-bitmap 7bit
# PGM file
0 string P2 image/x-portable-greymap 7bit
# PPM file
0 string P3 image/x-portable-pixmap 7bit
# PBM "rawbits" file
0 string P4 image/x-portable-bitmap
# PGM "rawbits" file
0 string P5 image/x-portable-greymap
# PPM "rawbits" file
0 string P6 image/x-portable-pixmap
# NIFF (Navy Interchange File Format, a modification of TIFF)
# [GRR: this *must* go before TIFF]
0 string IIN1 image/x-niff
# TIFF and friends
# TIFF file, big-endian
0 string MM image/tiff
# TIFF file, little-endian
0 string II image/tiff
# possible GIF replacements; none yet released!
# (Greg Roelofs, newt@uchicago.edu)
#
# GRR 950115: this was mine ("Zip GIF"):
# ZIF image (GIF+deflate alpha)
0 string GIF94z image/unknown
#
# GRR 950115: this is Jeremy Wohl's Free Graphics Format (better):
# FGF image (GIF+deflate beta)
0 string FGF95a image/unknown
#
# GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal
# (best; not yet implemented):
# PBF image (deflate compression)
0 string PBF image/unknown
# GIF
0 string GIF image/gif
# JPEG images
0 beshort 0xffd8 image/jpeg
# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu)
0 string BM image/bmp
#>14 byte 12 (OS/2 1.x format)
#>14 byte 64 (OS/2 2.x format)
#>14 byte 40 (Windows 3.x format)
#0 string IC icon
#0 string PI pointer
#0 string CI color icon
#0 string CP color pointer
#0 string BA bitmap array
0 string \x89PNG image/png
0 string FWS application/x-shockwave-flash
0 string CWS application/x-shockwave-flash
#------------------------------------------------------------------------------
# lisp: file(1) magic for lisp programs
#
# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
0 string ;; text/plain 8bit
# Emacs 18 - this is always correct, but not very magical.
0 string \012( application/x-elc
# Emacs 19
0 string ;ELC\023\000\000\000 application/x-elc
#------------------------------------------------------------------------------
# mail.news: file(1) magic for mail and news
#
# There are tests to ascmagic.c to cope with mail and news.
0 string Relay-Version: message/rfc822 7bit
0 string #!\ rnews message/rfc822 7bit
0 string N#!\ rnews message/rfc822 7bit
0 string Forward\ to message/rfc822 7bit
0 string Pipe\ to message/rfc822 7bit
0 string Return-Path: message/rfc822 7bit
0 string Path: message/news 8bit
0 string Xref: message/news 8bit
0 string From: message/rfc822 7bit
0 string Article message/news 8bit
#------------------------------------------------------------------------------
# msword: file(1) magic for MS Word files
#
# Contributor claims:
# Reversed-engineered MS Word magic numbers
#
0 string \376\067\0\043 application/msword
0 string \333\245-\0\0\0 application/msword
# disable this one because it applies also to other
# Office/OLE documents for which msword is not correct. See PR#2608.
#0 string \320\317\021\340\241\261 application/msword
#------------------------------------------------------------------------------
# printer: file(1) magic for printer-formatted files
#
# PostScript
0 string %! application/postscript
0 string \004%! application/postscript
# Acrobat
# (due to clamen@cs.cmu.edu)
0 string %PDF- application/pdf
#------------------------------------------------------------------------------
# sc: file(1) magic for "sc" spreadsheet
#
38 string Spreadsheet application/x-sc
#------------------------------------------------------------------------------
# tex: file(1) magic for TeX files
#
# XXX - needs byte-endian stuff (big-endian and little-endian DVI?)
#
# From <conklin@talisman.kaleida.com>
# Although we may know the offset of certain text fields in TeX DVI
# and font files, we can't use them reliably because they are not
# zero terminated. [but we do anyway, christos]
0 string \367\002 application/x-dvi
#0 string \367\203 TeX generic font data
#0 string \367\131 TeX packed font data
#0 string \367\312 TeX virtual font data
#0 string This\ is\ TeX, TeX transcript text
#0 string This\ is\ METAFONT, METAFONT transcript text
# There is no way to detect TeX Font Metric (*.tfm) files without
# breaking them apart and reading the data. The following patterns
# match most *.tfm files generated by METAFONT or afm2tfm.
#2 string \000\021 TeX font metric data
#2 string \000\022 TeX font metric data
#>34 string >\0 (%s)
# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
#0 string \\input\ texinfo Texinfo source text
#0 string This\ is\ Info\ file GNU Info text
# correct TeX magic for Linux (and maybe more)
# from Peter Tobias (tobias@server.et-inf.fho-emden.de)
#
0 leshort 0x02f7 application/x-dvi
# RTF - Rich Text Format
0 string {\\rtf application/rtf
#------------------------------------------------------------------------------
# animation: file(1) magic for animation/movie formats
#
# animation formats, originally from vax@ccwf.cc.utexas.edu (VaX#n8)
# MPEG file
0 string \000\000\001\263 video/mpeg
#
# The contributor claims:
# I couldn't find a real magic number for these, however, this
# -appears- to work. Note that it might catch other files, too,
# so BE CAREFUL!
#
# Note that title and author appear in the two 20-byte chunks
# at decimal offsets 2 and 22, respectively, but they are XOR'ed with
# 255 (hex FF)! DL format SUCKS BIG ROCKS.
#
# DL file version 1 , medium format (160x100, 4 images/screen)
0 byte 1 video/unknown
0 byte 2 video/unknown
# Quicktime video, from Linus Walleij <triad@df.lth.se>
# from Apple quicktime file format documentation.
4 string moov video/quicktime
4 string mdat video/quicktime

View File

@@ -0,0 +1 @@
conf.d/centos.example.com.conf, centos.example.com

View File

@@ -0,0 +1,25 @@
#
# This file can be used to set additional environment variables for
# the httpd process, or pass additional options to the httpd
# executable.
#
# Note: With previous versions of httpd, the MPM could be changed by
# editing an "HTTPD" variable here. With the current version, that
# variable is now ignored. The MPM is a loadable module, and the
# choice of MPM can be changed by editing the configuration file
# /etc/httpd/conf.modules.d/00-mpm.conf.
#
#
# To pass additional options (for instance, -D definitions) to the
# httpd binary at startup, set OPTIONS here.
#
OPTIONS="-D mock_define -D mock_define_too -D mock_value=TRUE"
#
# This setting ensures the httpd process is started in the "C" locale
# by default. (Some modules will not behave correctly if
# case-sensitive string comparisons are performed in a different
# locale.)
#
LANG=C

View File

@@ -0,0 +1,157 @@
# This is a modification of the default Apache 2.4 configuration file
# for Gentoo Linux.
#
# Support:
# http://www.gentoo.org/main/en/lists.xml [mailing lists]
# http://forums.gentoo.org/ [web forums]
# irc://irc.freenode.net#gentoo-apache [irc chat]
#
# Bug Reports:
# http://bugs.gentoo.org [gentoo related bugs]
# http://httpd.apache.org/bug_report.html [apache httpd related bugs]
#
#
# This is the main Apache HTTP server configuration file. It contains the
# configuration directives that give the server its instructions.
# See <URL:http://httpd.apache.org/docs/2.4> for detailed information.
# In particular, see
# <URL:http://httpd.apache.org/docs/2.4/mod/directives.html>
# for a discussion of each configuration directive.
#
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
#
# Configuration and logfile names: If the filenames you specify for many
# of the server's control files begin with "/" (or "drive:/" for Win32), the
# server will use that explicit path. If the filenames do *not* begin
# with "/", the value of ServerRoot is prepended -- so "var/log/apache2/foo_log"
# with ServerRoot set to "/usr" will be interpreted by the
# server as "/usr/var/log/apache2/foo.log".
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# Do not add a slash at the end of the directory path. If you point
# ServerRoot at a non-local disk, be sure to point the LockFile directive
# at a local disk. If you wish to share the same ServerRoot for multiple
# httpd daemons, you will need to change at least LockFile and PidFile.
# Comment: The LockFile directive has been replaced by the Mutex directive
ServerRoot "/usr/lib64/apache2"
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so
#
# GENTOO: Automatically defined based on APACHE2_MODULES USE_EXPAND variable.
# Do not change manually, it will be overwritten on upgrade.
#
# The following modules are considered as the default configuration.
# If you wish to disable one of them, you may have to alter other
# configuration directives.
#
# Change these at your own risk!
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authn_anon_module modules/mod_authn_anon.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authn_dbm_module modules/mod_authn_dbm.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_dbm_module modules/mod_authz_dbm.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_owner_module modules/mod_authz_owner.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
<IfDefine CACHE>
LoadModule cache_module modules/mod_cache.so
</IfDefine>
LoadModule cgi_module modules/mod_cgi.so
LoadModule cgid_module modules/mod_cgid.so
<IfDefine DAV>
LoadModule dav_module modules/mod_dav.so
</IfDefine>
<IfDefine DAV>
LoadModule dav_fs_module modules/mod_dav_fs.so
</IfDefine>
<IfDefine DAV>
LoadModule dav_lock_module modules/mod_dav_lock.so
</IfDefine>
LoadModule deflate_module modules/mod_deflate.so
LoadModule dir_module modules/mod_dir.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
LoadModule ext_filter_module modules/mod_ext_filter.so
<IfDefine CACHE>
LoadModule file_cache_module modules/mod_file_cache.so
</IfDefine>
LoadModule filter_module modules/mod_filter.so
LoadModule headers_module modules/mod_headers.so
LoadModule include_module modules/mod_include.so
<IfDefine INFO>
LoadModule info_module modules/mod_info.so
</IfDefine>
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule mime_module modules/mod_mime.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
<IfDefine SSL>
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
</IfDefine>
LoadModule speling_module modules/mod_speling.so
<IfDefine SSL>
LoadModule ssl_module modules/mod_ssl.so
</IfDefine>
<IfDefine STATUS>
LoadModule status_module modules/mod_status.so
</IfDefine>
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule unixd_module modules/mod_unixd.so
<IfDefine USERDIR>
LoadModule userdir_module modules/mod_userdir.so
</IfDefine>
LoadModule usertrack_module modules/mod_usertrack.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
User apache
Group apache
# Supplemental configuration
#
# Most of the configuration files in the /etc/apache2/modules.d/ directory can
# be turned on using APACHE2_OPTS in /etc/conf.d/apache2 to add extra features
# or to modify the default configuration of the server.
#
# To know which flag to add to APACHE2_OPTS, look at the first line of the
# the file, which will usually be an <IfDefine OPTION> where OPTION is the
# flag to use.
Include modules.d/*.conf
# Virtual-host support
#
# Gentoo has made using virtual-hosts easy. In /etc/apache2/vhosts.d/ we
# include a default vhost (enabled by adding -D DEFAULT_VHOST to
# APACHE2_OPTS in /etc/conf.d/apache2).
Include vhosts.d/*.conf
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,385 @@
# Magic data for mod_mime_magic Apache module (originally for file(1) command)
# The module is described in /manual/mod/mod_mime_magic.html
#
# The format is 4-5 columns:
# Column #1: byte number to begin checking from, ">" indicates continuation
# Column #2: type of data to match
# Column #3: contents of data to match
# Column #4: MIME type of result
# Column #5: MIME encoding of result (optional)
#------------------------------------------------------------------------------
# Localstuff: file(1) magic for locally observed files
# Add any locally observed files here.
#------------------------------------------------------------------------------
# end local stuff
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Java
0 short 0xcafe
>2 short 0xbabe application/java
#------------------------------------------------------------------------------
# audio: file(1) magic for sound formats
#
# from Jan Nicolai Langfeldt <janl@ifi.uio.no>,
#
# Sun/NeXT audio data
0 string .snd
>12 belong 1 audio/basic
>12 belong 2 audio/basic
>12 belong 3 audio/basic
>12 belong 4 audio/basic
>12 belong 5 audio/basic
>12 belong 6 audio/basic
>12 belong 7 audio/basic
>12 belong 23 audio/x-adpcm
# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format
# that uses little-endian encoding and has a different magic number
# (0x0064732E in little-endian encoding).
0 lelong 0x0064732E
>12 lelong 1 audio/x-dec-basic
>12 lelong 2 audio/x-dec-basic
>12 lelong 3 audio/x-dec-basic
>12 lelong 4 audio/x-dec-basic
>12 lelong 5 audio/x-dec-basic
>12 lelong 6 audio/x-dec-basic
>12 lelong 7 audio/x-dec-basic
# compressed (G.721 ADPCM)
>12 lelong 23 audio/x-dec-adpcm
# Bytes 0-3 of AIFF, AIFF-C, & 8SVX audio files are "FORM"
# AIFF audio data
8 string AIFF audio/x-aiff
# AIFF-C audio data
8 string AIFC audio/x-aiff
# IFF/8SVX audio data
8 string 8SVX audio/x-aiff
# Creative Labs AUDIO stuff
# Standard MIDI data
0 string MThd audio/unknown
#>9 byte >0 (format %d)
#>11 byte >1 using %d channels
# Creative Music (CMF) data
0 string CTMF audio/unknown
# SoundBlaster instrument data
0 string SBI audio/unknown
# Creative Labs voice data
0 string Creative\ Voice\ File audio/unknown
## is this next line right? it came this way...
#>19 byte 0x1A
#>23 byte >0 - version %d
#>22 byte >0 \b.%d
# [GRR 950115: is this also Creative Labs? Guessing that first line
# should be string instead of unknown-endian long...]
#0 long 0x4e54524b MultiTrack sound data
#0 string NTRK MultiTrack sound data
#>4 long x - version %ld
# Microsoft WAVE format (*.wav)
# [GRR 950115: probably all of the shorts and longs should be leshort/lelong]
# Microsoft RIFF
0 string RIFF audio/unknown
# - WAVE format
>8 string WAVE audio/x-wav
# MPEG audio.
0 beshort&0xfff0 0xfff0 audio/mpeg
# C64 SID Music files, from Linus Walleij <triad@df.lth.se>
0 string PSID audio/prs.sid
#------------------------------------------------------------------------------
# c-lang: file(1) magic for C programs or various scripts
#
# XPM icons (Greg Roelofs, newt@uchicago.edu)
# ideally should go into "images", but entries below would tag XPM as C source
0 string /*\ XPM image/x-xbm 7bit
# this first will upset you if you're a PL/1 shop... (are there any left?)
# in which case rm it; ascmagic will catch real C programs
# C or REXX program text
0 string /* text/plain
# C++ program text
0 string // text/plain
#------------------------------------------------------------------------------
# compress: file(1) magic for pure-compression formats (no archives)
#
# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, whap, etc.
#
# Formats for various forms of compressed data
# Formats for "compress" proper have been moved into "compress.c",
# because it tries to uncompress it to figure out what's inside.
# standard unix compress
0 string \037\235 application/octet-stream x-compress
# gzip (GNU zip, not to be confused with [Info-ZIP/PKWARE] zip archiver)
0 string \037\213 application/octet-stream x-gzip
# According to gzip.h, this is the correct byte order for packed data.
0 string \037\036 application/octet-stream
#
# This magic number is byte-order-independent.
#
0 short 017437 application/octet-stream
# XXX - why *two* entries for "compacted data", one of which is
# byte-order independent, and one of which is byte-order dependent?
#
# compacted data
0 short 0x1fff application/octet-stream
0 string \377\037 application/octet-stream
# huf output
0 short 0145405 application/octet-stream
# Squeeze and Crunch...
# These numbers were gleaned from the Unix versions of the programs to
# handle these formats. Note that I can only uncrunch, not crunch, and
# I didn't have a crunched file handy, so the crunch number is untested.
# Keith Waclena <keith@cerberus.uchicago.edu>
#0 leshort 0x76FF squeezed data (CP/M, DOS)
#0 leshort 0x76FE crunched data (CP/M, DOS)
# Freeze
#0 string \037\237 Frozen file 2.1
#0 string \037\236 Frozen file 1.0 (or gzip 0.5)
# lzh?
#0 string \037\240 LZH compressed data
#------------------------------------------------------------------------------
# frame: file(1) magic for FrameMaker files
#
# This stuff came on a FrameMaker demo tape, most of which is
# copyright, but this file is "published" as witness the following:
#
0 string \<MakerFile application/x-frame
0 string \<MIFFile application/x-frame
0 string \<MakerDictionary application/x-frame
0 string \<MakerScreenFon application/x-frame
0 string \<MML application/x-frame
0 string \<Book application/x-frame
0 string \<Maker application/x-frame
#------------------------------------------------------------------------------
# html: file(1) magic for HTML (HyperText Markup Language) docs
#
# from Daniel Quinlan <quinlan@yggdrasil.com>
# and Anna Shergold <anna@inext.co.uk>
#
0 string \<!DOCTYPE\ HTML text/html
0 string \<!doctype\ html text/html
0 string \<HEAD text/html
0 string \<head text/html
0 string \<TITLE text/html
0 string \<title text/html
0 string \<html text/html
0 string \<HTML text/html
0 string \<!-- text/html
0 string \<h1 text/html
0 string \<H1 text/html
# XML eXtensible Markup Language, from Linus Walleij <triad@df.lth.se>
0 string \<?xml text/xml
#------------------------------------------------------------------------------
# images: file(1) magic for image formats (see also "c-lang" for XPM bitmaps)
#
# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
# additions by janl@ifi.uio.no as well as others. Jan also suggested
# merging several one- and two-line files into here.
#
# XXX - byte order for GIF and TIFF fields?
# [GRR: TIFF allows both byte orders; GIF is probably little-endian]
#
# [GRR: what the hell is this doing in here?]
#0 string xbtoa btoa'd file
# PBMPLUS
# PBM file
0 string P1 image/x-portable-bitmap 7bit
# PGM file
0 string P2 image/x-portable-greymap 7bit
# PPM file
0 string P3 image/x-portable-pixmap 7bit
# PBM "rawbits" file
0 string P4 image/x-portable-bitmap
# PGM "rawbits" file
0 string P5 image/x-portable-greymap
# PPM "rawbits" file
0 string P6 image/x-portable-pixmap
# NIFF (Navy Interchange File Format, a modification of TIFF)
# [GRR: this *must* go before TIFF]
0 string IIN1 image/x-niff
# TIFF and friends
# TIFF file, big-endian
0 string MM image/tiff
# TIFF file, little-endian
0 string II image/tiff
# possible GIF replacements; none yet released!
# (Greg Roelofs, newt@uchicago.edu)
#
# GRR 950115: this was mine ("Zip GIF"):
# ZIF image (GIF+deflate alpha)
0 string GIF94z image/unknown
#
# GRR 950115: this is Jeremy Wohl's Free Graphics Format (better):
# FGF image (GIF+deflate beta)
0 string FGF95a image/unknown
#
# GRR 950115: this is Thomas Boutell's Portable Bitmap Format proposal
# (best; not yet implemented):
# PBF image (deflate compression)
0 string PBF image/unknown
# GIF
0 string GIF image/gif
# JPEG images
0 beshort 0xffd8 image/jpeg
# PC bitmaps (OS/2, Windoze BMP files) (Greg Roelofs, newt@uchicago.edu)
0 string BM image/bmp
#>14 byte 12 (OS/2 1.x format)
#>14 byte 64 (OS/2 2.x format)
#>14 byte 40 (Windows 3.x format)
#0 string IC icon
#0 string PI pointer
#0 string CI color icon
#0 string CP color pointer
#0 string BA bitmap array
0 string \x89PNG image/png
0 string FWS application/x-shockwave-flash
0 string CWS application/x-shockwave-flash
#------------------------------------------------------------------------------
# lisp: file(1) magic for lisp programs
#
# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
0 string ;; text/plain 8bit
# Emacs 18 - this is always correct, but not very magical.
0 string \012( application/x-elc
# Emacs 19
0 string ;ELC\023\000\000\000 application/x-elc
#------------------------------------------------------------------------------
# mail.news: file(1) magic for mail and news
#
# There are tests to ascmagic.c to cope with mail and news.
0 string Relay-Version: message/rfc822 7bit
0 string #!\ rnews message/rfc822 7bit
0 string N#!\ rnews message/rfc822 7bit
0 string Forward\ to message/rfc822 7bit
0 string Pipe\ to message/rfc822 7bit
0 string Return-Path: message/rfc822 7bit
0 string Path: message/news 8bit
0 string Xref: message/news 8bit
0 string From: message/rfc822 7bit
0 string Article message/news 8bit
#------------------------------------------------------------------------------
# msword: file(1) magic for MS Word files
#
# Contributor claims:
# Reversed-engineered MS Word magic numbers
#
0 string \376\067\0\043 application/msword
0 string \333\245-\0\0\0 application/msword
# disable this one because it applies also to other
# Office/OLE documents for which msword is not correct. See PR#2608.
#0 string \320\317\021\340\241\261 application/msword
#------------------------------------------------------------------------------
# printer: file(1) magic for printer-formatted files
#
# PostScript
0 string %! application/postscript
0 string \004%! application/postscript
# Acrobat
# (due to clamen@cs.cmu.edu)
0 string %PDF- application/pdf
#------------------------------------------------------------------------------
# sc: file(1) magic for "sc" spreadsheet
#
38 string Spreadsheet application/x-sc
#------------------------------------------------------------------------------
# tex: file(1) magic for TeX files
#
# XXX - needs byte-endian stuff (big-endian and little-endian DVI?)
#
# From <conklin@talisman.kaleida.com>
# Although we may know the offset of certain text fields in TeX DVI
# and font files, we can't use them reliably because they are not
# zero terminated. [but we do anyway, christos]
0 string \367\002 application/x-dvi
#0 string \367\203 TeX generic font data
#0 string \367\131 TeX packed font data
#0 string \367\312 TeX virtual font data
#0 string This\ is\ TeX, TeX transcript text
#0 string This\ is\ METAFONT, METAFONT transcript text
# There is no way to detect TeX Font Metric (*.tfm) files without
# breaking them apart and reading the data. The following patterns
# match most *.tfm files generated by METAFONT or afm2tfm.
#2 string \000\021 TeX font metric data
#2 string \000\022 TeX font metric data
#>34 string >\0 (%s)
# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
#0 string \\input\ texinfo Texinfo source text
#0 string This\ is\ Info\ file GNU Info text
# correct TeX magic for Linux (and maybe more)
# from Peter Tobias (tobias@server.et-inf.fho-emden.de)
#
0 leshort 0x02f7 application/x-dvi
# RTF - Rich Text Format
0 string {\\rtf application/rtf
#------------------------------------------------------------------------------
# animation: file(1) magic for animation/movie formats
#
# animation formats, originally from vax@ccwf.cc.utexas.edu (VaX#n8)
# MPEG file
0 string \000\000\001\263 video/mpeg
#
# The contributor claims:
# I couldn't find a real magic number for these, however, this
# -appears- to work. Note that it might catch other files, too,
# so BE CAREFUL!
#
# Note that title and author appear in the two 20-byte chunks
# at decimal offsets 2 and 22, respectively, but they are XOR'ed with
# 255 (hex FF)! DL format SUCKS BIG ROCKS.
#
# DL file version 1 , medium format (160x100, 4 images/screen)
0 byte 1 video/unknown
0 byte 2 video/unknown
# Quicktime video, from Linus Walleij <triad@df.lth.se>
# from Apple quicktime file format documentation.
4 string moov video/quicktime
4 string mdat video/quicktime

View File

@@ -0,0 +1,131 @@
# This configuration file reflects default settings for Apache HTTP Server.
# You may change these, but chances are that you may not need to.
# Timeout: The number of seconds before receives and sends time out.
Timeout 300
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
KeepAlive On
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
MaxKeepAliveRequests 100
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
KeepAliveTimeout 15
# UseCanonicalName: Determines how Apache constructs self-referencing
# URLs and the SERVER_NAME and SERVER_PORT variables.
# When set "Off", Apache will use the Hostname and Port supplied
# by the client. When set "On", Apache will use the value of the
# ServerName directive.
UseCanonicalName Off
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
AccessFileName .htaccess
# ServerTokens
# This directive configures what you return as the Server HTTP response
# Header. The default is 'Full' which sends information about the OS-Type
# and compiled in modules.
# Set to one of: Full | OS | Minor | Minimal | Major | Prod
# where Full conveys the most information, and Prod the least.
ServerTokens Prod
# TraceEnable
# This directive overrides the behavior of TRACE for both the core server and
# mod_proxy. The default TraceEnable on permits TRACE requests per RFC 2616,
# which disallows any request body to accompany the request. TraceEnable off
# causes the core server and mod_proxy to return a 405 (Method not allowed)
# error to the client.
# For security reasons this is turned off by default. (bug #240680)
TraceEnable off
# Optionally add a line containing the server version and virtual host
# name to server-generated pages (internal error documents, FTP directory
# listings, mod_status and mod_info output etc., but not CGI generated
# documents or custom error documents).
# Set to "EMail" to also include a mailto: link to the ServerAdmin.
# Set to one of: On | Off | EMail
ServerSignature On
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
HostnameLookups Off
# EnableMMAP and EnableSendfile: On systems that support it,
# memory-mapping or the sendfile syscall is used to deliver
# files. This usually improves server performance, but must
# be turned off when serving from networked-mounted
# filesystems or if support for these functions is otherwise
# broken on your system.
EnableMMAP On
EnableSendfile Off
# FileETag: Configures the file attributes that are used to create
# the ETag (entity tag) response header field when the document is
# based on a static file. (The ETag value is used in cache management
# to save network bandwidth.)
FileETag MTime Size
# ContentDigest: This directive enables the generation of Content-MD5
# headers as defined in RFC1864 respectively RFC2616.
# The Content-MD5 header provides an end-to-end message integrity
# check (MIC) of the entity-body. A proxy or client may check this
# header for detecting accidental modification of the entity-body
# in transit.
# Note that this can cause performance problems on your server since
# the message digest is computed on every request (the values are
# not cached).
# Content-MD5 is only sent for documents served by the core, and not
# by any module. For example, SSI documents, output from CGI scripts,
# and byte range responses do not have this header.
ContentDigest Off
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
ErrorLog /var/log/apache2/error_log
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
# We configure the "default" to be a very restrictive set of features.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
# The index.html.var file (a type-map) is used to deliver content-
# negotiated documents. The MultiViews Options can be used for the
# same purpose, but it is much slower.
#
# Do not change this entry unless you know what you are doing.
<IfModule dir_module>
DirectoryIndex index.html index.html.var
</IfModule>
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,57 @@
# The configuration below implements multi-language error documents through
# content-negotiation.
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
# Some examples:
#ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
# Required modules: mod_alias, mod_include, mod_negotiation
# We use Alias to redirect any /error/HTTP_<error>.html.var response to
# our collection of by-error message multi-language collections. We use
# includes to substitute the appropriate text.
# You can modify the messages' appearance without changing any of the
# default HTTP_<error>.html.var files by adding the line:
# Alias /error/include/ "/your/include/path/"
# which allows you to create your own set of files by starting with the
# /var/www/localhost/error/include/ files and copying them to /your/include/path/,
# even on a per-VirtualHost basis. The default include files will display
# your Apache version number and your ServerAdmin email address regardless
# of the setting of ServerSignature.
<IfDefine ERRORDOCS>
Alias /error/ "/usr/share/apache2/error/"
<Directory "/usr/share/apache2/error">
AllowOverride None
Options IncludesNoExec
AddOutputFilter Includes html
AddHandler type-map var
Require all granted
LanguagePriority en cs de es fr it ja ko nl pl pt-br ro sv tr
ForceLanguagePriority Prefer Fallback
</Directory>
ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
ErrorDocument 410 /error/HTTP_GONE.html.var
ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,133 @@
# Settings for hosting different languages.
<IfDefine LANGUAGE>
# DefaultLanguage and AddLanguage allows you to specify the language of
# a document. You can then use content negotiation to give a browser a
# file in a language the user can understand.
#
# Specify a default language. This means that all data
# going out without a specific language tag (see below) will
# be marked with this one. You probably do NOT want to set
# this unless you are sure it is correct for all cases.
#
# It is generally better to not mark a page as
# being a certain language than marking it with the wrong
# language!
#
# DefaultLanguage nl
#
# Note 1: The suffix does not have to be the same as the language
# keyword --- those with documents in Polish (whose net-standard
# language code is pl) may wish to use "AddLanguage pl .po" to
# avoid the ambiguity with the common suffix for perl scripts.
#
# Note 2: The example entries below illustrate that in some cases
# the two character 'Language' abbreviation is not identical to
# the two character 'Country' code for its country,
# E.g. 'Danmark/dk' versus 'Danish/da'.
#
# Note 3: In the case of 'ltz' we violate the RFC by using a three char
# specifier. There is 'work in progress' to fix this and get
# the reference data for rfc1766 cleaned up.
#
# Catalan (ca) - Croatian (hr) - Czech (cs) - Danish (da) - Dutch (nl)
# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
# Norwegian (no) - Polish (pl) - Portugese (pt)
# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
AddLanguage ca .ca
AddLanguage cs .cz .cs
AddLanguage da .dk
AddLanguage de .de
AddLanguage el .el
AddLanguage en .en
AddLanguage eo .eo
AddLanguage es .es
AddLanguage et .et
AddLanguage fr .fr
AddLanguage he .he
AddLanguage hr .hr
AddLanguage it .it
AddLanguage ja .ja
AddLanguage ko .ko
AddLanguage ltz .ltz
AddLanguage nl .nl
AddLanguage nn .nn
AddLanguage no .no
AddLanguage pl .po
AddLanguage pt .pt
AddLanguage pt-BR .pt-br
AddLanguage ru .ru
AddLanguage sv .sv
AddLanguage zh-CN .zh-cn
AddLanguage zh-TW .zh-tw
# LanguagePriority allows you to give precedence to some languages
# in case of a tie during content negotiation.
#
# Just list the languages in decreasing order of preference. We have
# more or less alphabetized them here. You probably want to change this.
LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW
# ForceLanguagePriority allows you to serve a result page rather than
# MULTIPLE CHOICES (Prefer) [in case of a tie] or NOT ACCEPTABLE (Fallback)
# [in case no accepted languages matched the available variants]
ForceLanguagePriority Prefer Fallback
# Commonly used filename extensions to character sets. You probably
# want to avoid clashes with the language extensions, unless you
# are good at carefully testing your setup after each change.
# See http://www.iana.org/assignments/character-sets for the
# official list of charset names and their respective RFCs.
AddCharset us-ascii.ascii .us-ascii
AddCharset ISO-8859-1 .iso8859-1 .latin1
AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen
AddCharset ISO-8859-3 .iso8859-3 .latin3
AddCharset ISO-8859-4 .iso8859-4 .latin4
AddCharset ISO-8859-5 .iso8859-5 .cyr .iso-ru
AddCharset ISO-8859-6 .iso8859-6 .arb .arabic
AddCharset ISO-8859-7 .iso8859-7 .grk .greek
AddCharset ISO-8859-8 .iso8859-8 .heb .hebrew
AddCharset ISO-8859-9 .iso8859-9 .latin5 .trk
AddCharset ISO-8859-10 .iso8859-10 .latin6
AddCharset ISO-8859-13 .iso8859-13
AddCharset ISO-8859-14 .iso8859-14 .latin8
AddCharset ISO-8859-15 .iso8859-15 .latin9
AddCharset ISO-8859-16 .iso8859-16 .latin10
AddCharset ISO-2022-JP .iso2022-jp .jis
AddCharset ISO-2022-KR .iso2022-kr .kis
AddCharset ISO-2022-CN .iso2022-cn .cis
AddCharset Big5.Big5 .big5 .b5
AddCharset cn-Big5 .cn-big5
# For russian, more than one charset is used (depends on client, mostly):
AddCharset WINDOWS-1251 .cp-1251 .win-1251
AddCharset CP866 .cp866
AddCharset KOI8 .koi8
AddCharset KOI8-E .koi8-e
AddCharset KOI8-r .koi8-r .koi8-ru
AddCharset KOI8-U .koi8-u
AddCharset KOI8-ru .koi8-uk .ua
AddCharset ISO-10646-UCS-2 .ucs2
AddCharset ISO-10646-UCS-4 .ucs4
AddCharset UTF-7 .utf7
AddCharset UTF-8 .utf8
AddCharset UTF-16 .utf16
AddCharset UTF-16BE .utf16be
AddCharset UTF-16LE .utf16le
AddCharset UTF-32 .utf32
AddCharset UTF-32BE .utf32be
AddCharset UTF-32LE .utf32le
AddCharset euc-cn .euc-cn
AddCharset euc-gb .euc-gb
AddCharset euc-jp .euc-jp
AddCharset euc-kr .euc-kr
# Not sure how euc-tw got in - IANA doesn't list it???
AddCharset EUC-TW .euc-tw
AddCharset gb2312 .gb2312 .gb
AddCharset iso-10646-ucs-2 .ucs-2 .iso-10646-ucs-2
AddCharset iso-10646-ucs-4 .ucs-4 .iso-10646-ucs-4
AddCharset shift_jis .shift_jis .sjis
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,85 @@
<IfModule autoindex_module>
<IfDefine !NO_AUTOINDEX_CONF>
<IfModule alias_module>
# We include the /icons/ alias for FancyIndexed directory listings. If
# you do not use FancyIndexing, you may comment this out.
Alias /icons/ "/usr/share/apache2/icons/"
<Directory "/usr/share/apache2/icons">
Options Indexes MultiViews
AllowOverride None
Require all granted
</Directory>
</IfModule>
# Directives controlling the display of server-generated directory listings.
#
# To see the listing of a directory, the Options directive for the
# directory must include "Indexes", and the directory must not contain
# a file matching those listed in the DirectoryIndex directive.
# IndexOptions: Controls the appearance of server-generated directory
# listings.
IndexOptions FancyIndexing VersionSort
# AddIcon* directives tell the server which icon to show for different
# files or filename extensions. These are only displayed for
# FancyIndexed directories.
AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
AddIconByType (TXT,/icons/text.gif) text/*
AddIconByType (IMG,/icons/image2.gif) image/*
AddIconByType (SND,/icons/sound2.gif) audio/*
AddIconByType (VID,/icons/movie.gif) video/*
AddIcon /icons/binary.gif .bin .exe
AddIcon /icons/binhex.gif .hqx
AddIcon /icons/tar.gif .tar
AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
AddIcon /icons/a.gif .ps .ai .eps
AddIcon /icons/layout.gif .html .shtml .htm .pdf
AddIcon /icons/text.gif .txt
AddIcon /icons/c.gif .c
AddIcon /icons/p.gif .pl .py
AddIcon /icons/f.gif .for
AddIcon /icons/dvi.gif .dvi
AddIcon /icons/uuencoded.gif .uu
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
AddIcon /icons/tex.gif .tex
AddIcon /icons/bomb.gif core
AddIcon /icons/back.gif ..
AddIcon /icons/hand.right.gif README
AddIcon /icons/folder.gif ^^DIRECTORY^^
AddIcon /icons/blank.gif ^^BLANKICON^^
# DefaultIcon is which icon to show for files which do not have an icon
# explicitly set.
DefaultIcon /icons/unknown.gif
# AddDescription allows you to place a short description after a file in
# server-generated indexes. These are only displayed for FancyIndexed
# directories.
# Format: AddDescription "description" filename
#AddDescription "GZIP compressed document" .gz
#AddDescription "tar archive" .tar
#AddDescription "GZIP compressed tar archive" .tgz
# ReadmeName is the name of the README file the server will look for by
# default, and append to directory listings.
# HeaderName is the name of a file which should be prepended to
# directory indexes.
ReadmeName README.html
HeaderName HEADER.html
# IndexIgnore is a set of filenames which directory indexing should ignore
# and not include in the listing. Shell-style wildcarding is permitted.
IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
</IfDefine>
</IfModule>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,10 @@
<IfDefine INFO>
# Allow remote server configuration reports, with the URL of
# http://servername/server-info
<Location /server-info>
SetHandler server-info
Require local
</Location>
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,35 @@
<IfModule log_config_module>
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-Agent}i" agent
LogFormat "%v %h %l %u %t \"%r\" %>s %b %T" script
LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" VLOG=%{VLOG}e" vhost
<IfModule logio_module>
# You need to enable mod_logio.c to use %I and %O
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" vhostio
</IfModule>
# The location and format of the access logfile (Common Logfile Format).
# If you do not define any access logfiles within a <VirtualHost>
# container, they will be logged here. Contrariwise, if you *do*
# define per-<VirtualHost> access logfiles, transactions will be
# logged therein and *not* in this file.
CustomLog /var/log/apache2/access_log common
# If you would like to have agent and referer logfiles,
# uncomment the following directives.
#CustomLog /var/log/apache2/referer_log referer
#CustomLog /var/log/apache2/agent_logs agent
# If you prefer a logfile with access, agent, and referer information
# (Combined Logfile Format) you can use the following directive.
#CustomLog /var/log/apache2/access_log combined
</IfModule>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,46 @@
<IfModule mime_module>
# TypesConfig points to the file containing the list of mappings from
# filename extension to MIME-type.
TypesConfig /etc/mime.types
# AddType allows you to add to or override the MIME configuration
# file specified in TypesConfig for specific file types.
#AddType application/x-gzip .tgz
# AddEncoding allows you to have certain browsers uncompress
# information on the fly. Note: Not all browsers support this.
#AddEncoding x-compress .Z
#AddEncoding x-gzip .gz .tgz
# If the AddEncoding directives above are commented-out, then you
# probably should define those extensions to indicate media types:
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
# AddHandler allows you to map certain file extensions to "handlers":
# actions unrelated to filetype. These can be either built into the server
# or added with the Action directive (see below)
# To use CGI scripts outside of ScriptAliased directories:
# (You will also need to add "ExecCGI" to the "Options" directive.)
#AddHandler cgi-script .cgi
# For type maps (negotiated resources):
#AddHandler type-map var
# Filters allow you to process content before it is sent to the client.
#
# To parse .shtml files for server-side includes (SSI):
# (You will also need to add "Includes" to the "Options" directive.)
#AddType text/html .shtml
#AddOutputFilter INCLUDES .shtml
</IfModule>
<IfModule mime_magic_module>
# The mod_mime_magic module allows the server to use various hints from the
# contents of the file itself to determine its type. The MIMEMagicFile
# directive tells the module where the hint definitions are located.
MIMEMagicFile /etc/apache2/magic
</IfModule>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,15 @@
<IfDefine STATUS>
# Allow server status reports generated by mod_status,
# with the URL of http://servername/server-status
<Location /server-status>
SetHandler server-status
Require local
</Location>
# ExtendedStatus controls whether Apache will generate "full" status
# information (ExtendedStatus On) or just basic information (ExtendedStatus
# Off) when the "server-status" handler is called.
ExtendedStatus On
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,32 @@
# Settings for user home directories
<IfDefine USERDIR>
# UserDir: The name of the directory that is appended onto a user's home
# directory if a ~user request is received. Note that you must also set
# the default access control for these directories, as in the example below.
UserDir public_html
# Control access to UserDir directories. The following is an example
# for a site where these directories are restricted to read-only.
<Directory /home/*/public_html>
AllowOverride FileInfo AuthConfig Limit Indexes
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
<Limit GET POST OPTIONS>
Require all granted
</Limit>
<LimitExcept GET POST OPTIONS>
Require all denied
</LimitExcept>
</Directory>
# Suexec isn't really required to run cgi-scripts, but it's a really good
# idea if you have multiple users serving websites...
<IfDefine SUEXEC>
<Directory /home/*/public_html/cgi-bin>
Options ExecCGI
SetHandler cgi-script
</Directory>
</IfDefine>
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,99 @@
# Server-Pool Management (MPM specific)
# PidFile: The file in which the server should record its process
# identification number when it starts.
#
# DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING
PidFile /run/apache2.pid
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
# Mutex file:/run/apache_mpm_mutex
# Only one of the below sections will be relevant on your
# installed httpd. Use "/usr/sbin/apache2 -l" to find out the
# active mpm.
# common MPM configuration
# These configuration directives apply to all MPMs
#
# StartServers: Number of child server processes created at startup
# MaxRequestWorkers: Maximum number of child processes to serve requests
# MaxConnectionsPerChild: Limit on the number of connections that an individual
# child server will handle during its life
# prefork MPM
# This is the default MPM if USE=-threads
#
# MinSpareServers: Minimum number of idle child server processes
# MaxSpareServers: Maximum number of idle child server processes
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 10000
</IfModule>
# worker MPM
# This is the default MPM if USE=threads
#
# MinSpareThreads: Minimum number of idle threads available to handle request spikes
# MaxSpareThreads: Maximum number of idle threads
# ThreadsPerChild: Number of threads created by each child process
<IfModule mpm_worker_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 10000
</IfModule>
# event MPM
#
# MinSpareThreads: Minimum number of idle threads available to handle request spikes
# MaxSpareThreads: Maximum number of idle threads
# ThreadsPerChild: Number of threads created by each child process
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 10000
</IfModule>
# peruser MPM
#
# MinSpareProcessors: Minimum number of idle child server processes
# MinProcessors: Minimum number of processors per virtual host
# MaxProcessors: Maximum number of processors per virtual host
# ExpireTimeout: Maximum idle time before a child is killed, 0 to disable
# Multiplexer: Specify a Multiplexer child configuration.
# Processor: Specify a user and group for a specific child process
<IfModule mpm_peruser_module>
MinSpareProcessors 2
MinProcessors 2
MaxProcessors 10
MaxRequestWorkers 150
MaxConnectionsPerChild 1000
ExpireTimeout 1800
Multiplexer nobody nobody
Processor apache apache
</IfModule>
# itk MPM
#
# MinSpareServers: Minimum number of idle child server processes
# MaxSpareServers: Maximum number of idle child server processes
<IfModule mpm_itk_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 10000
</IfModule>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,10 @@
<IfDefine MEM_CACHE>
# 128MB cache for objects < 2MB
CacheEnable mem /
MCacheSize 131072
MCacheMaxObjectCount 1000
MCacheMinObjectSize 1
MCacheMaxObjectSize 2097152
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,67 @@
# Note: The following must must be present to support
# starting without SSL on platforms with no /dev/random equivalent
# but a statically compiled-in mod_ssl.
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>
<IfDefine SSL>
# This is the Apache server configuration file providing SSL support.
# It contains the configuration directives to instruct the server how to
# serve pages over an https connection. For detailing information about these
# directives see <URL:http://httpd.apache.org/docs/2.4/mod/mod_ssl.html>
# Do NOT simply read the instructions in here without understanding
# what they do. They're here only as hints or reminders. If you are unsure
# consult the online docs. You have been warned.
## Pseudo Random Number Generator (PRNG):
# Configure one or more sources to seed the PRNG of the SSL library.
# The seed data should be of good random quality.
# WARNING! On some platforms /dev/random blocks if not enough entropy
# is available. This means you then cannot use the /dev/random device
# because it would lead to very long connection times (as long as
# it requires to make more entropy available). But usually those
# platforms additionally provide a /dev/urandom device which doesn't
# block. So, if available, use this one instead. Read the mod_ssl User
# Manual for more details.
#SSLRandomSeed startup file:/dev/random 512
#SSLRandomSeed startup file:/dev/urandom 512
#SSLRandomSeed connect file:/dev/random 512
#SSLRandomSeed connect file:/dev/urandom 512
## SSL Global Context:
# All SSL configuration in this context applies both to the main server and
# all SSL-enabled virtual hosts.
# Some MIME-types for downloading Certificates and CRLs
<IfModule mime_module>
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
</IfModule>
## Pass Phrase Dialog:
# Configure the pass phrase gathering process. The filtering dialog program
# (`builtin' is a internal terminal dialog) has to provide the pass phrase on
# stdout.
SSLPassPhraseDialog builtin
## Inter-Process Session Cache:
# Configure the SSL Session Cache: First the mechanism to use and second the
# expiring timeout (in seconds).
#SSLSessionCache dbm:/run/ssl_scache
SSLSessionCache shmcb:/run/ssl_scache(512000)
SSLSessionCacheTimeout 300
## Semaphore:
# Configure the path to the mutual exclusion semaphore the SSL engine uses
# internally for inter-process synchronization.
Mutex file:/run/apache_ssl_mutex ssl-cache
## SSL Compression:
# Known to be vulnerable thus disabled by default (bug #507324).
SSLCompression off
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,9 @@
<IfDefine SSL>
<IfModule http2_module>
# enable debugging for this module
#LogLevel http2:info
#Enable HTTP/2 support
Protocols h2 h2c http/1.1
</IfModule>
</IfDefine>

View File

@@ -0,0 +1,19 @@
<IfDefine DAV>
DavLockDB "/var/lib/dav/lockdb"
# The following directives disable redirects on non-GET requests for
# a directory that does not include the trailing slash. This fixes a
# problem with several clients that do not appropriately handle
# redirects for folders with DAV methods.
<IfModule setenvif_module>
BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
BrowserMatch "MS FrontPage" redirect-carefully
BrowserMatch "^WebDrive" redirect-carefully
BrowserMatch "^WebDAVFS/1.[012345678]" redirect-carefully
BrowserMatch "^gnome-vfs/1.0" redirect-carefully
BrowserMatch "^XML Spy" redirect-carefully
BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully
</IfModule>
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,18 @@
# Examples below are taken from the online documentation
# Refer to:
# http://localhost/manual/mod/mod_ldap.html
# http://localhost/manual/mod/mod_auth_ldap.html
<IfDefine LDAP>
LDAPSharedCacheSize 200000
LDAPCacheEntries 1024
LDAPCacheTTL 600
LDAPOpCacheEntries 1024
LDAPOpCacheTTL 600
<Location /ldap-status>
SetHandler ldap-status
Require local
</Location>
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,191 @@
<IfDefine SSL>
<IfDefine SSL_DEFAULT_VHOST>
<IfModule ssl_module>
# see bug #178966 why this is in here
# When we also provide SSL we have to listen to the HTTPS port
# Note: Configurations that use IPv6 but not IPv4-mapped addresses need two
# Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443"
Listen 443
<VirtualHost _default_:443>
ServerName localhost
Include /etc/apache2/vhosts.d/default_vhost.include
ErrorLog /var/log/apache2/ssl_error_log
<IfModule log_config_module>
TransferLog /var/log/apache2/ssl_access_log
</IfModule>
## SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
## SSLProtocol:
# Don't use SSLv2 anymore as it's considered to be broken security-wise.
# Also disable SSLv3 as most modern browsers are capable of TLS.
SSLProtocol ALL -SSLv2 -SSLv3
## SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
# This list of ciphers is recommended by mozilla and was stripped off
# its RC4 ciphers. (bug #506924)
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:HIGH:!RC4:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK
## SSLHonorCipherOrder:
# Prefer the server's cipher preference order as the client may have a
# weak default order.
SSLHonorCipherOrder On
## Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If the certificate
# is encrypted, then you will be prompted for a pass phrase. Note that a
# kill -HUP will prompt again. Keep in mind that if you have both an RSA
# and a DSA certificate you can configure both in parallel (to also allow
# the use of DSA ciphers, etc.)
SSLCertificateFile /etc/ssl/apache2/server.crt
## Server Private Key:
# If the key is not combined with the certificate, use this directive to
# point at the key file. Keep in mind that if you've both a RSA and a DSA
# private key you can configure both in parallel (to also allow the use of
# DSA ciphers, etc.)
SSLCertificateKeyFile /etc/ssl/apache2/server.key
## Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the concatenation of
# PEM encoded CA certificates which form the certificate chain for the
# server certificate. Alternatively the referenced file can be the same as
# SSLCertificateFile when the CA certificates are directly appended to the
# server certificate for convinience.
#SSLCertificateChainFile /etc/ssl/apache2/ca.crt
## Certificate Authority (CA):
# Set the CA certificate verification path where to find CA certificates
# for client authentication or alternatively one huge file containing all
# of them (file must be PEM encoded).
# Note: Inside SSLCACertificatePath you need hash symlinks to point to the
# certificate files. Use the provided Makefile to update the hash symlinks
# after changes.
#SSLCACertificatePath /etc/ssl/apache2/ssl.crt
#SSLCACertificateFile /etc/ssl/apache2/ca-bundle.crt
## Certificate Revocation Lists (CRL):
# Set the CA revocation path where to find CA CRLs for client authentication
# or alternatively one huge file containing all of them (file must be PEM
# encoded).
# Note: Inside SSLCARevocationPath you need hash symlinks to point to the
# certificate files. Use the provided Makefile to update the hash symlinks
# after changes.
#SSLCARevocationPath /etc/ssl/apache2/ssl.crl
#SSLCARevocationFile /etc/ssl/apache2/ca-bundle.crl
## Client Authentication (Type):
# Client certificate verification type and depth. Types are none, optional,
# require and optional_no_ca. Depth is a number which specifies how deeply
# to verify the certificate issuer chain before deciding the certificate is
# not valid.
#SSLVerifyClient require
#SSLVerifyDepth 10
## Access Control:
# With SSLRequire you can do per-directory access control based on arbitrary
# complex boolean expressions containing server variable checks and other
# lookup directives. The syntax is a mixture between C and Perl. See the
# mod_ssl documentation for more details.
#<Location />
# #SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#</Location>
## SSL Engine Options:
# Set various options for the SSL engine.
## FakeBasicAuth:
# Translate the client X.509 into a Basic Authorisation. This means that the
# standard Auth/DBMAuth methods can be used for access control. The user
# name is the `one line' version of the client's X.509 certificate.
# Note that no password is obtained from the user. Every entry in the user
# file needs this password: `xxj31ZMTZzkVA'.
## ExportCertData:
# This exports two additional environment variables: SSL_CLIENT_CERT and
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the server
# (always existing) and the client (only existing when client
# authentication is used). This can be used to import the certificates into
# CGI scripts.
## StdEnvVars:
# This exports the standard SSL/TLS related `SSL_*' environment variables.
# Per default this exportation is switched off for performance reasons,
# because the extraction step is an expensive operation and is usually
# useless for serving static content. So one usually enables the exportation
# for CGI and SSI requests only.
## StrictRequire:
# This denies access when "SSLRequireSSL" or "SSLRequire" applied even under
# a "Satisfy any" situation, i.e. when it applies access is denied and no
# other module can change it.
## OptRenegotiate:
# This enables optimized SSL connection renegotiation handling when SSL
# directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/var/www/localhost/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
## SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant shutdown
# approach is that mod_ssl sends the close notify alert but doesn't wait
# for the close notify alert from client. When you need a different
# shutdown approach you can use one of the following variables:
## ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is closed, i.e. no
# SSL close notify alert is send or allowed to received. This violates the
# SSL/TLS standard but is needed for some brain-dead browsers. Use this when
# you receive I/O errors because of the standard approach where mod_ssl
# sends the close notify alert.
## ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection is closed, i.e. a
# SSL close notify alert is send and mod_ssl waits for the close notify
# alert of the client. This is 100% SSL/TLS standard compliant, but in
# practice often causes hanging connections with brain-dead browsers. Use
# this only for browsers where you know that their SSL implementation works
# correctly.
# Notice: Most problems of broken clients are also related to the HTTP
# keep-alive facility, so you usually additionally want to disable
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
# "force-response-1.0" for this.
<IfModule setenvif_module>
BrowserMatch ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
</IfModule>
## Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a compact
# non-error SSL logfile on a virtual host basis.
<IfModule log_config_module>
CustomLog /var/log/apache2/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</IfModule>
</VirtualHost>
</IfModule>
</IfDefine>
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,45 @@
# Virtual Hosts
#
# If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at
# <URL:http://httpd.apache.org/docs/2.4/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.
<IfDefine DEFAULT_VHOST>
# see bug #178966 why this is in here
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80
# When virtual hosts are enabled, the main host defined in the default
# httpd.conf configuration will go away. We redefine it here so that it is
# still available.
#
# If you disable this vhost by removing -D DEFAULT_VHOST from
# /etc/conf.d/apache2, the first defined virtual host elsewhere will be
# the default.
<VirtualHost *:80>
ServerName localhost
Include /etc/apache2/vhosts.d/default_vhost.include
<IfModule mpm_peruser_module>
ServerEnvironment apache apache
</IfModule>
</VirtualHost>
</IfDefine>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,71 @@
# ServerAdmin: Your address, where problems with the server should be
# e-mailed. This address appears on some server-generated pages, such
# as error documents. e.g. admin@your-domain.com
ServerAdmin root@localhost
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
# If you change this to something that isn't under /var/www then suexec
# will no longer work.
DocumentRoot "/var/www/localhost/htdocs"
# This should be changed to whatever you set DocumentRoot to.
<Directory "/var/www/localhost/htdocs">
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.4/mod/core.html#options
# for more information.
Options Indexes FollowSymLinks
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
AllowOverride All
# Controls who can get stuff from this server.
Require all granted
</Directory>
<IfModule alias_module>
# Redirect: Allows you to tell clients about documents that used to
# exist in your server's namespace, but do not anymore. The client
# will make a new request for the document at its new location.
# Example:
# Redirect permanent /foo http://www.example.com/bar
# Alias: Maps web paths into filesystem paths and is used to
# access content that does not live under the DocumentRoot.
# Example:
# Alias /webpath /full/filesystem/path
#
# If you include a trailing / on /webpath then the server will
# require it to be present in the URL. You will also likely
# need to provide a <Directory> section to allow access to
# the filesystem path.
# ScriptAlias: This controls which directories contain server scripts.
# ScriptAliases are essentially the same as Aliases, except that
# documents in the target directory are treated as applications and
# run by the server when requested rather than as documents sent to the
# client. The same rules about trailing "/" apply to ScriptAlias
# directives as to Alias.
ScriptAlias /cgi-bin/ "/var/www/localhost/cgi-bin/"
</IfModule>
# "/var/www/localhost/cgi-bin" should be changed to whatever your ScriptAliased
# CGI directory exists, if you have that configured.
<Directory "/var/www/localhost/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
# vim: ts=4 filetype=apache

View File

@@ -0,0 +1,7 @@
<VirtualHost *:80>
ServerName gentoo.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

View File

@@ -0,0 +1,74 @@
# /etc/conf.d/apache2: config file for /etc/init.d/apache2
# When you install a module it is easy to activate or deactivate the modules
# and other features of apache using the APACHE2_OPTS line. Every module should
# install a configuration in /etc/apache2/modules.d. In that file will have an
# <IfDefine NNN> directive where NNN is the option to enable that module.
#
# Here are the options available in the default configuration:
#
# AUTH_DIGEST Enables mod_auth_digest
# AUTHNZ_LDAP Enables authentication through mod_ldap (available if USE=ldap)
# CACHE Enables mod_cache
# DAV Enables mod_dav
# ERRORDOCS Enables default error documents for many languages.
# INFO Enables mod_info, a useful module for debugging
# LANGUAGE Enables content-negotiation based on language and charset.
# LDAP Enables mod_ldap (available if USE=ldap)
# MANUAL Enables /manual/ to be the apache manual (available if USE=docs)
# MEM_CACHE Enables default configuration mod_mem_cache
# PROXY Enables mod_proxy
# SSL Enables SSL (available if USE=ssl)
# STATUS Enabled mod_status, a useful module for statistics
# SUEXEC Enables running CGI scripts (in USERDIR) through suexec.
# USERDIR Enables /~username mapping to /home/username/public_html
#
#
# The following two options provide the default virtual host for the HTTP and
# HTTPS protocol. YOU NEED TO ENABLE AT LEAST ONE OF THEM, otherwise apache
# will not listen for incomming connections on the approriate port.
#
# DEFAULT_VHOST Enables name-based virtual hosts, with the default
# virtual host being in /var/www/localhost/htdocs
# SSL_DEFAULT_VHOST Enables default vhost for SSL (you should enable this
# when you enable SSL)
#
APACHE2_OPTS="-D DEFAULT_VHOST -D INFO -D SSL -D SSL_DEFAULT_VHOST -D LANGUAGE"
# Extended options for advanced uses of Apache ONLY
# You don't need to edit these unless you are doing crazy Apache stuff
# As not having them set correctly, or feeding in an incorrect configuration
# via them will result in Apache failing to start
# YOU HAVE BEEN WARNED.
# PID file
#PIDFILE=/var/run/apache2.pid
# timeout for startup/shutdown checks
#TIMEOUT=10
# ServerRoot setting
#SERVERROOT=/usr/lib64/apache2
# Configuration file location
# - If this does NOT start with a '/', then it is treated relative to
# $SERVERROOT by Apache
#CONFIGFILE=/etc/apache2/httpd.conf
# Location to log startup errors to
# They are normally dumped to your terminal.
#STARTUPERRORLOG="/var/log/apache2/startuperror.log"
# A command that outputs a formatted text version of the HTML at the URL
# of the command line. Designed for lynx, however other programs may work.
#LYNX="lynx -dump"
# The URL to your server's mod_status status page.
# Required for status and fullstatus
#STATUSURL="http://localhost/server-status"
# Method to use when reloading the server
# Valid options are 'restart' and 'graceful'
# See http://httpd.apache.org/docs/2.2/stopping.html for information on
# what they do and how they differ.
#RELOAD_TYPE="graceful"

View File

@@ -0,0 +1,3 @@
vhosts.d/gentoo.example.com.conf, gentoo.example.com
vhosts.d/00_default_vhost.conf, localhost
vhosts.d/00_default_ssl_vhost.conf, localhost

View File

@@ -23,7 +23,8 @@ class TlsSniPerformTest(util.ApacheTest):
super(TlsSniPerformTest, self).setUp()
config = util.get_apache_configurator(
self.config_path, self.vhost_path, self.config_dir, self.work_dir)
self.config_path, self.vhost_path, self.config_dir,
self.work_dir)
config.config.tls_sni_01_port = 443
from certbot_apache import tls_sni_01
@@ -41,8 +42,8 @@ class TlsSniPerformTest(util.ApacheTest):
@mock.patch("certbot.util.exe_exists")
@mock.patch("certbot.util.run_script")
def test_perform1(self, _, mock_exists):
mock_register = mock.Mock()
self.sni.configurator.reverter.register_undo_command = mock_register
self.sni.configurator.parser.modules.add("socache_shmcb_module")
self.sni.configurator.parser.modules.add("ssl_module")
mock_exists.return_value = True
self.sni.configurator.parser.update_runtime_variables = mock.Mock()
@@ -55,10 +56,6 @@ class TlsSniPerformTest(util.ApacheTest):
self.sni._setup_challenge_cert = mock_setup_cert
responses = self.sni.perform()
# Make sure that register_undo_command was called into temp directory.
self.assertEqual(True, mock_register.call_args[0][0])
mock_setup_cert.assert_called_once_with(achall)
# Check to make sure challenge config path is included in apache config
@@ -71,7 +68,7 @@ class TlsSniPerformTest(util.ApacheTest):
def test_perform2(self):
# Avoid load module
self.sni.configurator.parser.modules.add("ssl_module")
self.sni.configurator.parser.modules.add("socache_shmcb_module")
acme_responses = []
for achall in self.achalls:
self.sni.add_chall(achall)
@@ -81,7 +78,8 @@ class TlsSniPerformTest(util.ApacheTest):
# pylint: disable=protected-access
self.sni._setup_challenge_cert = mock_setup_cert
with mock.patch("certbot_apache.configurator.ApacheConfigurator.enable_mod"):
with mock.patch(
"certbot_apache.override_debian.DebianConfigurator.enable_mod"):
sni_responses = self.sni.perform()
self.assertEqual(mock_setup_cert.call_count, 2)

View File

@@ -1,5 +1,6 @@
"""Common utilities for certbot_apache."""
import os
import shutil
import sys
import unittest
@@ -16,7 +17,7 @@ from certbot.plugins import common
from certbot.tests import util as test_util
from certbot_apache import configurator
from certbot_apache import constants
from certbot_apache import entrypoint
from certbot_apache import obj
@@ -38,6 +39,9 @@ class ApacheTest(unittest.TestCase): # pylint: disable=too-few-public-methods
self.rsa512jwk = jose.JWKRSA.load(test_util.load_vector(
"rsa512_key.pem"))
self.config = get_apache_configurator(self.config_path, vhost_root,
self.config_dir, self.work_dir)
# Make sure all vhosts in sites-enabled are symlinks (Python packaging
# does not preserve symlinks)
sites_enabled = os.path.join(self.config_path, "sites-enabled")
@@ -55,8 +59,13 @@ class ApacheTest(unittest.TestCase): # pylint: disable=too-few-public-methods
os.path.pardir, "sites-available", vhost_basename)
os.symlink(target, vhost)
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
class ParserTest(ApacheTest): # pytlint: disable=too-few-public-methods
class ParserTest(ApacheTest):
def setUp(self, test_dir="debian_apache_2_4/multiple_vhosts",
config_root="debian_apache_2_4/multiple_vhosts/apache2",
@@ -72,12 +81,16 @@ class ParserTest(ApacheTest): # pytlint: disable=too-few-public-methods
with mock.patch("certbot_apache.parser.ApacheParser."
"update_runtime_variables"):
self.parser = ApacheParser(
self.aug, self.config_path, self.vhost_path)
self.aug, self.config_path, self.vhost_path,
configurator=self.config)
def get_apache_configurator(
def get_apache_configurator( # pylint: disable=too-many-arguments, too-many-locals
config_path, vhost_path,
config_dir, work_dir, version=(2, 4, 7), conf=None):
config_dir, work_dir, version=(2, 4, 7),
conf=None,
os_info="generic",
conf_vhost_path=None):
"""Create an Apache Configurator with the specified options.
:param conf: Function that returns binary paths. self.conf in Configurator
@@ -86,8 +99,8 @@ def get_apache_configurator(
backups = os.path.join(work_dir, "backups")
mock_le_config = mock.MagicMock(
apache_server_root=config_path,
apache_vhost_root=vhost_path,
apache_le_vhost_ext=constants.os_constant("le_vhost_ext"),
apache_vhost_root=conf_vhost_path,
apache_le_vhost_ext="-le-ssl.conf",
apache_challenge_location=config_path,
backup_dir=backups,
config_dir=config_dir,
@@ -95,22 +108,37 @@ def get_apache_configurator(
in_progress_dir=os.path.join(backups, "IN_PROGRESS"),
work_dir=work_dir)
with mock.patch("certbot_apache.configurator.util.run_script"):
with mock.patch("certbot_apache.configurator.util."
"exe_exists") as mock_exe_exists:
mock_exe_exists.return_value = True
with mock.patch("certbot_apache.parser.ApacheParser."
"update_runtime_variables"):
config = configurator.ApacheConfigurator(
config=mock_le_config,
name="apache",
version=version)
# This allows testing scripts to set it a bit more quickly
if conf is not None:
config.conf = conf # pragma: no cover
orig_os_constant = configurator.ApacheConfigurator(mock_le_config,
name="apache",
version=version).constant
config.prepare()
def mock_os_constant(key, vhost_path=vhost_path):
"""Mock default vhost path"""
if key == "vhost_root":
return vhost_path
else:
return orig_os_constant(key)
with mock.patch("certbot_apache.configurator.ApacheConfigurator.constant") as mock_cons:
mock_cons.side_effect = mock_os_constant
with mock.patch("certbot_apache.configurator.util.run_script"):
with mock.patch("certbot_apache.configurator.util."
"exe_exists") as mock_exe_exists:
mock_exe_exists.return_value = True
with mock.patch("certbot_apache.parser.ApacheParser."
"update_runtime_variables"):
try:
config_class = entrypoint.OVERRIDE_CLASSES[os_info]
except KeyError:
config_class = configurator.ApacheConfigurator
config = config_class(config=mock_le_config, name="apache",
version=version)
# This allows testing scripts to set it a bit more
# quickly
if conf is not None:
config.conf = conf # pragma: no cover
config.prepare()
return config

View File

@@ -63,7 +63,7 @@ setup(
},
entry_points={
'certbot.plugins': [
'apache = certbot_apache.configurator:ApacheConfigurator',
'apache = certbot_apache.entrypoint:ENTRYPOINT',
],
},
test_suite='certbot_apache',

View File

@@ -9,8 +9,7 @@ import zope.interface
from certbot import configuration
from certbot import errors as le_errors
from certbot import util as certbot_util
from certbot_apache import configurator
from certbot_apache import constants
from certbot_apache import entrypoint
from certbot_compatibility_test import errors
from certbot_compatibility_test import interfaces
from certbot_compatibility_test import util
@@ -56,13 +55,14 @@ class Proxy(configurators_common.Proxy):
def _prepare_configurator(self):
"""Prepares the Apache plugin for testing"""
for k in constants.CLI_DEFAULTS_DEBIAN.keys():
setattr(self.le_config, "apache_" + k, constants.os_constant(k))
for k in entrypoint.ENTRYPOINT.OS_DEFAULTS.keys():
setattr(self.le_config, "apache_" + k,
entrypoint.ENTRYPOINT.OS_DEFAULTS[k])
# An alias
self.le_config.apache_handle_modules = self.le_config.apache_handle_mods
self._configurator = configurator.ApacheConfigurator(
self._configurator = entrypoint.ENTRYPOINT(
config=configuration.NamespaceConfig(self.le_config),
name="apache")
self._configurator.prepare()

View File

@@ -342,9 +342,9 @@ def get_os_info_ua(filepath="/etc/os-release"):
"""
if os.path.isfile(filepath):
os_ua = _get_systemd_os_release_var("PRETTY_NAME", filepath=filepath)
os_ua = get_var_from_file("PRETTY_NAME", filepath=filepath)
if not os_ua:
os_ua = _get_systemd_os_release_var("NAME", filepath=filepath)
os_ua = get_var_from_file("NAME", filepath=filepath)
if os_ua:
return os_ua
@@ -361,8 +361,8 @@ def get_systemd_os_info(filepath="/etc/os-release"):
:rtype: `tuple` of `str`
"""
os_name = _get_systemd_os_release_var("ID", filepath=filepath)
os_version = _get_systemd_os_release_var("VERSION_ID", filepath=filepath)
os_name = get_var_from_file("ID", filepath=filepath)
os_version = get_var_from_file("VERSION_ID", filepath=filepath)
return (os_name, os_version)
@@ -377,10 +377,10 @@ def get_systemd_os_like(filepath="/etc/os-release"):
:rtype: `list` of `str`
"""
return _get_systemd_os_release_var("ID_LIKE", filepath).split(" ")
return get_var_from_file("ID_LIKE", filepath).split(" ")
def _get_systemd_os_release_var(varname, filepath="/etc/os-release"):
def get_var_from_file(varname, filepath="/etc/os-release"):
"""
Get single value from systemd /etc/os-release
@@ -405,7 +405,7 @@ def _get_systemd_os_release_var(varname, filepath="/etc/os-release"):
def _normalize_string(orig):
"""
Helper function for _get_systemd_os_release_var() to remove quotes
Helper function for get_var_from_file() to remove quotes
and whitespaces
"""
return orig.replace('"', '').replace("'", "").strip()